用0填充多维数组元素

14

我有一个二维数组,我想在不循环所有元素的情况下将元素设置为零。

int a[100][200];

我不能在声明的时候初始化它们。


4
为什么不能在声明时初始化它们? - Greg Domjan
你是在尝试在一个类中声明它们吗? - cpx
12个回答

31

尝试一下

int a[100][200] = {{0}};

如果你初始化了一些(但不是所有)元素,剩下的元素将被初始化为零。在这里,你只显式地初始化了第一个子数组的第一个元素,编译器会处理其余部分。


2
+1 = {0} 也可以工作,但这样做可能会更好地避免编译器警告。 - Potatoswatter
13
更简洁地说,C++ 允许使用 = {}; - Johannes Schaub - litb
假设括号数量正确,这适用于超过2个维度的数组吗? - 101
1
@101 - 是的。你在显式初始化第一维中的第一个条目,其余部分会自动完成(无论维度如何)。 - bta

18

尝试使用memset(a,0,sizeof(a));

这将简单地用0字节覆盖数组所使用的内存。除非您确实知道自己在做什么,否则不要对用户定义的数据类型执行此操作。还有更加C++风格但不是最简单的方法:std::fillstd::fill_n


2
即使对于非用户定义的数据类型,这也可能会产生意外的结果。数据成员指针是一个例子,它们在GCC和Clang使用的C++-ABI(Itanium ABI)中使用了非0x0空指针编码 - 它们使用了所有1位。对于“int”来说,这应该没问题。 - Johannes Schaub - litb
你应该在这里使用 sizeof(a) * sizeof(int) 吗? - Mikhail
2
不需要乘以int大小,数组上的sizeof返回字节中的正确大小。 - Alexander Gessler

7

对于C++,您可以使用来自算法头文件的std:fill方法。

int a[x][y];
std::fill(a[0], a[0] + x * y, 0);

因此,在您的情况下,您可以使用以下内容:
int a[100][200];
std::fill(a[0], a[0] + 100 * 200, 0);

当然,0可以替换为任意整数值。

6

C++允许通过基元素指针完全迭代多维数组。因此,您可以使用std::fill并将其传递给第一个非数组元素。

std::fill(a[0] + 0, a[99] + 100, 0);

在C语言中,这是不被正式允许的,你需要单独迭代每个子数组,因为在C中,迭代超出第一个子数组的past-the-end指针会导致未定义的行为。尽管如此,在实践中仍然有效。

这还是真的吗?(以前是吗?) - Potatoswatter

3

“我无法在声明时初始化它们”是什么意思?是“不知道如何”还是“无法在那里修改代码”?

C++语言具有将整个数组在声明点初始化为0的功能。

int a[100][100] = {};

(注意,大括号之间没有必要显式地使用0)。你能使用它吗?
如果不能,那么你的选择是:使用memset技巧、1D重新解释技巧或通过迭代数组(使用或不使用std::fill)来显式设置每个元素。

在声明时进行初始化是被禁止的,例如当gotoswitch跳过声明进入变量作用域时。 - Potatoswatter

3

许多答案使用了指针算术和 fill。这可以更简单地完成:

int a[N][K];
fill(a[0], a[N], 0);

实际上,无论有多少维度,a[N]都是多维数组后面的第一个内存地址。这也适用:

int a[N][K][L][M];
fill(**a[0], **a[N], 0);

这里的星号将指针解引用为int*类型(数组括号将int****解引用为int***,两个星号完成其余工作)。

2

memset(a, 0, 100 * 200 * sizeof(int)); 应该就可以了。


(注:此代码是用于将数组a中的所有元素初始化为0,其中a数组的大小为100 * 200个int类型的元素)

1
如果这个数组在文件作用域声明,或者在函数作用域但使用了“static”,那么它会自动初始化为零,您不需要做任何事情。这仅适用于程序启动时的一次初始化;如果您需要重置它,则必须自己编写代码。我会使用memset来完成这个任务。
如果它在函数作用域中声明而没有使用static,则需要使用memset或显式初始化器——一个单独的= { 0 }就足够了,您不需要像其他人建议的那样写出所有2002个零。

还应该补充一点,静态变量和非静态声明变量的语义有很大不同。声明为静态的变量本质上声明了一个状态;这可能并不是OP想要的。我赞同memset方法(或明确的初始化程序)。 - Schedler

0

提到的memset方法(memset(a,0,sizeof(a));)可以工作,但是如果按照您的标签使用C++方式并使用向量呢?

std::vector<std::vector<int> > a;
a.assign(100, std::vector<int>(200));

0

我测试了这个解决方案,它有效。

int arr[100][200];

for (int i=0; i<100; i++)
    for (int j=0; j<200; j++) (arr[i][j] = 0);

for (int i=0; i<100; i++)
    for (int j=0; j<200; j++) cout << (arr[i][j]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接