当前位置: 移动技术网 > IT编程>开发语言>C/C++ > C++中C风格字符串与字符数组实例讲解

C++中C风格字符串与字符数组实例讲解

2018年04月25日  | 移动技术网IT编程  | 我要评论

每个党员不论职务高低 都必须编入,全境警戒,变形金刚横行末世

1 字符串字面值与C风格字符串

在C++中,双引号括起来的零个或多个字符构成字符串字面值,如

“Hello World”

字符串字面值的类型实际上是由常量构成的数组,编译器在每个字符串的结尾处添加一个空字符(’\0’),因此字符串字面值的实际长度要比它的内容多1。

字符串字面值是一种通用结构的实例,这种结构即是C++由C继承而来的C风格字符串。C风格字符串不是一种类型,而是为了表达和使用字符串而形成的一种约定俗成的写法。按此习惯书写的字符串存放在字符数组中,并以空字符结束。

2 字符数组

字符数组的详细解释请参考《C++中字符数组》。可以使用字符串字面值对字符数组进行初始化。

char a[] = “C++”;

在“1字符串字面值与C风格字符串”中提到,字符串字面值的结尾还包含一个空字符,此时数组a的维度是4。

3 操作C风格字符串的函数

处理C风格字符串的函数有strlen()、strcmp()、strcat()以及strcpy()等。这些函数在cstring头文件中定义,cstring是C语言头文件string.h的C++b版本,因此,在使用这些函数时,应该包含cstring头文件。

#include 

4 实战

4.1 问题提出

在CSDN上有朋友提到如下问题:

char *src = "Danny";

const char *addition = "Andy";

strcat(src, addition);

程序报错,而如果将程序改为

char src[] = "Danny";

const char *addition = "Andy";

strcat(src, addition);

则不报错。

4.2 问题分析

4.2.1 内存结构

C++程序在内存中主要分为五个数据段,分别是代码段、数据段、BBS段、堆和栈。其中,数据段中保存的是全局变量和静态变量,字符串字面值也保存在数据段中;而栈中保存的是程序临时创建的局部变量。

4.1.2 处理数据段中的数据

对于当strcat()函数的两个参数都是字符指针时的情况,此时两个字符指针均指向保存在数据段中的字符串字面值,如图1所示。

\

图1 src和addition的内容

从图1中可以看出,字符串字面值”Danny”保存在0x00347838中,而字符串字面值”Andy”保存在0x00347830中。之后通过strcat()函数将”Andy”附加到”Danny”之后,实际上是对程序的数据段进行操作,而程序的数据端是不允许写入的,因此报错信息是“写入位置时发生访问冲突”,如图2所示。

\

图2 报错信息

4.2.2 处理栈中的数据

如果将src定义为字符数组,则此时src保存在栈中,程序允许对栈中的数据进行修改。src的地址如图3所示。

\

图3 src和addition的内容

从图3中可以看出,src的地址是在0x007bf7ec处,该地址位于程序的栈中;而addition的地址是在0x002f7830处,该地址位于程序的数据段中。

此时,虽然strcat()函数不再报错,但是当main()函数返回时,还会弹出栈被破坏的信息,如图4所示。

\

图4 栈被破坏信息

正如“2 字符数组”中提到,数组src的维数是6,使用strcat()函数,将长度为5的字符串字面值“Andy”附加到长度为6的src的后面,那么肯定覆盖了程序堆中的其他数据,因此会弹出堆被破坏的信息。

4.3 问题解决

4.3.1 加大strcat()源维数

如果使用处理字符串字面值的函数strcat(),则需要将源即src的数据维数变大,使其大于等于“DannyAndy” 的长度,即不小于10。例如

char src[11] = "Danny";

4.3.2 使用C++的string类

标准库类型string表示可变长度的字符序列,使用string类型必须首先包含string头文件。

#include 

string src = "Danny";

string addition = "Andy";

src += addition;

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网