在C语言中循环内重新声明数组

3

当循环声明数组时,数组是否在重复循环时被设置为零?

我有一个数组,并且正在这样使用它...

while(i<n)
{
    int a[1000];
    //taking inputs in array..
    /*some calculations with array..
    the values in array may change*/
}

下一次循环时,数组a被重新声明,这是一个新的数组,所以数组零位置的值不会保留。

实际上,我曾经用这种方式编写代码,并观察到值不为零,而是与之前循环结束时的值相同。为什么呢?


4
通常情况下,C语言不会对任何内容进行初始化;它可能只是指向相同的内存位置。您需要自己初始化数组。参见https://dev59.com/0HVC5IYBdhLWcg3wtzut。 - Robert Harvey
如果你没有显式地初始化数组,那么第二次循环时,它们可能包含上一次循环结束时剩下的值,否则就必须添加一些代码来更改它!然而,标准(C99)指出,“每次声明到达时,该值变得不确定”--注意这允许编译器将一个局部变量覆盖另一个变量,其中它可以计算出它们从未同时需要。 - user3793679
作为提醒,对于那些期望数组“通常”保持不变的人(在这个线程中有很多,什么鬼?),请考虑最基本的循环展开优化。虽然它可能不会用于1k数组,但如果它更小,它可能会为每个展开生成一个新的堆栈数组。 - Blindy
3个回答

3

数组的值未初始化,它们包含了在堆栈上的随机垃圾值。

此外,在每次循环运行中,数组中的数字可能会被覆盖。如果您需要在循环之间保持值不变,则应将数组声明提升到 while 循环之前。

使用:

int a[1000] = {0};

初始化数组为零。


2
它不是“用未定义的值初始化”。它只是没有被初始化,也就是根本没有任何操作发生。 - James Curran
1
英语语言的细微差别。 "Initialized"(特别是“ize”后缀)意味着一个过程正在做某事。因此,说“在每个循环中初始化...”意味着数组的当前值将被替换为其他值。 - James Curran

3

本地数组不会自动清零,即使是第一次使用。

您需要显式地进行清零:

while(i<n)
{
    int a[1000] = {0};
    // :
}

1
C++中的数组是否会被初始化为零? - vinay_Kumar
1
在C和C++中,数组没有默认初始化的要求。通常情况下,对于全局数组,库启动代码会将数组清零,但是局部数组从不会这样做。 - James Curran

1

原则上,每次都应该将其视为一个新数组。实际上,它很可能会携带与前一次迭代相同的值。如果您想要在每次循环时都获得完全新的数组,则需要使用malloccalloc进行分配1(然后在循环底部使用free以避免内存泄漏)。

考虑以下测试:

#include <stdio.h>

int main()
{
    int i = 0, n = 10;
    while(i++<n)
    {
        int a[10];
        printf("before assignment: %d\n", a[2]);
        a[2] = 5;
    }
    return 0;
}

在第一次迭代中,a [2] 可能包含任何值。实际上,在初始化之前读取该值是未定义行为。这绝对是要避免的事情,因为它可能导致不可预测的后果。
在第二次迭代(以及随后的迭代)中,当我测试时,它恰好包含 5(但不能保证应该如此)。
但是,如果您像这样初始化 a
int a[10] = {0};

那么每次都会使a的所有元素都为0。

1. 实际上,在实践中,如果您这样做,您可能仍然会得到相同的内存块。无论哪种方式,行为都不可靠。


3
读取未初始化的值是未定义行为。编译器可能会对整个循环进行优化,因为它可能假定循环永远不会被执行。 - mafso
2
数组随机值填充,在每个周期上,就像在第一个周期上一样。也许我们应该称其为垃圾而不是随机。这些值是特定内存位置中曾经存在的任何内容。在第一个周期中,它给出了具有某些陌生垃圾值的位置。在随后的周期中,它仍然给出具有一些垃圾值的位置,这次是熟悉的。但它们仍然是垃圾值。 - Utkan Gezer
1
我把它改成了“垃圾值”,这个术语确实更好。 - Kijewski
4
就像去当地游泳池游泳并被给予一个储物柜一样。假设你早上9:00进去,拿到第一个空闲储物柜的钥匙。但由于清洁不彻底,里面有一张废报纸。你把它拿出来,换成你的报纸。你在9:01离开游泳池,然后在9:02回来。柜台上的可爱女孩用奇怪的眼神看着你,又给了你同样的钥匙。储物柜里会有你的报纸,但是,如果她有机会,她会把钥匙给别人。除非你买下那个储物柜,否则就将变量声明在循环外部。 - Utkan Gezer
1
是的,它确实可以:反对者应该撤回他们的投票 :) 除此之外,我不确定 OP 实际上做了什么:读取未初始化的值(她必须以某种方式确定其中的值),在这种情况下,应该指出这是 UB;或者如果她(根据问题中给出的评论所示)没有这样做,但在调试器中看到了数组的值,那么唯一的误解就是自动变量被初始化了。在没有澄清这一点的情况下,我不会改变任何东西。 - mafso
显示剩余10条评论

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