使用一个值初始化整个2D数组

时间:2013-03-20 10:23:21

标签: c arrays initialization

使用以下声明

int array[ROW][COLUMN]={0};

我得到了全部为零的数组,但是使用了以下一个

int array[ROW][COLUMN]={1};

我没有得到所有值的数组。默认值仍为0.

为什么会出现这种行为?如何使用所有1进行初始化?

编辑:我刚才明白使用值为1的memset将每个字节设置为1,因此每个数组单元的实际值不会为1,而是16843009。如何将其设置为1?

7 个答案:

答案 0 :(得分:86)

您会收到此行为,因为int array [ROW][COLUMN] = {1}; 表示“将所有项目设置为1”。让我试着解释一下这是如何工作的。

初始化数组的明确,过于清晰的方式如下:

#define ROW 2
#define COLUMN 2

int array [ROW][COLUMN] =
{
  {0, 0},
  {0, 0}
};

但是,C允许您省略数组(或struct / union)中的某些项。你可以写一下:

int array [ROW][COLUMN] =
{
  {1, 2}
};

这意味着,将第一个元素初始化为1和2,其余元素“就好像它们具有静态存储持续时间”。 C中有一条规则,即所有未由程序员明确初始化的静态存储持续时间的对象必须设置为零。

所以在上面的例子中,第一行设置为1,2而下一行设置为0,0,因为我们没有给它们任何显式值。

接下来,C中有一条允许松散支撑样式的规则。第一个例子也可以写成

int array [ROW][COLUMN] = {0, 0, 0, 0};

虽然当然这种风格很差,但阅读和理解起来比较困难。但这个规则很方便,因为它允许我们编写

int array [ROW][COLUMN] = {0};

表示:“将第一行中的第一列初始化为0,将所有其他项初始化为具有静态存储持续时间,即将它们设置为零。”

因此,如果你尝试

int array [ROW][COLUMN] = {1};

表示“将第一行中的第一列初始化为1并将所有其他项目设置为零”。

答案 1 :(得分:23)

如果要将数组初始化为-1,则可以使用以下内容

memset(array, -1, sizeof(array[0][0]) * row * count)

但这仅适用于0-1

答案 2 :(得分:11)

int array[ROW][COLUMN]={1};

这只将第一个元素初始化为1.其他所有元素都为0。

在第一个例子中,您正在做同样的事情 - 将第一个元素初始化为0,其余元素默认为0.

原因很简单:对于数组,编译器会将您未指定的每个值初始化为0。

使用char数组,您可以使用memset来设置每个字节,但这通常不适用于int数组(尽管它适用于0)。

一般的for循环可以快速完成此任务:

for (int i = 0; i < ROW; i++)
  for (int j = 0; j < COLUMN; j++)
    array[i][j] = 1;

或者可能更快(取决于编译器)

for (int i = 0; i < ROW*COLUMN; i++)
  *((int*)a + i) = 1;

答案 3 :(得分:5)

请注意,GCC具有designated initializer表示法的扩展名,这对上下文非常有用。 clang也允许它没有评论(部分原因是它试图与GCC兼容)。

扩展表示法允许您使用...指定要使用以下值初始化的元素范围。例如:

#include <stdio.h>

enum { ROW = 5, COLUMN = 10 };

int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = 1 } };

int main(void)
{
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COLUMN; j++)
            printf("%2d", array[i][j]);
        putchar('\n');
    }
    return 0;
}

输出结果不出所料:

 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1

请注意,Fortran 66(Fortran IV)对阵列的初始值设定项有重复计数;当指定的初始化器被添加到语言中时,C总是让我感到奇怪的是C没有得到它们。并且Pascal使用0..9表示法来指定0到9(包括0和9)的范围,但C不使用..作为标记,因此未使用它并不奇怪。

请注意...符号周围的空格基本上是强制性的;如果它们附加到数字,则该数字被解释为浮点数。例如,0...9将被标记为0...9,并且不允许浮点数作为数组下标。 使用命名常量,...ROW-1不会造成麻烦,但最好养成安全习惯。

附录:

我顺便注意到GCC 7.3.0拒绝:

int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = { 1 } } };

标量初始值设定项1error: braces around scalar initializer [-Werror])周围有一组额外的括号。我不确定这是正确的,因为您通常可以在int a = { 1 };中围绕标量指定大括号,这是标准明确允许的。我也不确定它是不正确的。

我也想知道更好的符号是[0]...[9] - 这是明确的,不能与任何其他有效语法混淆,并避免与浮点数混淆。

int array[ROW][COLUMN] = { [0]...[4] = { [0]...[9] = 1 } };

也许标准委员会会考虑这个?

答案 4 :(得分:1)

要使用零初始化2d数组,请使用以下方法: int arr[n][m] = {};

注意:上述方法仅适用于以0初始化;

答案 5 :(得分:0)

改为使用 vector 数组:

vector<vector<int>> array(ROW, vector<int>(COLUMN, 1));

答案 6 :(得分:0)

char grid[row][col];
memset(grid, ' ', sizeof(grid));

用于将char数组元素初始化为空格字符。