char *strPtr = "HELLO ";

char str[] = "HELLO ";

*(strPtr + 1) = 'B'; // 出错

*(str + 1) = 'B'; // 正常执行

原因分析如下:

C++字符数组与字符指针在运算时的区别_c++C++字符数组与字符指针在运算时的区别_c++C++字符数组与字符指针在运算时的区别_c++C++字符数组与字符指针在运算时的区别_c++“HELLO”在内存中的存储形式:

 C++字符数组与字符指针在运算时的区别_字符数组_05

 指针变量strPtr在内存中的存储形式:(前面是内存的地址)

C++字符数组与字符指针在运算时的区别_字符指针_06 

冒号前面是内存的地址,后面存放的是具体内容。可以看出指针变量存储的是"HELLO "的第一个字母的内存地址。

str数组在内存中的存储形式: 

C++字符数组与字符指针在运算时的区别_字符数组_07

 冒号前面是内存的地址,后面存放的是具体内容。可以看出字符数组中的每个元素存储的是"HELLO "的每个字母的内存地址。

1printf("%xd\n", &strPtr); // 输出结果为:0x00C17BF0

2printf("%xd\n", strPtr); // 输出结果为:0x00907BF0

3printf("%xd\n", &str); // 输出结果为:0x001BA9F0

4printf("%xd\n", str); // 输出结果为:0x001BA9F0

上述12中输出的结果不同是因为strPtr是一个变量,变量名作为表达式时实际是取这个变量中所存取的值。所以1是输出strPtr这个变量的地址,而2是输出strPtr这个变量存取的值。而34输出的结果相同是因为str只是数组名称并不是一个变量。而数组名称作为表达式时表示的就是这个数组第一个元素的地址。而&str表示的是整个数组在内存中占用的地址。它是一个指针数组,即char (*strArray)[6] = &str;strArray中的每个元素存取的值就是str这个数组各个元素的内存地址。这里输出时由于没有指定输出哪个元素,所以默认输出了strArray的第一个元素。因此它与4输出结果相同。

从上可以看出,对数组str进行的运算实际是对其自身的内存地址进行的运算。即str+1实际是获取了str这个数组的第2个元素的地址,而不是这个数据的第2个元素所存取的地址。获取的结果为0x001BA9F1。而对指针strPtr进行的运算实际是对其所存储的内存地址进行的运算。即strPtr+1实际是获取的其存储的内存地址进行加1。获取的结果为0x00907BF1。所以,*(str + 1) = 'B';操作实际只是改变了0x001BA9F这个地址中所存取的值,而*(strPtr + 1) = 'B';则是要改变0x00907BF1这个地址中所存取的值。而0x00907BF1这个地址中存取的是字面量的值,即常量的值,是不允许修改的。所以,执行*(strPtr + 1) = 'B';操作时会出错。

 

数组名str代表的是数组的首地址,是一个常量,所以对其进行str++会出错。因为不能改变一个常量的值。而指针strPtr是一个变量,所以可以进行strPtr++操作。