2010-07-01 178 views
4

靜態和外部變量之間有什麼區別?做一個靜態變量有什麼好處? 爲什麼我們更喜歡在多功能程序中創建外部變量?這本書說,否則它很早就被初始化了。我不明白。靜態和外部變量

+3

C#和C++是非常不同的語言。由於「外部」變量的概念在C#中不存在,我假設這是關於C++的。 – 2010-07-01 19:33:17

+2

你也指哪本書?知道名稱/國際標準書號來清除你的問題會很方便(頁面也很方便)。 – XIII 2010-07-01 19:34:15

+0

讓我們通過yashwant kanetkar 和turbo c通過robert lafore – 2010-07-01 19:36:01

回答

24

問題是,在C靜態可以有不同的含義。我將嘗試在以下段落中概述不同的情況。

如果一個變量被定義在一個函數之外,它可以被文件中的所有函數使用。有時也稱爲「全局變量」。這意味着整個文件只有一個這個變量的實例。此外,變量的名稱存儲在生成的.OBJ文件中。後者很重要,因爲如果另一個文件在函數外還定義了一個具有相同名稱的變量,則鏈接器假定它們在兩種情況下都是相同的變量,並將它們合併。 爲了更清楚地說明,最好將關鍵字「extern」添加到其中一個變量中。在這種情況下,我們說我們聲明變量,而不是定義它。對編譯器/鏈接器來說,這是一個額外的信號,表明我們實際上想引用在其他地方定義的全局變量。

如果你想定義一個全局變量,但不想讓它可用於其他文件,請在之前添加關鍵字static。關鍵字static告訴編譯器,變量名不能存儲在.OBJ文件中。這意味着兩個.C文件具有以下行:

static long MyGlobalVariable; 

將分別具有自己的變量。這兩個變量將被稱爲MyGlobalVariable。

如果你在一個函數中定義了一個變量,它將變成一個局部變量。如果函數被調用,它就會存在,並在函數完成後再次消失。 在某些情況下,您希望在函數調用之間保留變量的值。您可以通過使用全局變量(而不是局部變量)來完成此操作,但是該變量可用於文件中的所有函數,您不一定需要該函數。在這種情況下,你可以把關鍵字static變量之前,像這樣:

void MyFunction() 
{ 
static long MyLocalVariable = 0; 
++MyLocalVariable; 
} 

第一次調用函數時,MyLocalVariable將「創造」,並與值0初始化在函數結束,變量不被破壞,但保持不變。因此,下次您調用此函數時,變量的值將爲1,而不是零。

在C中,將函數外部的變量(作爲全局變量)還是將其定義爲靜態函數並不重要。唯一的區別是變量可以被訪問的地方。

在C++中,情況完全不同。如果你寫這個(在函數外):

MyClass MyGlobalVariable; 

MyGlobalVariable將建造(這就是:構造函數將被執行),在應用程序開始之前,甚至主要被調用。但是,您無法真正控制所有全局變量的構建順序。 因此,如果另一個文件包含此:

MyOtherClass MySecondGlobalVariable; 

你無法知道自己是否MyGlobalVariable或MySecondGlobalVariable首先構造。如果其中一個的構造函數依賴於另一個的存在(構造),那麼這會產生問題。

在另一方面,如果你定義的變量作爲函數內部靜態:

void MyFunction() 
{ 
static MyClass MyStaticVariable; 
} 

然後MyStaticVariable將建造第一次函數被調用。利用這種結構,你可以寫這樣的事情:

MyClass &getMyClass() 
{ 
static MyClass MySelf; 
return MySelf; 
} 

我們已經實現了一個單,我們有構造時,它的控制。我們第一次需要它時,它就被構建了。

說實話,這種方法相當簡單,因爲它可能會導致多線程應用程序出現問題。在那種情況下,還有其他的技巧。

+0

這個問題現在只被標記爲C. – 2010-07-01 19:58:36

+0

關於你給出的例子,如果我重新啓動程序,第一行是靜態的long MyLocalVariable = 0; 它的值爲0.那麼它的值是1呢? – 2010-07-01 20:24:29

+0

在++ ++ MyLocalVariable行之後,它的值將爲1.如果稍後再次輸入函數,值將仍爲1,並且在++ ++ MyLocalVariable之後,值將爲2.依此類推。重要的是要看到初始化爲零僅在第一次輸入函數時(或者更確切地說,在變量被構建的那一刻)執行。 – Patrick 2010-07-01 20:47:00

-3

「靜態」或多或少意味着「這將永遠存在」。根據上下文,你會得到不同的結果:

static int global_variable; 
void function() 
{ 
     static int global_function_variable; 
} 

class foo 
{ 
     static void function() 
     { 
      static int foo_function_variable; 
      //... 
     } 
     static int foo_variable; 
} 

global_variable - 只有「翻譯單位」內纔可見。 (由於頭都或多或少複製的,這是否意味着在頭一個靜態全局存在爲它包含在所有的cpp文件不同的變量?)

global_function_variable創建第一次function被調用,並且將繼續貫穿整個項目的整個生命週期。值仍然存在,所以如果您在一次函數調用中更改它,則下一次函數調用將使用更改後的變量。

foo::function()是一個可以像全局函數一樣調用的函數;你不需要有一個foo的實例來調用它。這意味着它沒有有效的this指針,但是。同樣,即使沒有任何foo對象,foo_variable也存在。所有foo對象具有相同的foo_variable - 如果您在一個對象中更改它,則所有其他對象都會「看到」更改。

foo_function_variable行爲,我想,就像global_function_variable

背後extern的基本思想是控制變量的起重: 從MSDN

// specifying_linkage1.cpp 
int i = 1; 
void other(); 

int main() { 
    // Reference to i, defined above: 
    extern int i; 
} 

void other() { 
    // Address of global i assigned to pointer variable: 
    static int *external_i = &i; 

    // i will be redefined; global i no longer visible: 
    // int i = 16; 
} 

extern int global_variable; 

extern也可以使用利用另一種語言,最常見的一種可變鏈接,C.

global_variable是extern最常用的用法;它說其他地方有一個名爲「global_variable」的變量,我們將使用該變量。在某處,您需要聲明變量而不使用關鍵字extern,否則它永遠不會被創建。

+1

那些downvote請評論爲什麼? – Narfanator 2015-12-16 20:32:09