0

可能重复:
未在 c 中初始化时 int 的默认值。为什么我得到不同的输出?

初学者所以小软..我在下面编译一个简单的代码,我没有为我的变量分配任何值但是C程序会生成一些随机值,为什么会这样?(只有第二个变量生成随机整数)

那么这些价值观是从哪里来的呢?

#include<stdio.h>

main(void) {
    int var1;
    int var2;

    printf("Var1 is %d and Var2 is %d.", var1, var2);
    return 0; //Book says I should use this for getting an output but my compiler anyways compile and return me values whether I use it or not
}

//Output 1st compiled: var1 = 19125, var2 = 8983
//Output 2nd compiled: var1 = 19125, var2 = 9207
//Output 2nd compiled: var1 = 19125, var2 = 9127
4

5 回答 5

3

您的C程序被编译为一些可执行程序。请注意,如果您在 Linux 上使用 编译gcc -Wall,您将收到有关未初始化变量的警告。

和变量被编译成使用一些堆栈槽或一些寄存器var1var2这些包含一些明显的随机数,您的程序会打印这些随机数。(这个数字并不是真正随机的,它只是不可预测的垃圾)。

C语言不要求对变量进行隐式初始化(​​与 Java 等相比)。

在实践中,我强烈建议在C 语言中始终显式初始化局部变量(通常,编译器可能足够聪明,甚至可以避免发出无用的初始化)。

您所观察到的称为未定义行为

如果您var1使用不同的编译器、使用不同的优化标志或使用不同的环境进行编译(可能export SOMEVAR=something在再次运行程序之前键入可能会更改输出var1,或者使用大量程序参数等...)。

您可以(在 Linux 上)编译gcc -fverbose-asm -S并添加各种优化标志(例如-O1-O2...)您的源代码,并使用一些编辑器yoursource.c查看生成的汇编代码。yoursource.s

于 2012-11-19T06:30:02.610 回答
2

在 C 中,当您声明变量时,会在堆栈上为它们保留一些空间。堆栈是 C 跟踪哪些参数传递给哪个函数、变量存储在哪里(如果您在函数中静态声明它们)、返回值存储在哪里等等的方式。每次调用函数时,它都会将值压入堆栈;也就是说,它将这些值写入堆栈上的下一个可用空间,并更新堆栈指针以解决此问题。当一个函数返回时,它会递减堆栈指针,指向它在前一个函数调用中指向的位置。

如果你声明了一个变量,但你没有初始化它,你只需要得到之前的任何值。如果调用了另一个函数,您可能会得到传递给该函数的参数;或者您可能会获得要返回的函数的返回地址。

在您呈现的情况下,您正在显示该main()函数,没有调用其他函数。但是,在加载程序的过程中,动态链接器可能调用了进程空间内的几个函数。因此,您看到的值可能是从那里遗留下来的。

但是,您不能依赖这些值是什么。它们可以是任何东西;它们可以初始化为 0,可以是随机数据,也可以是任何类型的内部数据。

于 2012-11-19T06:30:28.510 回答
1

var1 和 var2 的内容未定义。因此,它们可以包含任何有效值(取决于许多外部因素)。

只有第二个 var 接缝是随机的,这纯属幸运。改天再试一次,重启后或启动其他一些程序后,我敢打赌第一个 var 会改变。

于 2012-11-19T06:25:13.800 回答
0

它被称为局部变量。任何局部变量都有auto存储说明符,它们位于 C 中的堆栈上。

由于您尚未初始化这些变量,因此它将采用任何称为garbage value或的值indeterminate value(语言标准不强制要求它必须具有特定值),因此您将获得任何随机值。

var1您获得相同的价值,但没有获得相同的价值,这纯粹是巧合var2。但在任何其他系统上,它可能会给出不同的值,甚至在您的系统上可能会在一段时间后给出。所以,使用未初始化的变量是undefined behaviour

于 2012-11-19T06:27:24.517 回答
0

在 C 中,

如果变量被声明为全局或静态,那么它们会自动初始化为零。但是,如果它们被声明为 local ,那么这些变量的值是不确定的,即 ..,取决于编译器。(一些垃圾值)

于 2012-11-19T06:28:27.680 回答