簡體   English   中英

C中的數組初始化

[英]Array initialisation in C

我對以下代碼有疑問:

int main()
{
    int array1 = {1,2,3,4,5}; //error in c++ , warning in c
    int array2[] = {1,2,3,4,5};
    int array3[5] = {1,2,3,4,5};
}

這段代碼在c++第3行給出了錯誤,但在c卻沒有?

我知道array1實際上是一個intarray2array3是數組,所以為什么c編譯器沒有顯示錯誤,只是一個警告:“標量初始化中的多余元素”

是否使用了這樣的定義,為什么它在c有效?

它無效C.見C11 6.7.9:

初始化程序不應嘗試為未初始化的實體中包含的對象提供值。

我猜你正在使用gcc。 然后,如果您希望程序的行為與嚴格的標准C一樣,請按以下方式編譯:

gcc -std=c11 -pedantic-errors

錯誤:標量初始化程序中的多余元素

是無效的C.它只是對代碼少檢查。 這是未定義的行為。

來自: C11草案N1570; 6.7.9初始化

約束
2初始化程序不應嘗試為未初始化的實體中包含的對象提供值。
3要初始化的實體的類型應為未知大小的數組或不是可變長度數組類型的完整對象類型。

絕對打破約束2. int是一個完整的對象類型嗎?

附件J.2(未定義的行為):

標量的初始值設定項既不是單個表達式,也不是括在括號中的單個表達式(6.7.9)。

額外:
@James Kanze:

prog.c:4:12: error: expected identifier or ‘(’ before numeric constant
  int i = 1,2,3,4,5;
            ^

你可以做到,但你需要做一個表達式:

int i = (1,2,3,4,5); //need parenthesis, evaluates to 5, values 1-4 thrown away.

使用initalizer-list初始化的int編譯會產生警告(在gcc中):

prog.c:5:2: warning: excess elements in scalar initializer [enabled by default]
  int j = {1,2,3,4,5};
  ^

但似乎編譯器足夠聰明,只能初始化int而不是以下內存。 演示

它符合C規范。

引自C11第6.7.9節(初始化):

句法

 1 initializer: assignment-expression { initializer-list } { initializer-list , } 

因此,初始化程序可以是直接表達式(上面的assignment-expression ),也可以是括號括起來的初始化程序列表。 標准的該部分中的約束不限制“正常”(非數組或非指針)變量。

這允許你寫例如

int a = { 1 };

和其他人一樣,我認為你想知道的是:

int array1 = {1,2,3,4,5};

在這種情況下,C和C ++之間沒有區別; 這條線在兩種語言中都是合法的,但它並不代表你的想法。 在C和C ++中,都有一個聲明,如果類型是標量類型( int is),那么{...}的內容必須是單個表達式。 並且1,2,3,4,5可以解釋為單個表達式(使用逗號運算符); 就像是:

int array1 = 1, 2, 3, 4, 5;

顯然是合法的。

這有點曖昧,但是,因為在這兩種語言,這種類型的初始化的語法使得,標點符號,而不是運營商。 所以這是一個解釋問題; 是內容必須是單個表達式語法約束的語句(這將導致逗號成為運算符),或對評估指定語法的結果的約束。 我的直覺是第二個是意圖,聲明應該導致錯誤。 但差異不在於C和C ++之間,而在於編譯器的作者解釋標准的方式。

編輯:

重新閱讀更接近:在C ++標准中,它明確地說明了這一點

如果T是標量類型,則表示聲明

\n     T x = {a};\n

相當於

\n     T x = a;\n

這並沒有留下太多的蠕動空間:在C ++中,聲明似乎顯然是合法的; 它只在C中存在一些歧義。

在C / C ++中初始化數組的正確方法是:

int array2[] = {1,2,3,4,5};

這里的方括號實際上告訴編譯器這是一個數組,在你的情況下是一組數字。 以這種初始化方式,不必指定數組的長度。 編譯器會知道。

第二種方法是定義一個數組並對其進行初始化:

int array3[5];
int *array = new int[5];

在這種情況下,您需要通知編譯器數組的大小。 此外,在第二種情況下,您需要手動刪除內存。

正如您的編譯器所說,這對C來說也是不正確的。 這里需要注意的重要一點是,在這種“約束違規”(官方術語)的情況下,編譯器可能只生成一個診斷(編譯器所做的)並繼續。

這就是為什么通常你應該確保你的代碼編譯而沒有任何診斷。

C是一種低級許可語言。 它允許影響指向int的指針。

int array1 = {1,2,3,4,5};

編輯:

我應該在編寫愚蠢的東西之前在不同的編譯器下測試它。

這被MSVC(2008)拒絕為錯誤。

gcc和clang都會excess elements in scalar initializer發出警告excess elements in scalar initializer並且只會影響1到a

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM