字符指针指的是 char* 型指针,我们常常会这样使用
char* pstr = "hello,world";
下面就以这句代码为基础来挖出字符指针的一些坑。
目录
1、第一个坑:赋值的坑
你可能会认为上面这句代码在做的事是,把一个字符串放到字符指针pstr里了,pstr是一个指针类型,而“hello, world”是一个字符串常量,两者很显然不等价。
=》这句代码的本质是 ,将字符串第一个字符的地址存放到 字符指针pstr
2、第二个坑:修改的坑
================ 错误示范 ================
现在我想把 "hello,world" 的第一个字符改成大写的,一般来说会这么干
char* pstr = "hello,world";
*pstr = 'H';
但是这个时候就会报错了,
因为 "hello,world" 是一个常量,存储的时候是被放在常量区的(常量区的内容不可被修改),我们通过指针修改常量区的内容,很显然是不合适的。
================ 换一种写法 ================
换成下面这种写法就可以了
char str[20] = "hello, world";
*str = 'H';
只不过是换成了数组的形式,为什么就可以了呢??这个时候的 "hello, world" 不是常量了吗??
- 第一步,赋值的时候是从右往左执行的,所以是先在常量区创建一个常量叫做 "hello, world";
- 第二步,在栈上创建一个数组,数组名为str,数组大小为20个字节;
- 第三步,将"hello, world"从常量区拷贝一份,拷贝到刚刚创建好的str数组中。
因此,此时我们修改的其实是栈上的字符串,常量区的并没有发生改变。
3、第三个坑:开辟空间的坑
从第二个坑我们知道, 常量区的字符串是不能被修改的,但是拷贝到栈上以后,我们可以修改栈上的字符串。下面的判断结果是什么呢??
char str1[20] = "hello, world";
char str2[20] = "hello, world";
const char* str3 = "hello, world";
const char* str4 = "hello, world";
if (str1 == str2)
printf("相同\n");
else
printf("不同\n");
if (str3 == str4)
printf("相同\n");
else
printf("不同\n");
结果如下:
第一句:在常量区创建一个常量“hello, world”,在栈上创建一个数组str1,数组大小为20,将常量区的“hello, world”拷贝一份到str1里
第二句:在栈上创建一个数组str2,数组大小为20,将常量区的“hello, world”拷贝一份到 str2 里
第三句:将常量区的字符串“hello, world”的地址赋值给 str3
第四句:将常量区的字符串“hello, world”的地址赋值给 str4
注意:栈上的内容是可以修改的,因此每次创建都要开辟新的空间;但是常量区的内容是不可以被修改的,重复创建没有任何意义。