【发布时间】:2013-05-19 15:51:38
【问题描述】:
第 1 部分
我有 2 个字符串,它们的定义方式如下-
char s1[] = "foo";
char *s2 = "foo";
当我尝试更改这些字符串的一个字符时,比如第二个字符 -
char s1[1] = 'x';
char s2[1] = 'x';
字符串s1 中的字符发生了变化,但是更改字符串s2 中的字符给了我这个错误-Segmentation fault (core dumped)。
为什么会这样?
为什么我无法更改以其他方式定义的字符串的字符?
第 2 部分
字符串(它们是字符数组,对吗?)可以使用 -char *s = "foo" 进行初始化
但是为什么当我尝试使用 int *arr = {1, 2, 3} 之类的相同内容初始化不同类型的数组时,编译器会发出警告?
foo.c: In function ‘main’:
foo.c:5:5: warning: initialization makes pointer from integer without a cast [enabled by default]
foo.c:5:5: warning: (near initialization for ‘foo’) [enabled by default]
foo.c:5:5: warning: excess elements in scalar initializer [enabled by default]
foo.c:5:5: warning: (near initialization for ‘foo’) [enabled by default]
foo.c:5:5: warning: excess elements in scalar initializer [enabled by default]
foo.c:5:5: warning: (near initialization for ‘foo’) [enabled by default]
注意:我的编译器是 GCC。
【问题讨论】:
-
s1是一个数组(有 4 个元素);s2是一个指针(指向具有 4 个元素的(不可修改的)数组的第一个元素)。 “字符串”是一个数组,其中一个元素是'\0'。阅读comp.lang.c FAQ,从第 6 节开始。 -
@KingsIndian 还有一个PART 2。
-
@pmg 它不必是“不可修改的”。只有修改它是UB。有细微的差别。
-
@KingsIndian:我的意思是“在 UB 的惩罚下不可修改”。关键是,与某些人的看法不同,在 C 中,字符串文字不是常量:它的类型是
char [N] /* with N large enough for all elements and the nul byte */,而不是const char[N]。请注意,出于这个原因,我没有说“const”(或“constant”):)