声明时矩阵未填零

5

当我在另一个函数中调试我的代码时,我偶然发现了这种“奇怪”的行为。

#include <stdio.h>

#define MAX 20

int main(void) {
    int matrix[MAX][MAX] = {{0}};

    return 0;
}

如果我在return 0;行上设置断点并使用Code::Blocks查看本地变量,矩阵不是完全填充为零的。第一行是零,但数组的其余部分只包含随机垃圾。
我知道我可以使用双重for循环手动将所有内容初始化为零,但不是应该使用{{0}}初始化器将此矩阵全部填充为零吗?
也许因为今天太累了,但我能发誓我知道这个问题的答案。
我尝试使用不同的标准(使用Code::Blocks捆绑的gcc编译器)进行编译:-std=c89-std=c99std=c11但结果相同。
有什么想法?你能解释一下吗?
编辑: 我特别问的是{{0}}初始化器。
我一直认为它会将所有列和所有行都填充为零。
编辑2: 我特别关注Code::Blocks及其捆绑的GCC。其他评论说代码在不同平台上可以工作。但为什么对我无效? :/
谢谢。

1
这个答案说你做得很对。https://dev59.com/YXI-5IYBdhLWcg3wwbZL#1688758 - djechlin
@Dmitri 因为你必须假设前MAX个元素是第一行,进行数学计算,再用更多的数学计算来得到差异 - 我相信你已经回答了自己的问题 :P - djechlin
1
因为我想在左上角的子矩阵上工作,跳过外部部分会非常麻烦。 - Zorgatone
10
如果你使用优化编译,你不能完全相信调试器告诉你的结果。即使没有进行优化,我也不会百分之百地相信它。为了确保程序的准确性,请将值打印出来检查。 - interjay
4
确保在具有副作用的地方使用该对象,以确保编译器不会将其优化掉。 - ouah
显示剩余5条评论
2个回答

3
我已经搞清楚了。
即使编译器上没有任何优化标志,调试器信息也是错误的。
所以我用两个for循环打印出值,并且它被正确初始化,即使调试器说不一样(奇怪)。
然而还是感谢您的评论。

-1

你的代码应该将它初始化为零。实际上,你可以直接这样做:int matrix[MAX][MAX] = {};,它会被初始化为0。然而,int matrix[MAX][MAX] = {{1}}; 只会将matrix[0][0]设置为1,其他所有元素都是0。

我怀疑你在Code::Blocks中观察到的是调试器(gdb?)没有完全显示代码中断的位置 - 要么是优化器的某些副作用。为了测试这个理论,在初始化后立即添加以下循环:

``` int i,j;

for (i = 0; i < MAX; i++)
  for (j = 0; j < MAX; j++)
     printf("matrix[%d][%d] = %d\n", i, j, matrix[i][j]);

```

并查看它打印的内容是否与调试器的输出一致。

我猜可能发生的情况是,由于您没有使用矩阵,优化器可能已经决定不初始化它。为了验证,请反汇编您的主函数(在gdb中输入disass main),并查看矩阵是否实际被初始化。


1
在标准C中,不允许使用int matrix[MAX][MAX] = {}; - M.M
我已经找到了答案。你不能只在{}里面放一个零,双括号更好{{0}}。 另外,数组被正确初始化了,我发现调试器可能只是显示单元格出错了或者编译器在幕后做了一些优化(而我没有设置任何优化标志)。 - Zorgatone
我后面的代码中使用了矩阵,只是没有展示程序的其余部分,因为它与问题无关。在声明和初始化之后,我正在暂停调试器。 - Zorgatone

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