2010-02-07 86 views
37

我的理解是int變量會自動初始化爲0;但是,事實並非如此。下面的代碼打印一個隨機值。C++中的變量初始化

int main() 
{ 
    int a[10]; 
    int i; 
    cout << i << endl; 
    for(int i = 0; i < 10; i++) 
     cout << a[i] << " "; 
    return 0; 
} 
  • 什麼規則,如果有的話,適用於初始化?
  • 具體來說,變量在什麼條件下自動初始化?

回答

62

將自動初始化,如果

  • 它是一個類/結構實例中的默認構造函數初始化所有基本類型;像MyClass instance;
  • 你使用數組初始值設定語法,例如int a[10] = {}(所有零)或int a[10] = {1,2};(所有零除第一兩個項目:a[0] == 1a[1] == 2
  • 同樣適用於非集合類/結構,例如MyClass instance = {}; (更多相關信息,可以發現here
  • 這是一個全局/外部變量
  • 變量定義static(無論在函數內部或全局/命名空間範圍) - 感謝傑裏

永遠不要相信自動初始化的普通類型(int,long,...)的變量!它可能發生在C#等語言中,但不在C++中。

+7

第一點是有點不準確。如果它是非POD類型,它將自動初始化。 :) – jalf 2010-02-07 21:34:17

+0

對,改變了;)thx – AndiDog 2010-02-07 21:49:47

+2

「簡單類型」的靜態存儲持續時間的變量也被初始化爲零(或者在指針的情況下爲空指針)。這可以是在函數內部聲明爲'static'的東西,或者是在命名空間範圍內聲明的東西(即在任何函數之外)。 – 2010-02-07 23:22:16

12

int不初始化爲零。當你說int i;時,你所做的只是爲整數保留空間。該位置的值未初始化。這隻會在您說int i = 0;(或int i = 5;,在這種情況下,該值初始化爲5)完成。無論如何,將變量初始化爲某個已知值是一種很好的做法。否則,i保留任何隨機值在該空間爲其保留時在該內存位置。這就是爲什麼cout打印出一個隨機值。

默認值取決於語言的實現。有些語言會將其初始化爲一些「理智」的值(比如0)。作爲一個經驗法則,我總是將一個變量初始化爲一個合理的值(除非我知道在我使用它之前我將它初始化爲肯定是)。正如我之前提到的,假設這個值是理智的。它可能會也可能不會(取決於語言,或者該語言的解釋器/編譯器的實現)。

2

除非您自己做,否則局部變量不會被初始化。你看到的是在你的方法被調用之前堆棧中的垃圾。

4

這個職位的最佳說它:http://www.velocityreviews.com/forums/showpost.php?p=1528247&postcount=10

有沒有「默認」構造函數 非類的類型,但默認 (零)的初始化。不幸的是,對於 使用C新空房禁地的兼容性, 默認的初始化是不是在以下 情況進行 爲POD類型:

裸(即不宣佈初始化 )局部變量的 類或函數。

動態分配的實例。

然而,在其他地方(尤其是 靜態變量)和中給出的空初始化 paramters 任何東西的情況下(當是有效的),得到 默認的(零)的初始化。

+1

我不會說這是由於「對C的敏感程度」,我認爲它更多地與C++的「不支付你不使用的」哲學有關。 – Manuel 2010-02-08 20:10:29

3

在C++中,自動變量是未定義的,直到它們被明確賦予一個值。也許你正在考慮C#或其他.Net語言或Java。

5

請參見4.9.5 C++編程語言的初始化。

取決於您的變量是否是本地的,可能會發生靜態,用戶定義或常量默認初始化。

因爲您正在使用POD(普通舊數據類型),所以自動變量未初始化爲任何默認值。

4

要強制POD的初始化(這int是),你可以使用複製初始化語法:

#include <iostream> 

int main() { 
    int i = int(); 
    int j; 

    std::cout << "i: " << i << std::endl; 
    // warning: undefined behavior 
    std::cout << "j: " << j << std::endl; 
} 

這是屬於在「只付你使用什麼」。如果你打算隨後給變量賦值,或者根本不使用它,那麼沒有理由去完成初始化它的工作。要做到這一點,你必須明確地要求完成這項工作。

+1

這對'unsigned int's或'long long'或類似的類型在GCC中包含多個單詞不起作用,但它可以在MSVC中工作,相關問題:http://stackoverflow.com/questions/2144012式/顯式型轉換和 - 多簡單型說明符 – smerlin 2010-02-08 19:42:10

0

儘管您最近的發現可能不受歡迎(因爲您可能需要初始化其他語言將要處理的某些變量),但這可能意味着更少的cpu週期,從而代碼更快。

2

如果沒有爲對象指定初始值設定項,則該對象將被默認初始化;如果不執行初始化,則具有自動或動態存儲持續時間的對象具有不確定的值。

Par。 8.5,最近的C++ 0x N3092.pdf草案的部分11,

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/

3

不同的操作系統(即OS X與Ubuntu Linux操作系統)將不同的反應,未初始化與在C++中初始化變量。根據我的經驗,OS X版本的gcc將爲以下兩個版本的代碼編譯並打印出2。就像我在Ubuntu Linux機器上工作一樣,第一個代碼塊將打印出發生在內存位置的變量引用(循環後的+2)。

int c; 

    for(int i = 0; i < 3; i++) 
    { 
     c++; 
    } 

    cout << c << endl; 

凡爲,他們都會給你同樣的結果:

int c = 0; 

    for(int i = 0; i < 3; i++) 
    { 
     c++; 
    } 

    cout << c << endl; 
-1

這裏int i;是一個自動變量必須手動初始化。自動變量不會在c和C++中自動初始化。

如果你想編譯器進行初始化,然後你需要使用下面的東西,

聲明i爲靜態變量。

static int i; //零由編譯器分配給i。

聲明i作爲全局變量[在main()外部)。