为什么它第一次显示777

时间:2011-04-08 03:22:35

标签: c linux

这是我的代码:

#include <stdio.h>


void foo(void)
{
    int i;
    printf("%d\n", i);
    i = 777;
}

int main(void)
{
    foo();
    //printf("hello\n");
    foo();
    return 0;
}

它显示:

-1079087064
777

但如果您删除代码中的//,则会显示:

134513817
hello
13541364

所以为什么它第一次显示777,

感谢

4 个答案:

答案 0 :(得分:4)

您正在做的是undefined behavior。您正在打印未初始化变量的值。该数字可以基于之前在该变量的内存位置中的任何内容。

答案 1 :(得分:1)

如果你希望它是777,那么两次都这样做:

void foo(void)
{
    int i = 777;
    printf("%d\n", i);
}

让我也解释为什么它是未初始化的东西给出了这种未定义的行为。当你创建一个变量时,它会为变量分配一些内存。此内存可能已经从之前使用那些(或那些)内存块的其他程序中获得了一些值。然后将这些值存储在变量中,直到您将其设置为其他值,例如使用=运算符赋值。

答案 2 :(得分:1)

我相信它第一次显示777(没有printf)因为你的c编译器如何工作并使用基于堆栈的内存模型将c转换为汇编。查看维基百科有关汇编语言和堆栈的更多信息。

在你的第一个测试中,你输入了函数foo,它'创建'(可能仅通过移动堆栈指针)堆栈中的空间为局部变量i,打印它的垃圾值(-1079087064)然后设置该内存到777.然后它又回到了主要部分并再次调用了foo。这个调用与第一个调用完全相同,它在前一次调用的同一位置“创建”它的空间,并打印出任何值。由于该内存先前已设置为777,即打印的内存。两个foo调用将编译为类似的东西:

call foo
call foo

在你的第二个例子中,在调用foo之间调用了printf。

call foo
; code to set up call to printf, probably involving stack
call printf ; most definitely changing the stack
; clean up also probably changes the stack
call foo

因此,在调用printf时涉及的许多赋值改变了堆栈内存中变量i的赋值。随后对foo的调用只打印出一个新的垃圾值,可能与之前的内存位置相同。

答案 3 :(得分:0)

除了要求打印它的内容之外,

i没有被初始化。因此,它可以打印任何(垃圾值),这是未定义的行为