簡體   English   中英

如何在C中用零初始化數組[int][int]?

[英]How to initialize an array[int][int] with zeros in C?

想象一下這個場景。 我需要存儲交貨的產品數量。 每個交貨和產品都有一個編號來識別它。 我使用的數組有點像這樣: int array[500][500];

主要問題是我不知道如何用 0 初始化整個數組。 500 個插槽中任何被遺漏的垃圾最終都會在我仍然需要編寫的許多其他算法中適得其反。 我以前做int array[500] = {0}; 但在這種情況下,有兩個 ID 與每個索引相關。

我以前做int array[500] = {0}; 但在這種情況下,每個索引都有兩個 ID。

沒關系; 這在 C11 中仍然有效和合適。

試試看!

現場演示

(不要介意“.cpp”;這是 Coliru 為我們修復的,但是-xc告訴 GCC 將代碼編譯為 C。)


您不需要額外的括號。 該標准明確說明了這一點:

[C11: 6.7.9/20]:如果聚合或聯合包含作為聚合或聯合的元素或成員,則這些規則遞歸地應用於子聚合或包含的聯合。 如果子聚合或包含聯合的初始值設定項以左大括號開頭,則該大括號及其匹配的右大括號所包含的初始值設定項將初始化子聚合或包含聯合的元素或成員。 否則,只考慮列表中足夠多的初始值設定項來考慮子聚合的元素或成員或所包含聯合的第一個成員; 剩下的任何初始值設定項都將用於初始化當前子聚合或包含的聯合所屬的聚合的下一個元素或成員。

后來提供了一個例子:

[C11: 6.7.9/26]:示例 3 聲明

int y[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 }, };

是一個帶有完全括號初始化的定義:1、3 和 5 初始化 y 的第一行(數組對象y[0] ),即y[0][0]y[0][1]y[0][2] 同樣,接下來的兩行初始化y[1]y[2] 初始化器提前結束,所以 y[3] 用零初始化。 完全可以達到同樣的效果

int y[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 };

y[0] 的初始值設定項不以左大括號開頭,因此使用了列表中的三個項目。 同樣,對於y[1]y[2]連續采用接下來的三個。

順便回憶一下,數組是 C 中的聚合:

[C11: 6.2.5/21]:算術類型和指針類型統稱為標量類型。 數組和結構類型統稱為聚合類型。

現在,對於僅提供一個值(0)的情況,您習慣的正常規則(所有剩余元素無論如何都為零)仍然適用:

[C11: 6.7.9/21]:如果花括號括起來的列表中的初始化器比集合的元素或成員少,或者用於初始化已知大小數組的字符串文字中的字符比元素少在數組中,聚合的其余部分應與具有靜態存儲持續時間的對象一樣隱式初始化。

您可能仍會收到來自編譯器的關於此的樣式警告(我沒有),但您可以忽略它們。

但是,如果您使用的是 C 的古董版本,則可能需要加倍大括號; 我不太熟悉這個功能的歷史。

如果數組的大小是像值 500 這樣的編譯時常量,那么寫就足夠了

int array[500][500] = { 0 };

或者您甚至可以使用指定的初始化程序,例如

int a[500][500] = { [0][0] = 0 };

或喜歡

int a[500][500] = { [0] = { 0 } };

或類似的東西。

在這種情況下,數組的所有元素都將被零初始化。

如果它是一個可變長度數組,那么您可能不會在聲明時對其進行初始化。 在這種情況下,您可以使用標准的 C 函數 memset。 例如

#include <string.h>

//...

int main( void )
{
    size_t m = 500;
    size_t n = 500;

    int array[m][n];

    memset( array, 0, m * n * sizeof( int ) );
    //...

使用memset將整個內存塊初始化為 0:

NAME         
   memset - fill memory with a constant byte

SYNOPSIS         
   #include <string.h>

   void *memset(void *s, int c, size_t n);

DESCRIPTION         
   The memset() function fills the first n bytes of the memory area
   pointed to by s with the constant byte c.

RETURN VALUE         
   The memset() function returns a pointer to the memory area s.

所以對於你的例子:

int array[500][500];
memset(&array, 0, sizeof(int) * 500 * 500);

如果您的數組被定義為函數的全局變量或static變量,您實際上不需要初始化它,所有元素在程序開始時都將具有零值。

如果數組定義在具有自動存儲的函數體內,則int array[500][500]; ,您可以在定義點初始化它

int array[500][500] = { 0 };

如果您打算在程序執行期間的任何時候將所有值重置為零,您可以使用<string.h> memset

memset(array, 0, sizeof array);

暫無
暫無

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

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