HOWTO · C
在 C 語言中將陣列初始化為 0
本教程介紹了在 C 語言中初始化陣列為 0 的不同方法。
本頁內容
若要在宣告 int 陣列時將每個元素初始化為零,可使用 int values[5] = {0};。在 C 中,第一個元素會以 0 初始化,聚合中的其餘元素也會一併初始化為零。如果陣列已經宣告,則可用迴圈逐一指定每個元素。memset 可以將陣列的位元組填為零,但填入位元組並不能普遍取代依型別進行的初始化。
宣告陣列時將元素初始化為零
如果在宣告陣列時已知其大小,可以使用初始化器。以下完整範例會印出初始化後的五個值。
#include <stdio.h>
int main(void) {
int values[5] = {0};
for (size_t i = 0; i < sizeof values / sizeof values[0]; ++i) {
printf("%d%s", values[i], i == 4 ? "\n" : " ");
}
return 0;
}
0 0 0 0 0
{0} 初始化器會明確將第一個元素設為零;聚合初始化也會將未指定的元素初始化為零。對於具有靜態或執行緒儲存期的物件,也可以省略初始化器:C 會自動將其初始化為零。一般未初始化的區域陣列具有自動儲存期,因此其元素不會自動設為零。請加入初始化器,或在讀取元素前先逐一指定其值。
使用迴圈將陣列元素初始化為零
如果陣列已經宣告,或元素值要在執行期間決定,使用迴圈會很方便。以下完整範例以陣列的元素數量作為迴圈界限,並印出結果。
#include <stdio.h>
int main(void) {
int values[5];
size_t count = sizeof values / sizeof values[0];
for (size_t i = 0; i < count; ++i) {
values[i] = 0;
}
for (size_t i = 0; i < count; ++i) {
printf("%d%s", values[i], i + 1 == count ? "\n" : " ");
}
return 0;
}
0 0 0 0 0
這裡的 sizeof 運算式之所以可行,是因為 values 在相同作用域中是陣列,而不是指標參數。如果將陣列傳給函式,請另外傳入其長度;在函式內,陣列參數會調整為指標,因此 sizeof 取得的是指標大小。
謹慎使用 memset()
標準函式庫函式 memset 會將相同的位元組值寫入一段記憶體。請包含 <string.h>,並使用 sizeof values 涵蓋目前作用域中的整個陣列,如以下完整範例所示。
#include <stdio.h>
#include <string.h>
int main(void) {
int values[5];
memset(values, 0, sizeof values);
for (size_t i = 0; i < sizeof values / sizeof values[0]; ++i) {
printf("%d%s", values[i], i == 4 ? "\n" : " ");
}
return 0;
}
0 0 0 0 0
第三個引數是位元組數,因此對這個陣列而言,sizeof values 是正確的。memset 不會將每個元素指定為特定型別的值,而是寫入全零位元的表示方式。只有當這種表示方式適用於該元素型別及平台時,才使用它。若要在宣告時以可攜方式將陣列初始化為語意上的零值,請優先使用 {0}。不要假設在所有 C 實作中,零位元組都代表空指標或浮點零。
將陣列初始化為非零值
在初始化器中列出所需的值,例如 int values[] = {2, 4, 6};。C 會根據初始化器的數量推斷最外層維度。對多維陣列使用這種形式時,只能省略最外層維度:int grid[][3] = {{1, 2, 3}, {4, 5, 6}};;內層維度必須指定。
GNU 範圍指定器,例如 int values[5] = {[0 ... 4] = 7};,是 GCC 擴充語法,並非可攜的標準 C 語法。如果需要讓程式適用於不同的 C 編譯器,請使用一般初始化器清單或迴圈。在此函式情境中,像 (int[]){1, 2, 3} 這樣的複合常值會建立一個區塊生命期的未命名陣列;這不是動態配置,也不能普遍取代具名陣列宣告來完成初始化。