2010-06-11 348 views
10

當我看到這個符號時,我感到非常驚訝。它是做什麼的,它是什麼樣的C概念?什麼是「int * a =(int [2]){0,2};」準確地做?

+0

在C模式下編譯時無法用VC++進行編譯。你試過什麼編譯器? – AraK 2010-06-11 14:49:00

+0

它適用於GCC,所以也許它不在C標準? – Dpp 2010-06-11 14:53:36

+0

我猜你是對的 - 這是另一個GCC擴展。不知道你從中獲得什麼。 – 2010-06-11 14:56:13

回答

19

這是C99標準第6.5.2.5節定義的複合字面值。

它不是C++語言的一部分,因此C++編譯器不編譯它並不奇怪。 (或Java或Ada編譯器)

複合文字的值是由 初始值設定項列表初始化的未命名對象的值。如果複合文字出現在函數體外部,則對象 具有靜態存儲持續時間;否則,它具有與 封閉塊關聯的自動存儲持續時間。

所以不,它不會破壞堆棧。編譯器爲該對象分配存儲空間。

括號放在類型中,然後是一個初始化列表 - 它不是一個強制轉換,因爲在C99語法中,初始化列表沒有意義;相反,它是應用於產生給定類型對象的類型的後綴運算符。您不是創建{ 0, 3 }並將其轉換爲數組,您正在使用值0和3初始化int[2]


至於爲什麼它的使用,我看不到一個很好的理由在你的單行線,雖然它可能是一個可以被重新分配在其他一些陣列點帶面,所以這是一個較短的方式這樣做的前兩行:

int default_a[] = { 0, 2 }; 
int *a = default_a; 

if (some_test) a = get_another_array(); 

我已經找到了通過臨時工會職能

// fills an array of unions with a value 
kin_array_fill (array, (kin_variant_t) { .ref = value }) 
+0

很好的解釋! 聯合的好例子,它是初始化並傳遞指向函數的一個簡短方法。它看起來像匿名數組。遺憾的是它沒有在C++中實現 – Dpp 2010-06-11 16:39:32

+0

我剛剛查找了C++中的匿名數組,並且似乎有點類似的東西將在C++ 0x中實現:std :: initializer_list <>,例如,對於我們的示例,您可以在函數原型中指定std :: initializer_list 作爲參數,併爲該函數提供一個初始化程序列表,如{0,2}。 – Dpp 2010-06-11 16:50:31

-2
  • {0, 2}爲包括0和2
  • (int[2])它轉換爲一個數組的數組符號(不知道爲什麼)
  • int * a =將它分配給int指針a。
+0

沒有強制轉換,編譯器將其視爲試圖將多個值分配給標量變量。 – eemz 2010-06-11 14:50:15

+5

-1這不是演員。 – Artefacto 2010-06-11 15:23:40

0

(int [2])告訴編譯器,下面的表達式應該被轉換爲int [2]。這是必需的,因爲可以將{0,2}轉換爲不同的類型,如long [2]。 Cast在編譯時發生 - 而不是運行時。

整個表達式在內存中創建一個數組,並將a指向該數組。

1
  1. 在堆棧上爲[數組]兩個int s分配空間。
  2. 將兩個int的[數組]分別填入值02
  3. 聲明類型爲int*的局部變量,併爲該變量分配兩個int的[數組]的地址。
6

這是C99結構有用,稱爲複合文字

從2005年5月委員會節6.5.2.5草案:

即由 帶括號的類型名稱後面 初始化 的brace-封閉列表後綴表達式是字面的化合物。它提供了一個 未命名對象,其值由初始值列表 給出。

...

實施例1的文件的範圍定義

int *p = (int []){2, 4}; 

初始化p 指向一個 陣列2個整數的第一元件,所述第一具有 的價值二和第二,四。 這個複合詞 的表達式必須是常量。 未命名對象的持續時間爲靜態存儲 。

相關問題