2013-05-19 32 views
-2

PART 1这两个字符串有什么区别?

我有两个字符串,它们将在后面的ways-

char s1[] = "foo"; 
char *s2 = "foo"; 

定义。当我试图改变这些字符串,比如一个字符时,第2个字符 -

char s1[1] = 'x'; 
char s2[1] = 'x'; 

字符串中的字符s1更改,但更改字符串s2中的字符会给我出现此错误 - Segmentation fault (core dumped)

这是为什么?

为什么我无法更改以另一种方式定义的字符串的字符?


PART 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。

+1

**'s1'是一个数组**(带4个要素); **'s2'是一个指针**(指向具有4个元素的(不可修改)数组的第一个元素)。 “字符串”是其中一个元素是“\ 0”的数组。阅读[comp.lang.c FAQ](http://c-faq.com/),从第6部分开始。 – pmg

+0

@KingsIndian还有一个** PART 2 **。 – ShuklaSannidhya

+0

@pmg它不必是“不可修改的”。只有修改它是UB。有一个微妙的区别。 –

回答

4

第一个是一个字符串,它是一个字符数组,填充字符串“foo”中的字符,第二个是一个指向具有值“foo”的常量的指针。由于第二个是不变的,所以不允许修改它。

而且不,你不能初始化指向值集的指针 - 因为指针没有实际的内存来存储分配给它的值。您需要可以使它指向另一个数组:

int foox[3] = { 1, 2, 3 }; 
int *foo = foox; 

,或者您需要分配一些内存,然后存储的值:

int *foo = malloc(sizeof(int) * 3); 

foo[0] = 1; 
foo[1] = 2; 
foo[2] = 3; 
+0

所以我可以称这样的字符串不可变? – ShuklaSannidhya

+3

该标准表示它是“未定义的行为”写入它们 - 在某些情况下完全可以写入这样的字符串[例如使用Turbo C++,你可能可以,因为它为DOS生成代码,它没有任何写保护内存的能力,所以没有什么能阻止你写入字符串 - 或者覆盖你当前正在执行的代码,应该你编写的代码是有意或无意的]。 –