C++中的字符和字符串
1. C++11风格字符串的最后一位有隐含的‘\0’,可以用 str[str.size()]读到。需要注意。参考:
string str = ""; // str[str.size()] == '\0'
char a[] ="abcd"; // 以字符串赋值,最后一位有隐含的‘\0’; 用cout输出来看到的还是abcd sizeof(a) == 5; // 变量的字节大小 strlen(a) == 4; // 有效元素的个数,到 '\0' 结束
char a[5] = "abcde"; //会报错,最后要留一位给‘\0’ char a[5] = {'a','b','c','d','d'}; // 以字符赋值,没问题,sizeof(a) == 4
对于char*类型,又不一样了
const char* b = “abcdef”; // 将字符串的首地址赋给 b sizeof(b) == 4; // 这个是a这个指针的字节数 strlen(b) == 6; // 这个是该数组长度
上面 b 是一个指针变量,可以修改指向,不能修改指向的内容,即可以让b指向另一块内存,但不能用 b[0] = 'c' 这样的方式修改b指向的内容。
a 是“常量”,它的指向不能改变,即它指向的地址不能改变,但是它指向的内容可以改变。
如果char* 类型变量不是用常量直接初始化的,那么在赋值结束时一定要手动添加一个’\0‘(分配空间时,也需要多分配一个char空间),这样用strlen才可以正确得返回长度,后面的使用也不会有问题,例如:没有加’\0‘时,这个变量作为参数传入函数就出了问题invalid_argument。
最后一位的’\0‘不参与计算==》》 a[strlen(a)-1] == e;
2. char * 和char []的分辨
char a[]:声明的是一个字符数组对象,所以它实际上是一个数组,只不过在用索引读元素等操作时,a表现为该数组首元素的地址,实际上a 还是有数组的其它属性的。
空间上,a数组的所有内容都在栈空间,a的地址和数组首地址相同.
string a = "abc"; // a为字符串对象,在堆空间 char b[] = "abc"; // b为字符数组,在栈空间
char* p:声明的是一个指针类型,p将指向某一个字符串的内存块。 指针变量p在栈空间里面,其指向的空间则要具体分析。
oncst char* p = "abc"; // "abc"为只读常量,在代码段;只读空间无法用 p[i] 修改 char* q; q = (char*)malloc(10); // malloc申请的空间在堆空间;可以用 q[i]修改合法地址的内容 cout << p << ' ' << &p; // p保存的是“abc”的首地址,为代码段中的地址;&p为变量p的地址,在栈空间 cout << q << ' ' << &q; // 所以 q 保存堆空间的地址,&q还是栈空间的地址
* 这里"abc" 并不是从哪个变量中得到的,是一个常量 ——参考博客
浙公网安备 33010602011771号