写项目的时候又被最基础的 char* , char[] , strncat , strcpy卡了一会,太久没碰老是搞混,索性在这里做个笔记:
const char* str1 = "abc";
// char* str1="abc";
// 有些编译器允许上面这样子写
const char* const str3 = "abc";
// str3 = "def"; 错误!!!str3指针不可改变指向!!
printf_s("st1:%p str3:%p\n", str1, str3);
// st1:012E8B30 str3:012E8B30
const char* str1 = "abc";
在这句里,“abc”,做了3件事:
所以,const char* str1=“abc” 这句话是正确的(编译器不同,有时需加上const关键字,因为数组名退化为的是常量指针)。
如果想限定str1指向,const char* const str3 = “abc” 这样写。
而正因为“abc”申请区域是常量存储区,很清楚看到printf_s(“st1:%p str3:%p\n”, str1, str3);的地址是一样的。
分配区域是常量存储区!!!
const char* str1 = "abcdef";
cout << strlen(str1)<<endl; // 6
cout << sizeof(str1) << endl; // 4
char str2[7] = "abcdef";
cout << strlen(str2)<<endl; // 6
cout << sizeof(str2) << endl; // 7
printf_s("st1:%p str2:%p\n", str1, str2);
// st1:00F48BD0 str2:00BEFA3C
主要注意的就是,“abcdef”是一个常量,
char str2[10] = "abcdef";
“abcdef”先会在常量存储区存下来,然后会因为要赋值给str2,会在栈中开辟一段内存,内存大小为7个节点(char数组后会自动加一个’\0’),然后又有一个"abc"被保存在栈中。
因此str1和str2地址是不一样的。
strncat()主要功能是在字符串的结尾追加n个字符。
strcpy是一种C的标准库函数,strcpy把**含有’\0’*的字符串复制到另一个地址空间,返回值的类型为char。
结合以上:char*,char[]的特性:
char *str1="abcd";
// const char*str1="abcd; 等价
char str2[20] = "1234";
strncat(str1, str2, 4);
像是某些版本VS或者DEV这样子是不会报错,但是是不可行的:首先,str1指向的"abcd"的地址是在常量存储区的,在栈存储的仅仅是指向该区的地址,是无法对str1指向的常量区("abcd"的地址)进行修改。
char *str1="abcd";
char str2[] = "1234";
strncat(str2, str1, 4);
printf("%s\n", str2);
这样子反过来就可以了。
strcpy()同理。