初始化陣列,C語言中陣列的初始化

2020-07-16 10:04:25
如果沒有顯式地初始化陣列變數,那麼就會採用一般規則:如果陣列具有動態儲存週期,那麼陣列元素的值就是沒有定義的。否則,所有的元素都會被預設地初始化為 0(如果陣列元素是指標,則會被初始化為NULL)。

編寫初始化列表

當在定義陣列時,若要顯式地初始化陣列,必須使用初始化列表(initialization list):這是用逗號分隔開的初始化器(initializer)列表,也就是將每個陣列元素的初始值放在大括號 {} 內。如下所示:
int a[4] = { 1, 2, 4, 8 };

上述定義使得陣列 a 中的元素具有下面的初始值:
a[0] = 1, a[1] = 2, a[2] = 4, a[3] = 8

當初始化一個陣列時,請注意下面的規則:

(1) 不能在定義長度可變陣列時,進行初始化操作。

(2) 如果陣列具有靜態儲存週期,那麼該陣列的初始化器必須是常數表示式。如果陣列具有動態儲存週期,那麼可以在初始化器中使用變數。

(3) 如果提供了初始化列表,那麼可以在陣列定義中省略陣列長度,陣列長度由初始化器列表中最後一個陣列元素的索引值決定。例如,前面例子中陣列a的定義,等同於下面程式碼:
int a[ ] = { 1, 2, 4, 8 };   // 有4個元素的陣列

(4) 如果一個陣列的定義同時包含了對陣列長度指定和初始化列表,那麼長度是通過方括號內的表示式指定的。任何元素只要在列表中沒有對應的初始化器,就會被初始化為 0(對於指標型別,則初始化為 NULL)。如果列表中所包含初始化器比陣列元素更多,則多出來的初始化器直接被忽略。

(5) 最後一個初始化值後面如果還有多餘的逗號,則忽略此逗號。

根據這些規則,下面的定義都是等價的:
int a[4] = { 1, 2 };
int a[]  = { 1, 2, 0, 0 };
int a[]  = { 1, 2, 0, 0, };
int a[4] = { 1, 2, 0, 0, 5 };

在最後一行程式碼的陣列定義中,初始化器5被忽略了。當這種不匹配的情況發生時,大多數編譯器會發出警告。

陣列的初始化器必須與陣列元素具有相同的型別。如果陣列元素型別是聯合、結構或者陣列型別,那麼每個初始化器則又會是另一個初始化列表。例如:
typedef struct { unsigned long pin;
                 char name[64];
                 /* ... */
               } Person;
Person team[6] = { { 1000, "Mary"}, { 2000, "Harry"} };

陣列的其他 4 個元素會被初始化為 0,按照本例情況,為{0,""}。

可以利用字串字面量來初始化陣列 char、wchar_t、char16_t 或 char32_t。

初始化特定元素

借助於 C99 新增的元素指示符(element designator),可以把初始化器關聯到特定的元素。當需要把特定的元素與初始化器關聯時,將其索引值放在方括號內。換句話說,陣列元素的元素修飾符一般格式如下:

[常數表示式]


索引值必須是整數常數表示式,在下面的範例中,元素指示符是 [A_SIZE/2]:
#define A_SIZE 20
int a[A_SIZE] = { 1, 2, [A_SIZE/2] = 1, 2 };

該陣列在定義時把元素 a[0] 和 a[10] 初始化為 1,把元素 a[1] 和 a[11] 初始化為 2。該陣列的所有其他元素都被初始化為 0。在這個例子中,沒有元素指示符的初始化器會被關聯到前一個初始化元素的下一個元素。

如果在定義陣列時沒有指定其長度,那麼元素指示符的索引值可以是任何的非負整數值。因此,下面的定義會建立一個有 1001 個元素的陣列。
int a[ ] = { [1000] = -1 };

所有的陣列元素都具有初始值 0,但最後一個元素例外,它的初始值是 -1。