2016-03-08 46 views
0

http://en.cppreference.com/w/cpp/language/storage_duration未初始化的變量 - 它傳遞給一個函數

Static local variables

Static variables declared at block scope are initialized the first time control passes through their declaration (unless their initialization is zero- or constant-initialization, which can be performed before the block is first entered). On all further calls, the declaration is skipped.

什麼是「靜態」在這句話的含義?它是:

static storage duration. The storage for the object is allocated when the program begins and deallocated when the program ends.

如果是這樣的話,那並不能說明什麼,在初始化方面main或任何其他功能發生int k;,因爲k不是一個靜態變量(它不會分配時程序結束時程序開始並解除分配 - 等待一秒鐘,您可能會說程序開始時main函數開始運行,程序結束時返回,但這不是我想到的)。

在主函數:

int k; 
k++; 

導致錯誤:uninitialized local variable 'k' used

因此,如果k以上不是一個靜態局部變量,你能舉一個這樣的變量的例子嗎?

誰能告訴我爲什麼下面的代碼編譯和運行沒有任何問題,即使k未初始化?

由於沒有身體的功能:

void foo(int* number) { } 

,並要求它像這樣在main

int k;  
foo(&k); 
k++; 

現在編譯並沒有問題運行,但k值爲-858993459 。編譯器不喜歡我試圖在沒有啓動的情況下增加它,但將它傳遞給foo導致編譯器忘記了它。爲什麼?

+0

下流者,小心解釋原因? – user5539357

+0

一個程序在調用'main'之前開始,在'main'返回之後結束。局部變量具有自動存儲持續時間,除非您使用'static'指定靜態持續時間,例如'static int k;' – molbdnilo

回答

0

可能取決於您的編譯器實現。 我猜編譯器會發現你的變量是以非const方式傳遞給函數的,所以函數可能會修改/初始化k的值。 您的編譯器不會深入該函數來推斷邏輯,因此它可讓您編譯代碼。

編輯:我沒有得到與這個在線compier相同的行爲:http://cpp.sh/9axqz 但編譯警告消失,只要我做了一些與函數中的數字。

+0

在Visual Studio中,我不會發出警告,而是編譯錯誤。傳遞給foo後,它消失。 – user5539357

0

靜態局部變量是這樣的:

void example() { 
    static int i = 0; // a static local variable 
    int j = 0; // not static 
    // ... 
} 

內建類型,例如int不會自動初始化。因此,當您將該變量設置爲有意義的內容之前嘗試讀取該變量時,可能會可能會,因爲它可以容納任何東西。

僅僅因爲你的特定編譯器不再給你一個警告並不意味着你的變量被正確初始化。作爲一個經驗法則,你應該始終明確地初始化變量,以避免意外從中讀取,而不必首先將其設置:

int i; // not initialized 
int j = 0; // explicitly set to 0 

這裏是C++的核心準則的鏈接初始化的話題:https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es20-always-initialize-an-object,它可能值得一讀。

+0

我對這篇文章中的靜態含義感到困惑。不知何故,我認爲他們在那裏使用了靜態變量的不同含義,尤其是靜態存儲已在前一段中進行了解釋...... – user5539357

0

靜態變量可以被定義如下:

int nextIndex() 
{ 
    static int index = -1; 
    return ++index; 
} 

所以,當你第一次調用這個函數的靜態變量index-1;被初始化。下一行將增加index1並返回結果。

所有後續調用nextIndex將只執行return ++index;部分並跳過初始化。

此外,靜態varibales會自動初始化爲零,如果未實現不同的話。

所以,如果你上面的函數改爲

int nextIndex() 
{ 
    static int index; 
    return ++index; 
} 

它返回的第一個值將是一個。第一次調用也不會初始化index,但是一旦程序啓動,它就會被初始化。