2013-02-01 21 views
1

在這段代碼中,爲什麼在我的測試中結果始終是1,23爲什麼未初始化的局部變量總是具有相同的初始值?

#include <stdio.h> 

void test() { 
    int a; 
    a++; 

    printf("%d",a); 
} 

int main(int argc, char *argv[]) { 
    test(); 
    test(); 
    test(); 
} 

我認爲test()中的變量是靜態的,不是嗎?爲什麼?

+1

http://stackoverflow.com/questions/1597405/what-happens-to-a-declared-uninitialized-variable-in-c-does-it-have-a-value – adt

回答

3

至於其他的答案告訴,你的變量沒有被初始化到初始化變量。 它打印1,2和3可能是因爲您的編譯器編譯的代碼prolog(prologue)清零與零堆棧。

C中的局部變量,實際上指向堆棧上的偏移量,stack frame將在返回調用後恢復。

我使用Google搜索並隨機選擇了一篇關於此的文章,請參見[How function calls work?]。

這裏是關於[Assembly Programming Assembly Function Stack Frame Explained](同樣,隨機選擇)的視頻講座。

而維基百科也解釋了[Call stack]。

+0

感謝您的視頻,這很有用。 – iLeoDo

9

該變量不是靜態的。您正在訪問未初始化的變量。行爲是未定義的。

2

因爲你正在使用一個非空間值(在這種情況下是隨機行爲)。

初始化您的變量(例如爲0):

#include <stdio.h> 
void test(){ 
    int a=0; 
    a++; 
    printf("%d",a); 
} 
int main(int argc, char *argv[]) { 
    test(); 
    test(); 
    test(); 
} 
+0

但爲什麼我的程序只顯示結果1,2,3? – iLeoDo

+0

這很複雜!它可能是:5,8,7。它是不確定的! 您的變量'a'可能是:0,它之前的值(可能是您的情況),甚至崩潰您的程序! 你總是需要初始化變量。 您可能會收到警告,是嗎? – Joze

+0

@Leo。董,你看到1,2,3的原因是因爲'test'的堆棧框架恰好和以前一樣佈置在同一個點上,所以有效地使'a'使用它以前的值。這完全是未定義的行爲,不能被依賴。你可以嘗試在你的'test()'調用之間插入一些函數調用(比如'printf'),並且看到'a'的未初始化值實際上受到'test()'之前調用的任何影響。 – Shahbaz

2

不,你的變量不是靜態的了!

https://stackoverflow.com/a/1597426/1758762

靜態變量(文件範圍和功能靜態)初始化爲零:

int x; // zero 
int y = 0; // also zero 

    void foo() { 
     static int x; // also zero 
    } 

非靜態變量(局部變量)是不確定的。在分配值之前讀取它們會導致未定義的行爲。

void foo() { 
    int x; 
    printf("%d", x); // the compiler is free to crash here 
} 
+0

但爲什麼我的程序只顯示結果1,2,3? – iLeoDo

1

您要打印的變量不是靜態的,也不是被初始化,因此正在採取垃圾值,這似乎是隨機給你,如果你在不同的機器上執行該程序,然後在那裏你會有不同的輸出,因爲在那裏你會爲了避免它有不同的垃圾值

,你將有一定的價值

+0

是垃圾值取決於機器? – iLeoDo

+0

垃圾值是未引用的值,它們仍然在您的內存中,但已經丟失了引用,因此您的編譯器會從任何內存位置進行拾取,這對我們來說是垃圾值 –

+0

我看,謝謝!我知道了! – iLeoDo