繁体   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