2017-03-20 45 views
4

以下爲gcc 6.3版接受爲有效c代碼c char字符數組v C案例的char *初始化

char *green = { 'a', 'b', 'c' }; // gcc error 

我相信有完美理性的原因是這樣,但我想知道它是什麼。這個問題是由初始化一個字節數組的情況引起的(所以unsigned char而不是char),很容易寫出像{ '\x43', '\xde', '\xa0' }而不是"\x43\xde\xa0",並且只要你忘記寫my_array[]而不是*my_array,你被編譯器捕獲。

+5

你的'定義white'不等同於其他兩個,因爲它缺少空終止符('\ 0')在字符串的結尾。 – abelenky

+0

@abelenky哦,是的,這是我忽略的一個好點,謝謝。 –

+0

嘗試'char * green = {「a」,「b」,「c」};';;) – LPs

回答

7

下會產生錯誤

char *green = { 'a', 'b', 'c' }; 

因爲對於​​初始化不是字符數組,你相信。它沒有類型,只是一個大括號包含的初始化列表。它在之前的樣本中初始化的東西(即white)決定了它的解釋方式。可以使用相同的initialzier來初始化任何能夠保存3個字符的聚合。

但是​​是一個指針,而不是一個聚合,所以你不能使用大括號包含的初始化列表,因爲它是初始值。

現在,下面的兩個工作,但具有非常不同的語義:

char blue[] = "abc"; 
char *red = "abc"; 

blue是一個數組。它將保留與文字​​相同的內容。 red指向的指針​​。


  1. 您可以使用compound literal expression

    char *green = (char[]){ 'a', 'b', 'c' }; 
    

    它告訴編譯器創建一個未命名的對象(生命時間,這取決於申報的範圍),這是字符數組類型,並用這三個字符進行初始化。然後指針指定該對象的地址。

+0

全部非常真實。然而,如果通過將初始化器列表更改爲char型數組文字(而不是字符串文字),並且通過討論「char *」聲明的重要性,那麼答案會更好。這樣做。 –

+0

@JohnBollinger - 我只是在輸入關於複合文字的信息 – StoryTeller

+0

@StoryTeller非常感謝您的幫助。 –

5

這三個聲明

char white[] = { 'a', 'b', 'c' }; 
char blue[] = "abc"; 
char *red = "abc"; 

是不同的。

第一個聲明一個字符數組,其中包含三個與初始值設定項對應的字符。

第二個聲明一個由四個字符組成的字符數組,因爲它是由包含終止零的四個字符的字符串文字初始化的。所以這個字符數組包含一個字符串。

第三個定義了一個字符串字面值,它是一個字符數組,並聲明瞭一個類型爲char *的指針,該指針由與字符串文字對應的字符數組的第一個字符的地址初始化。

因爲左對象是標量,可能不會被包含不止一個初始化列表來初始化你可以想象這個聲明一樣

char unnamed = { 'a', 'b', 'c', '\0' }; 
char *red = unnamed; 

這個聲明

char *green = { 'a', 'b', 'c' }; 

是無效的。

考慮到您可以使用複合文字來初始化指針。例如

char *green = (char[]){ 'a', 'b', 'c' }; 
+0

非常感謝你 –

+0

@SvenWilliamson根本沒有。不用謝。 –