C 中未初始化的变量或数组

Uninitialized variable or array in C

C中未初始化数组的结果从何而来?它们是随机分配的值还是存储在内存中的只是以前的值?

#include <stdio.h>

int main (void)
{
    int values[10];
    int index; 

    values[0] = 197;
    values[2] = -100;
    values[5] = 350;
    values[3] = values[0] + values[5];
    values[9] = values[5] / 10;
    --values[2];

    for ( index = 0; index < 10; index++ )
        printf ("values[%i] = %i\n", index, values[index]);

    return 0; 
}

和输出:

$ ./a.exe
values[0] = 197
values[1] = 0
values[2] = -101
values[3] = 547
values[4] = 8
values[5] = 350
values[6] = 51
values[7] = 0
values[8] = 44045216
values[9] = 35

你认为"uninitialized"是什么意思?

表示还没有设置值。 因为它还没有被设置,所以它可以存储任何值。

也许是 0,也许是 547……
任何值都是有效的,并且不能保证您会找到什么。

嗯,这是 C 编程 101。 C 是一种 procedure-oriented 语言,没有实现面向对象语言(例如 Java)中存在的某些功能,例如 "automatic" 和保证变量的初始化。

如果您在 C 中声明一个自动变量(在堆栈上不是动态分配的)并且不提供初始值,那么这个变量将具有我们所说的 "garbage value"。这是一般行为,但具体实现可能会有所不同。

举个例子:

int a;  //a variable with no initial value
printf("%d", a); 

我们无法预测这将打印什么。可以是 0 也可以是其他任何东西。该程序也可能崩溃。本质上,这是未定义的行为。

如果在 Java 中也这样做,那么肯定会打印 0(因为 Java 默认情况下将所有整数初始化为 0)。

现在来回答您的数组问题:这是单个整数还是整数数组并不重要。任何你没有明确赋值的内存位置都会有一个 "garbage value"。它可以是 0 或其他。此行为完全依赖于机器且不可预测。

底线是:确保变量在使用前已初始化。

未初始化的值只是您的应用程序尚未写入的内存地址。这就像拥有一个您周围的每个人都可以使用的记事本。当您的程序运行时,它会得到该记事本的一小部分,以前可能已被其他人使用过,也可能未被其他人使用过。如果它是(很有可能),那么它上面仍然会写一些东西,但可能对你来说没有任何意义。如果你想知道那里有什么,你必须写点东西。一般情况下,我们都会往里面写0,就好像擦除一切,从一张白纸开始。

Chapter and verse:

6.2.4 Storage durations of objects
...
5 An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration, as do some compound literals. The result of attempting to indirectly access an object with automatic storage duration from a thread other than the one with which the object is associated is implementation-defined.

6 For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration or compound literal is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached.

添加了重点。

基本上,具有 auto 存储持续时间的对象不会隐式初始化为任何特定值 - 它们具有最后写入该特定内存位置的任何值1 .您不能依赖该值为 0(或其他任何值)。

上面引用的最后一句话适用于这样的情况:

for (;;)
{
  int x;
  do_something_with( x );
}

循环的每次迭代都会有效地破坏 re-creates x,并且您不能依赖在循环的任何迭代中写入 x 的值传递到下一个迭代。 实际上在类似 x86 的系统上,它很可能会被保留下来,但不要假设到处都是这种情况。

请注意,在调试模式或其他模式下构建时,实现 可能 决定使用某个已知值初始化 auto 变量。


  1. 其中的机制广泛多样,不值得在这里介绍。