繁体   English   中英

用一个值初始化整个二维数组

[英]Initializing entire 2D array with one value

使用以下声明

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

我得到的数组全为零,但有以下一个

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

我没有得到所有一个值的数组。 默认值仍然是 0。

为什么会出现这种行为以及如何用全 1 进行初始化?

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

你会得到这种行为,因为int array [ROW][COLUMN] = {1}; 并不意味着“所有设置项目之一。” 让我尝试逐步解释这是如何工作的。

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

#define ROW 2
#define COLUMN 2

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

但是,C 允许您省略数组(或结构/联合)中的某些项目。 例如,您可以编写:

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则可以使用以下命令,

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

但这仅适用于0-1

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;

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

注意:上述方法只能用 0 初始化;

请注意,GCC 对指定的初始化符号进行了扩展,这对于上下文非常有用。 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 没有得到它们总是让我感到奇怪。 并且 Pascal 使用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 } } };

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

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

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

也许标准委员会会考虑?

改用向量数组:

vector<vector<int>> array(ROW, vector<int>(COLUMN, 1));
char grid[row][col];
memset(grid, ' ', sizeof(grid));

那是为了将 char 数组元素初始化为空格字符。

暂无
暂无

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

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