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

Kra*_*ken 65 c arrays initialization

有以下声明

int array[ROW][COLUMN]={0};
Run Code Online (Sandbox Code Playgroud)

我得到所有零的数组,但使用下面的一个

int array[ROW][COLUMN]={1};
Run Code Online (Sandbox Code Playgroud)

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

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

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

Lun*_*din 94

你遇到这个问题,因为int array [ROW][COLUMN] = {1};并不意味着"所有设置项目之一." 让我试着解释一下这是如何工作的.

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

#define ROW 2
#define COLUMN 2

int array [ROW][COLUMN] =
{
  {0, 0},
  {0, 0}
};
Run Code Online (Sandbox Code Playgroud)

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

int array [ROW][COLUMN] =
{
  {1, 2}
};
Run Code Online (Sandbox Code Playgroud)

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

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

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

int array [ROW][COLUMN] = {0, 0, 0, 0};
Run Code Online (Sandbox Code Playgroud)

虽然这当然是不好的风格,但是阅读和理解起来比较困难.但这个规则很方便,因为它允许我们写

int array [ROW][COLUMN] = {0};
Run Code Online (Sandbox Code Playgroud)

这意味着:"将第一行中的第一列初始化为0,将所有其他项初始化为具有静态存储持续时间,即将它们设置为零."

因此,如果你尝试

int array [ROW][COLUMN] = {1};
Run Code Online (Sandbox Code Playgroud)

它意味着"将第一行中的第一列初始化为1并将所有其他项目设置为零".

  • 谢谢你,我能做些什么来用 1 初始化整个数组?考虑到我的行和列的大小为数百? (2认同)

use*_*512 28

如果要初始化阵列,-1那么可以使用以下方法,

memset(array, -1, sizeof(array[0][0]) * row * count)
Run Code Online (Sandbox Code Playgroud)

但是,这将工作0-1

  • 使用"sizeof(array)"而不是"sizeof(array [0] [0])*row*count"更容易. (8认同)
  • 需要在 C++ 中包含 `<cstring>` (5认同)

tep*_*pic 11

int array[ROW][COLUMN]={1};
Run Code Online (Sandbox Code Playgroud)

这只将第一个元素初始化为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;
Run Code Online (Sandbox Code Playgroud)

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

for (int i = 0; i < ROW*COLUMN; i++)
  *((int*)a + i) = 1;
Run Code Online (Sandbox Code Playgroud)


小智 10

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

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


Jog*_*mar 7

使用向量数组代替:

vector<vector<int>> array(ROW, vector<int>(COLUMN, 1));
Run Code Online (Sandbox Code Playgroud)

  • 有可能,但OP没有提到C++。 (4认同)

Jon*_*ler 6

请注意,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;
}
Run Code Online (Sandbox Code Playgroud)

毫不奇怪,输出是:

 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
Run Code Online (Sandbox Code Playgroud)

请注意,Fortran 66(Fortran IV)对数组的初始化程序具有重复计数。当将指定的初始值设定项添加到语言时,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 } } };
Run Code Online (Sandbox Code Playgroud)

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

我还想知道是否会有更好的表示法[0]...[9]-它是明确的,不能与任何其他有效语法混淆,并且避免与浮点数混淆。

int array[ROW][COLUMN] = { [0]...[4] = { [0]...[9] = 1 } };
Run Code Online (Sandbox Code Playgroud)

也许标准委员会会考虑这一点?