1. 程式人生 > >C語言中,變數的儲存型別有幾種?

C語言中,變數的儲存型別有幾種?

在C語言中,對變數的儲存型別說明有以下四種:

        auto          自動變數

        register     暫存器變數

        extern       外部變數

        static         靜態變數

         所謂儲存型別是指變數佔用記憶體空間的方式,也稱為儲存方式。變數的儲存方式可分為“靜態儲存”和“動態儲存”兩種。

         靜態儲存變數通常是在變數定義時就在儲存單元並一直保持不變,直至整個程式結束。動態儲存變數是在程式執行過程中,使用它時才分配儲存單元,使用完畢立即釋放。典型的例子是函式的形式引數,在函式定義時並不給形參分配儲存單元,只是在函式被呼叫時,才予以分配,呼叫函式完畢立即釋放。如果一個函式被多次呼叫,則反覆地分配、釋放形參變數的儲存單元。從以上分析可知,靜態儲存變數是一直存在的,而動態儲存變數則時而存在時而消失。

       我們又把這種由於變數儲存方式不同而產生的特性稱變數的生存期。生存期表示了變數存在的時間。生存期和作用域是從時間和空間這兩個不同的角度來描述變數的特性,這兩者既有聯絡,又有區別。一個變數究竟屬於哪一種儲存方式,並不能僅從其作用域來判斷,還應有明確的儲存型別說明。

       自動變數和暫存器變數屬於動態儲存方式,外部變數和靜態變數屬於靜態儲存方式。在介紹了變數的儲存型別之後,可以知道對一個變數的說明不僅應說明其資料型別,還應說明其儲存型別。因此變數說明的完整形式應為:儲存型別說明符 資料型別說明符 變數名,變數名....;

       總結與區別:變數根據定義的位置的不同的生命週期,具有不同的作用域,作用域可分為6種:全域性作用域,區域性作用域,語句作用域,類作用域,名稱空間作用域和檔案作用域。

     從作用域看:

全域性變數具有全域性作用域。全域性變數只需在一個原始檔中定義,就可以作用於所有的原始檔。當然,其他不包含全域性變數的定義的原始檔需要用extern關鍵字再次宣告這個全域性變數。

       靜態區域性變數具有區域性作用域,它只被初始化一次,自從第一次被初始化直到程式執行結束一直存在,它和全域性變數的區別在於全域性變數對所有函式都是可見的,而靜態區域性變數只對定義自己的函式體始終可見。

       區域性變數也只有區域性作用域,它是自動物件(auto),它在程式執行期間不是一直存在,而是隻在函式執行期間存在,函式的一次呼叫執行結束後,變數被撤銷,其所佔用的記憶體也被收回。

       靜態全域性變數也具有全域性作用域,它與全域性變數的區別在於如果程式包含多個檔案的話,它作用於定義它檔案裡,不能作用到其他檔案裡,即被static關鍵字修飾過的變數具有檔案作用域。這樣即使兩個不同的原始檔都定義了相同名字的靜態全域性變數,它們也是不同的變數。

       從分配空間看:

       全域性變數,靜態區域性變數,靜態全域性變數都在靜態儲存區分配空間,而區域性變數在棧裡分配空間。

       全域性變數本身就是靜態儲存方式,靜態全域性變數當然也是靜態儲存方式。這兩者在儲存方式上並無不同。這兩者的區別雖在於非靜態全域性變數的作用域是整個源程式,當一個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是有效的。而靜態全域性變數則限制了其作用域,即只在定義該變數的原始檔內有效,在同一個源程式的其他原始檔中不能使用它。由於靜態全域性變數的作用域侷限於一個原始檔內,只能為該原始檔內的函式公用,因此可以避免在其他原始檔中引起錯誤。

       (1)靜態變數會放在程式的靜態資料儲存區(全域性可見)中,這樣可以在下一次呼叫的時候還可以保持原來的賦值。這一點是它與堆疊變數和堆變數的區別。

       (2)變數用static告知編譯器,自己僅僅在變數的作用範圍內可見。這一點是它與全域性變數的區別。

         從以上分析可以看出,把全域性變數改變為靜態變數後是改變了它的儲存方式即改變了它的生存期。把全域性變數改變為靜態變數後是改變了它的作用域,限制了它的使用範圍。因此static這個說明符在不同的地方所起的作用是不同的。應予以注意:

         Tips:

         A.若全域性變數僅在單個C檔案中訪問,則可以將這個變數修改為靜態全域性變數,以降低模組之間的耦合度。

         B.若全域性變數僅由單個函式訪問,則可以將這個變數改為該函式的靜態區域性變數,以降低模組之間的耦合度。

         C.設計和使用訪問動態全域性變數、靜態全域性變數、靜態區域性變數的函式時,需要考慮重入問題,因為他們都放在靜態資料儲存區,全域性可見;

         D.如果我們需要一個可重入的函式,那麼我們一定要避免函式中使用static變數(這樣的函式被稱為:帶“內部儲存器”功能的函式)。

         E.函式中必須要使用static變數情況:比如當某函式的返回值為指標型別時,則必須是static的區域性變數的地址作為返回值,若為auto型別,則返回為錯指標。