天天看點

全局變量、局部變量(auto局部變量)、靜态全局變量、靜态局部變量的差別

C/C++變量根據定義位置的不同,具有不同的作用域和存儲域。

作用域可分為6種:全局作用域,局部作用域,語句作用域,類作用域,命名作用域和檔案作用域。

存儲域可分為2種:靜态存儲區和棧區,另:函數申請記憶體空間在堆區裡面(這不在本文讨論範圍之内)。

首先,從作用域看,

全局變量具有全局作用域,隻需在一個源檔案中定義,就可以作用于所有的源檔案。當然,其它不包括全局變量定義的源檔案,需要用extern關鍵字再次聲明該全局變量,之後才可以在該源檔案中使用;

靜态全局變量具有全局作用域,它與全局變量的差別在于,如果程式包含多個檔案的話,它作用于定義自己的檔案裡,不能作用于其它源檔案中,即被static關鍵字修飾過的變量具有檔案作用域。是以即使兩個不同的源檔案都定義了相同的靜态全局變量,他們也是不同的變量;

局部變量具有局部作用域,它是自動(auto)類型,在程式運作期間不是一直存在,隻有在函數執行期間存在,函數的一次調用結束後,變量所占用的記憶體即被收回;

靜态局部變量具有局部作用域,它隻被初始化一次,從第一次初始化到程式運作結束都一直存在,即使函數調用結束後也仍然存在,但不可被其它函數調用,因其隻對定義自己的函數體可見。

其次,從存儲域(也即記憶體配置設定空間)看,

全局變量、靜态全局變量、靜态局部變量都在靜态存儲區配置設定空間,而局部變量在棧區配置設定空間。

1、靜态存儲區裡的資料可以在下一次調用的時候保持原來的指派,這是其與棧變量和堆變量的最大差別。

2、靜态變量用關鍵字static告知編譯器自己的作用域。

3、函數中必須要使用static變量的情況:當某函數的傳回值為指針類型時,則必須是static的局部變量的位址作為傳回值,若為auto類型,則傳回為錯指針。

從以上分析可以看出,局部變量改變為靜态局部變量後是改變存儲方式,即改變了生存周期;而把全局變量改變為靜态變量後是改變了作用域,限制了其使用範圍。

另外詳細對比靜态局部變量與自動局部變量的差別:

1、一般情況下,不作專門說明的局部變量,均是自動變量,可用關鍵字auto作出說明,稱作為自動局部變量。不存在自動全局變量,全局變量的類型隻能定義為extern或static。

2、靜态局部變量屬于靜态存儲類别,在靜态存儲區内配置設定存儲配置設定單元。在程式整個運作期間都不釋放。而自動變量(即動态局部變量)屬于動态存儲類别,占動态存儲區空間而不占靜态存儲空間,函數調用結束後立即釋放。

3、靜态局部變量是在編譯時賦初值的,且隻指派一次。在程式運作時它已有初值,以後每次調用函數時不再重新賦初值而隻是保留上次函數調用結束時的值。而對自動變量賦初值,不是在編譯時進行的,而是在函數調用時進行,每調用一次函數重新給一次初值,相當于執行一次指派語句。

4、如果在定義局部變量時不賦初值的話,則對靜态局部變量來說,編譯時自動賦初值0或空字元。而對自動變量來說,如果不賦初值則它的值是一個不确定的值。這是由于每次函數調用結束後存儲單元已釋放,下次調用時又重新配置設定存儲單元,而所配置設定單元的值是不确定。

5、雖然靜态局部變量在函數調用結束後仍然存在,但其他函數不能引用它。

繼續閱讀