看到c风格字符串的时候,有了几个疑问,如下:
程序 1 如下:
#include#include #include using namespace std; int main(int argc, char *argv[]) { const char ca[] = {'h', 'e', 'l', 'l', 'o'}; cout << strlen(ca) << endl; int i = 0; while (ca[i] != '\0') { cout << ca[i++] << endl; } cout << strlen(ca) << endl; }
windows xp下的mingw 结果 D:\c_c_plus>a.exe 5 h e l l o 6当时我非常纳闷怎么ca的长度会变化了(5,6),试了几次结果都是这样,没有想明白,于是换到了linux下同样的程序,结果如下
sulong@sulong-desktop:~/Documents/c_c_plus$ ./a.out 8 h e l l o 6这里,ca的长度再次变化了(5,8),我的第一反应是在此好像strlen对ca不起作用了,仔细看书,归结出原因在此:
- strlen等标准库函数的参数是c风格字符串(c++ primer中描述到,传递给这些函数的指针必须具有非零值,而且指向以null结束的字符数组中的第一个元素);
- 而c风格字符串有一点值得注意,需要以null结束,如char ca1[] = {'1', '2'}就不是,而char ca2={'1', '2', '\0'}则是,同时字符串字面量也是c风格字符串的实例;
- strlen总是假定其参数字符串以null字符结束,当调用该函数时,系统将会从实参指向的内存空间开始一致搜索结束符,知道恰好遇到null位置,strlen返回的这一段内存空间内总共有多少个字符;
- 当实参是非c风格字符的时候,这个数值是不可预知的;
#include不过有一点不是很明白,对于第一个程序,为什么对ca进行解引用之后,ca的长度变化了?windows(5,6),linux(8,6),我的猜测是c++允许计算数组的超出末端的地址,但是不允许对此地址进行解引用操作,否则结果是未定义的。#include #include using namespace std; int main(int argc, char *argv[]) { const char ca[] = {'h', 'e', 'l', 'l', 'o', '\0'}; cout << strlen(ca) << endl; int i = 0; while (ca[i] != '\0') { cout << ca[i++] << endl; } cout << strlen(ca) << endl; } output: 5 h e l l o 5
除了strlen函数,我同时测试了其他cstring中的库函数,参数必须严格安装说明和建议,否则结果也是未定义的,如下 程序 3 :
#include#include using namespace std; int main(int argc, char* argv[]) { const char *c1 = "hello"; const char *c2 = "world"; char pc[5 + 5 + 1]; strncpy(pc, c1, 5); cout << pc << endl; } output: hello6
因为strncpy(pc, c1, 5)的5只够存储hello,而null字符也是需要空间的,使用的时候,时刻记住一定要算上结束符null,需要修改为6以上(当然不能超过pc的size),结果才能正确输出为hello。
两点感悟:
1. 少用c风格字符串,用string
2. 多多编程测试细节
No comments:
Post a Comment