最近我一直在学习关于C语言的所有内容,并且在 时使用
感到困惑char a[];
在
char *p;
当谈到字符串操作时。例如,我可以为它们分配一个字符串,如下所示:
char a[] = "Hello World!";
char *p = "Hello World!";
并查看/访问它们,如:
printf("%s\n", a);
printf("%s\n", p);
并操纵它们,如:
printf("%c\n", &a[6]);
printf("%c\n", &p[6]);
那么,我错过了什么?
答案 0 :(得分:9)
char a[] = "Hello World!";
这会分配可修改的数组,其大小足以容纳字符串文字(包括终止NUL字符)。然后用字符串文字的内容初始化数组。如果它是局部变量,那么这实际上意味着它在运行时每次创建局部变量时都会memcpy
。
当您需要修改字符串时使用此选项,但不需要将其设置为更大。
此外,如果您有char *ap = a;
,则当a
超出范围ap
时会成为悬空指针。或者,同样的事情,当return a;
对于该函数是局部的时,你不能做a
,因为返回值将悬挂指向现在销毁该函数的局部变量的指针。
请注意,使用这种情况很少见。通常,您不希望数组包含来自字符串文字的内容。有类似的东西更常见:
char buf[100]; // contents are undefined
snprintf(buf, sizeof buf, "%s/%s.%d", pathString, nameString, counter);
char *p = "Hello World!";
这定义了指针,并将其初始化为指向字符串文字。请注意,字符串文字(通常)是不可写的,所以你真的应该 而不是这样:
const char *p = "Hello World!";
当你需要指向不可修改的字符串的指针时使用它。
与上面的a
相比,如果你有const char *p2 = p;
或者return p;
,这些都很好,因为指针指向程序常量数据中的字符串文字,并且对于整个程序的执行。
字符串文字本身,带双引号的文本,构成字符串的实际字节,是在编译时创建的,通常与应用程序中的其他常量数据一起放置。然后代码中的字符串文字具体地表示这个常量数据blob的地址。
答案 1 :(得分:2)
char *
个字符串是只读的。 char[]
字符串可以修改它们。
char *str = "hello";
str[0] = 't'; // This is an illegal operation
尽管
char str[] = "hello"; str[0] = 't'; // Legal, string becomes tello