2013-05-08 40 views
4

考慮下面的代碼:爲什麼「char * ptr = {'R','E','D',' 0'};」 「char * ptr =」RED「時給出太多警告;」工作正常?

#include<stdio.h> 

int main() 
{ 
    char *ptr={'R','E','D','\0'}; 
    //char *ptr="RED"; 
} 

它顯示的警告名單如下:

warning: initialization makes pointer from integer without a cast| 
warning: excess elements in scalar initializer| 
warning: (near initialization for 'ptr')| 

但是,如果工作正常,如果我註釋掉的第一條語句並激活第二語句(被註釋掉在我的代碼中)。

這是爲什麼?在第一種情況下,爲什麼不是指向同一個陣列的指針未指定爲ptr,就像在第二種情況下一樣?這是什麼嚴格的技術原因?

回答

4

在6.7.9(11)[所述N1570草案,在相同6.7.8(11)C99的],則指定

爲標量的初始化應該是單個表達,可選地包含在大括號中。對象的初始值是表達式的初始值(轉換後);與簡單賦值相同的類型約束和轉換適用,將標量類型作爲其聲明類型的非限定版本。

通過

char *ptr={'R','E','D','\0'}; 

多單表達式提供更多您違反了 「不得」 的要求,並調用未定義的行爲(4(2)):

如果' '應該''或'不得'出現在約束或運行時約束之外的要求被違反時,行爲是未定義的。

說出來的方式,這種特殊的未定義行爲通常mainfests因爲編譯器忽略所有,但第一個表達式 - 除了的

warning: excess elements in scalar initializer| 

的產生和治療中的代碼,如果它是

char *ptr = {'R'}; 

那麼,這勿庸置疑導致

warning: initialization makes pointer from integer without a cast| 

因爲'R'是一個整數而不是指針。

在另一方面,

char *ptr = "RED"; 

是完全沒有問題,因爲該數組(1)"RED"被轉換爲指針到它的初始元件中的初始化,像這將是用於分配。

(1)字符串文字是數組,而不是指針,如6.4節所述。5(6):

在翻譯階段7中,字符或值爲0的代碼附加到每個多字節字符序列,該字符或字符序列由一個或多個字符串產生。 然後使用多字節字符序列來初始化靜態存儲持續時間和長度的數組,以便足以包含該序列。對於字符串文字,數組元素的類型爲char,並使用多字節字符序列的各個字節進行初始化。對於UTF-8字符串文字,數組元素的類型爲char,並使用UTF-8編碼的多字節字符序列的字符進行初始化。

(寬字符串文字是wchar_t[N]類型,char16_t[N]char32_t[N]的陣列,這取決於它們是否與LuU前綴。)

+0

大答案!!! – 2013-05-08 11:11:18

+0

但** H2CO3 **表示字符串字符串「RED」的類型爲char [4],而不是char *,但** paxdiablo **表示它的類型爲char *'。對? – 2013-05-08 11:19:41

+0

如果我是對的,你的回答在最後一行說,字符串文字確實是'char [4]'類型的,但是在賦給'ptr'之前它被轉換爲指針'char *'。 – 2013-05-08 11:21:18

相關問題