2013-05-19 34 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生成代碼,它沒有任何寫保護內存的能力,所以沒有什麼能阻止你寫入字符串 - 或者覆蓋你當前正在執行的代碼,應該你編寫的代碼是有意或無意的]。 –