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} 這樣的複合常值會建立一個區塊生命期的未命名陣列;這不是動態配置,也不能普遍取代具名陣列宣告來完成初始化。