问题 将可变大小的多维C数组初始化为零


我想将可变大小的二维数组初始化为零。 我知道它可以用于固定大小的数组:

int myarray[10][10] = {0};

但如果我这样做,它就无法运作:

int i = 10;
int j = 10;
int myarray[i][j] = {0};

是否有单行方式执行此操作或是否必须遍历数组的每个成员?

谢谢


4778
2017-09-15 14:41


起源



答案:


您无法使用初始化程序对其进行初始化,但您可以 memset() 数组为0。

#include <string.h>

int main(void) {
  int a = 13, b = 42;
  int m[a][b];
  memset(m, 0, sizeof m);
  return 0;
}

注意:这是 C99 在 C89 m的声明( int m[a][b]; )是一个错误。


9
2017-09-15 14:52



@ vittorio88:您可能正在使用C ++编译器。在C中指向任何对象的指针(m 单独的,类型 int (*)[b])与指向void的指针兼容(类型 void *)这是什么 memset() 预计。那里没有问题。 - pmg


答案:


您无法使用初始化程序对其进行初始化,但您可以 memset() 数组为0。

#include <string.h>

int main(void) {
  int a = 13, b = 42;
  int m[a][b];
  memset(m, 0, sizeof m);
  return 0;
}

注意:这是 C99 在 C89 m的声明( int m[a][b]; )是一个错误。


9
2017-09-15 14:52



@ vittorio88:您可能正在使用C ++编译器。在C中指向任何对象的指针(m 单独的,类型 int (*)[b])与指向void的指针兼容(类型 void *)这是什么 memset() 预计。那里没有问题。 - pmg


在线C99标准(n1256草案),第6.7.8节,第3段:

要初始化的实体的类型应该是未知大小的数组或 不是可变长度数组类型的对象类型。

强调我的。

正如其他人所说,你最好的选择是使用 memset()


3
2017-09-15 15:19





如果你得到一个指向数据结构的指针,你可以试试 memset的


1
2017-09-15 14:47



+1 - memset是迄今为止初始化数组和新内存分配的最佳方式,它肯定适用于C ++,因此值得在C中尝试。 - ChrisBD
@kbrimington:在大多数情况下,数组名称“衰减”到指向其第一个元素的指针。这也适用于多维数组,因为memset()需要一个 void*,数组名称本身所代表的指针类型没有问题。 - pmg
@pmg - 谢谢。我理解这一点;但是,我很欣赏澄清。 - kbrimington
@ChrisBD:总的来说, memset 到目前为止,这不是初始化数据的最佳方式。你应该只在必要的时候使用它。初始化时通常更好 { 0 } 在C(或与... { } 在C ++中)尽可能。它更便携,更不容易出错(很容易将参数传递给 memset 在错误的顺序)。 - jamesdlin
@james - 文书错误的风险不能公平地用于证明“不是最好的方式”;如果是这样的话,所有具有多个参数的程序将是“迄今为止不是完成任务的最佳方式”。 :) memset 是完成OP要求的有效程序。 - kbrimington


您不能使用非常量变量创建静态数组。 尝试使用动态分配:

int i = 10;
int j = 10;
size_t nbytes = i*j*sizeof(int);
int* myarray = (int*) malloc(nbytes);
memset(myarray,0,nbytes);

0
2017-09-15 14:59



-0.5(四舍五入)in C99 您 做 可以使用非常量变量创建静态数组。 - pmg


C中不支持可变大小的二维数组。必须修复一个维度(我不记得它是第一个还是第二个)。我建议一旦定义就循环遍历它。


-1
2017-09-15 14:46



-0.5(四舍五入) C99 支持可变大小的二维数组。 - pmg
你是对的。我的错。 - erelender