对于语句 char *a="hello";
对于这个声明方式,会造成的误解是:声明了一个字符指针(它会指向一个位置),将“字符串”赋值给 指针表达式"*a"所指向的地址。但正解是:声明了一个字符指针后,并用字符串常量的第一个字符的地址赋值给指针变量a。
即正确顺序是:
- 1.分配内存给字符指针;
- 2.分配内存给字符串;
- 3.将字符串首地址赋值给字符指针;
这里有两点需要考虑清楚的地方:
①*a只是指向一个字符。举例如下:
#include <iostream>
#include <string>
using namespace std;
int main() {
char *a ="abcdefg";
cout << "输出字符: " << *a << endl;
cout << "第二次输出字符: " << *(a+1) << endl;
cout << "输出字符串: " << a << endl;
return 0;
}
结果如下
输出字符: a
第二次输出字符: b
输出字符串: abcdefg
② 若字符串常量出现在在表达式中,代表的值为该字符串常量的第一个字符的地址。所以”hello”仅仅代表的是其地址。
原声明方式相当于以下声明方式:
char *a;
a="hello";/*这里字符串"hello"仅仅代表其第一个字符的地址*/
1.但还是不明白为什么字符串可以赋值给字符指针变量
char *p,a='5';
p=&a; //显然是正确的,
p="abcd"; //但为什么也可以这样赋值??
双引号做了3件事:
1.申请了空间(在常量区),存放了字符串
2. 在字符串尾加上了'/0'
3.返回地址
返回的地址,赋值给了指针变量p
2.以char *p = “hello”为例,把p换成数组,然后再赋值就不行了
字符串常量"hello"出现在一个表达式中时,"hello"表达式使用的值就是这些字符所存储的地址(在常量区),而不是这些字符本身。
所以,可以把字符串赋值给指向字符的指针p,而不能把字符串赋值给一个字符数组。
char a[10] = “hello”; //这样可以,这种情况是c语言初始化所支持的
如果写成char a[10]
然后 a = “hello” 这样就错误了。
因为同样是a数组,char a[10] = “hello”;这种是数组的初始化,和a[0] = ‘h’ a[1] = ‘e’…是一个道理
但是换成char a [10],然后a = “hello”是不行的,“hello”赋值的值是一个地址,而a虽然也有地址,与指针不同,指针的值是地址,而数组的值虽然同为地址,却是一个常量,不能给常量赋值
代码测试
#include <iostream>
#include <string>
using namespace std;
int main() {
char *p = "hello";
cout << p << endl;
char a[10];
a = "hello";
return 0;
}
报错 error C3863: array type 'char [10]' is not assignable
而修改后,正常运行
#include <iostream>
#include <string>
using namespace std;
int main() {
char *p = "hello";
cout << p << endl;
char a[10] = "hello"; //数组初始化
return 0;
}
字符数组,字符指针,字符串常量 知识回顾
1.以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写 "abc",那么编译器帮你存储的是"abc "
2."abc"是常量吗?
1.当作为字符数组初始值的时候,"abc"不是常量
char str[] = "abc";
因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",而又因为字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为
char str[4] = {'a','b','c','