3

我试图弄清楚为什么即使局部变量 i 从未在这个 C 程序中初始化,许多系统会打印出来0 1 2 3 4 5 6 7 8 9有人可以解释这是为什么吗?任何帮助表示赞赏!

void foo() {
   int i;
   printf("%d ", i++);
}
int main() {
    int j;
    for (j = 1; j <= 10; j++) foo();
}
4

5 回答 5

7

行为未定义。统计数据无关紧要。这可能是因为布局和堆栈的初始化,但也可能是由于任何其他原因。

例如,假设:

  1. 没有检查变量是否已初始化。
  2. 这是一个简单的堆栈机器。
  3. 堆栈初始化为 0。
  4. 该变量i是在堆栈上分配的,而不是作为寄存器分配的。
  5. 调用函数时,它不会初始化堆栈。

在这种情况下i,每次都会引用堆栈上的同一个位置,将从 0 开始,并且堆栈上的同一个位置将每次加一。

于 2012-12-02T06:27:13.370 回答
3

变量i是在堆栈上创建的,您没有对其进行初始化。所以它包含一些你无法预测的垃圾值。幸运的是,在您的情况下,该垃圾值最初为 0。如果在另一个系统上运行,您将获得一组不同的值。行为肯定是未定义的。

由于您除了在 for 循环中调用该函数之外什么都不做,幸运的是,该变量i每次都会被销毁并重新分配相同的内存空间。所以它在迭代中也保持了它的价值。

在我的系统上,它给出了这些值。

2009288233
2009288234
2009288235
2009288236
2009288237
2009288238
2009288239
2009288240
2009288241
2009288242
于 2012-12-02T06:27:36.950 回答
2

这可能是因为函数中的局部变量被重复地从同一个内存块中分配和释放。这就是输出重复递增的原因。

初始值为零是运气。它可能是任何其他垃圾值。

该行为是未定义的,不会在另一个系统上工作。

于 2012-12-02T06:28:24.603 回答
0

因为这是一个简单的程序,所以很幸运 i 使用了相同的内存位置。由于这未初始化,它将获取先前的值。

然而,这是未定义的。应该用警告编译它以找出这个错误。

于 2012-12-02T06:29:07.227 回答
0

正如其他人所指出的,这是未定义的行为,因此没有可靠的答案。

也就是说,你可能是对的,你得到的最常见的值是 0 到 9。这会发生,因为操作系统在你的程序接收它之前将堆栈占用的内存归零。foo()表示已进行的最深调用,因此它使用的是操作系统将其归零后尚未触及的内存,因此在第一次调用时,它很可能仍包含零。

在每个后续调用中,它可能会占据堆栈上的相同位置,因此在每个后续调用开始时,它可能以它在上一次调用结束时的值开始。

正因为它是未定义的行为,这根本不能保证,但是是的,它可能至少比没有的可能性更大。

于 2012-12-02T06:32:53.683 回答