简体   繁体   English

如何在C中用零初始化数组[int][int]?

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

Picture this scenario.想象一下这个场景。 I need to store the quantity of products of a delivery.我需要存储交货的产品数量。 Each delivery and product has a number to identify it.每个交货和产品都有一个编号来识别它。 I am using an array somewhat like this: int array[500][500];我使用的数组有点像这样: int array[500][500];

The main issue is that I do not have idea how to initialize the whole array with 0s.主要问题是我不知道如何用 0 初始化整个数组。 Any left-out junk in the 500 slots can backfire eventually in the many other algorithms I still have to code. 500 个插槽中任何被遗漏的垃圾最终都会在我仍然需要编写的许多其他算法中适得其反。 I used to do int array[500] = {0};我以前做int array[500] = {0}; but in this case, there are two ID's related to each index.但在这种情况下,有两个 ID 与每个索引相关。

I used to do int array[500] = {0};我以前做int array[500] = {0}; but in this case there is two ID's related to each index.但在这种情况下,每个索引都有两个 ID。

Doesn't matter;没关系; that's still valid and appropriate in C11.这在 C11 中仍然有效和合适。

Try it and see!试试看!

Live demo现场演示

(Don't mind the ".cpp"; that's fixed for us by Coliru, but -xc tells GCC to compile the code as C.) (不要介意“.cpp”;这是 Coliru 为我们修复的,但是-xc告诉 GCC 将代码编译为 C。)


You do not need extra brackets.您不需要额外的括号。 The standard spells this out explicitly:该标准明确说明了这一点:

[C11: 6.7.9/20]: If the aggregate or union contains elements or members that are aggregates or unions, these rules apply recursively to the subaggregates or contained unions. [C11: 6.7.9/20]:如果聚合或联合包含作为聚合或联合的元素或成员,则这些规则递归地应用于子聚合或包含的联合。 If the initializer of a subaggregate or contained union begins with a left brace, the initializers enclosed by that brace and its matching right brace initialize the elements or members of the subaggregate or the contained union.如果子聚合或包含联合的初始值设定项以左大括号开头,则该大括号及其匹配的右大括号所包含的初始值设定项将初始化子聚合或包含联合的元素或成员。 Otherwise, only enough initializers from the list are taken to account for the elements or members of the subaggregate or the first member of the contained union;否则,只考虑列表中足够多的初始值设定项来考虑子聚合的元素或成员或所包含联合的第一个成员; any remaining initializers are left to initialize the next element or member of the aggregate of which the current subaggregate or contained union is a part.剩下的任何初始值设定项都将用于初始化当前子聚合或包含的联合所属的聚合的下一个元素或成员。

And later provides an example:后来提供了一个例子:

[C11: 6.7.9/26]: EXAMPLE 3 The declaration [C11: 6.7.9/26]:示例 3 声明

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

is a definition with a fully bracketed initialization: 1, 3, and 5 initialize the first row of y (the array object y[0] ), namely y[0][0] , y[0][1] , and y[0][2] .是一个带有完全括号初始化的定义:1、3 和 5 初始化 y 的第一行(数组对象y[0] ),即y[0][0]y[0][1]y[0][2] Likewise the next two lines initialize y[1] and y[2] .同样,接下来的两行初始化y[1]y[2] The initializer ends early, so y[3] is initialized with zeros.初始化器提前结束,所以 y[3] 用零初始化。 Precisely the same effect could have been achieved by完全可以达到同样的效果

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

The initializer for y[0] does not begin with a left brace, so three items from the list are used. y[0] 的初始值设定项不以左大括号开头,因此使用了列表中的三个项目。 Likewise the next three are taken successively for y[1] and y[2] .同样,对于y[1]y[2]连续采用接下来的三个。

Recall, by the way, that arrays are aggregates in C:顺便回忆一下,数组是 C 中的聚合:

[C11: 6.2.5/21]: Arithmetic types and pointer types are collectively called scalar types. [C11: 6.2.5/21]:算术类型和指针类型统称为标量类型。 Array and structure types are collectively called aggregate types.数组和结构类型统称为聚合类型。

Now, for the case of providing only one value (the 0), the normal rule you're used to (that all remaining elements take on zero anyway) still applies:现在,对于仅提供一个值(0)的情况,您习惯的正常规则(所有剩余元素无论如何都为零)仍然适用:

[C11: 6.7.9/21]: If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration. [C11: 6.7.9/21]:如果花括号括起来的列表中的初始化器比集合的元素或成员少,或者用于初始化已知大小数组的字符串文字中的字符比元素少在数组中,聚合的其余部分应与具有静态存储持续时间的对象一样隐式初始化。

You may still receive style warnings from your compiler about this (I don't), but you can ignore them.您可能仍会收到来自编译器的关于此的样式警告(我没有),但您可以忽略它们。

If you're using an antique version of C, though, you may need to double-up on your braces;但是,如果您使用的是 C 的古董版本,则可能需要加倍大括号; I'm not too familiar with the history of this feature.我不太熟悉这个功能的历史。

If the sizes of the array are compile-time constants like the value 500 then it is enough to write如果数组的大小是像值 500 这样的编译时常量,那么写就足够了

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

Or you can even use a designated initializer for example like或者您甚至可以使用指定的初始化程序,例如

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

or like或喜欢

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

or something similar.或类似的东西。

In this case all elements of the array will be zero-initialized.在这种情况下,数组的所有元素都将被零初始化。

If it is a variable length array then you may not initialize it at declaration.如果它是一个可变长度数组,那么您可能不会在声明时对其进行初始化。 In this case you can use the standard C function memset.在这种情况下,您可以使用标准的 C 函数 memset。 For example例如

#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 ) );
    //...

Use memset to initialize the entire memory block to 0:使用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.

So for your example:所以对于你的例子:

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

If your array is defined as a global variable or a static variable local to a function, you don't actually need to initialize it, all elements will have a zero value at program start.如果您的数组被定义为函数的全局变量或static变量,您实际上不需要初始化它,所有元素在程序开始时都将具有零值。

If the array is defined inside a function body with automatic storage, int array[500][500];如果数组定义在具有自动存储的函数体内,则int array[500][500]; , you can initialize it at the point of definition with ,您可以在定义点初始化它

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

If you mean to reset all values to zero at any point during program execution, you can use memset from <string.h> :如果您打算在程序执行期间的任何时候将所有值重置为零,您可以使用<string.h> memset

memset(array, 0, sizeof array);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM