初始化字符串有多种方式,如下:
char a[]="abc";
//初始化方法一:这种情况下实际上规定了字符数组的大小为4(含结尾的\0)
char *p="zxcd";
//初始化方法二:思考为什么这样也可以初始化,p表示的是地址,"zxcd"是字符串,为什么可以划等号。
实际上第一种数组的这种初始化方法在编译器看来并不是初始化一个字符串,而是初始化多个字符,真正初始化一个字符串的操作应该如下:
char a[3]="ab";//记作写法1,因为要为字符串结尾的'\0'预留位置,如果这里写作a[2]就会报错
所以第一种初始化方法实际上等同于
char str[4] = {'a','b','c','\0'};
那么实际上初始化的并不是字符串,而是一个个单独的字符,我们知道字符串是存储在内存的常量区,那么上面这种初始化方式实际上“字符串”并不是存储在常量区,如果这时候的“字符串”是写在函数内部的话,是存储在栈区的,如果写在全局区,是存储在静态区的。
我们再来看第二种初始化方法,来思考为什么地址和字符串可以划等号
注意一点:字符串常量一旦出现在表达式中,那么字符串表达的就已经是地址了!
在第二种初始化方法中的双引号实际上做了三件事
1、申请了空间(在常量区),存放了字符串
2、在字符串尾加上了'/0'
3、返回地址所以实际上并不存在地址和字符串划等号的情况,之前也说过字符串常量是存放在常量区的,"ab"表达式使用的值是指向常量区的地址,而并不是字符串本身,所以可以将该表达式赋值给指针。
另外我们再来看写法1,一种看上去与写法1“类似”的写法的是
char a[3];
a="ab";
但是这个却报错了,为什么?
因为虽然字符串出现在表达式中是地址,而a也是地址,但是数组的地址是常量,给常量赋值必然是会报错的。
所以这次需要知道的结论是字符串如果出现在表达式中就是表示地址的,而单个的字符则不是。