-
靜態變量
鎖定
- 中文名
- 靜態變量
- 外文名
- static variables
- 分 類
- 變量
- 儲存方式
- 靜態
- 學 科
- 計算機
- 領 域
- 計算機編程
靜態變量概念
“靜態變量”這一術語有兩個容易混淆的定義:
- 語言無關的通用定義:與程序有着相同生命週期的變量;
- C族語言特有的定義:以static存儲類聲明的變量。
而在以Pascal為代表的許多程序語言中,所有局部變量都由系統自動分配存儲空間,而所有全局變量的存儲空間則以靜態分配的方式獲取(對應“靜態變量”),因此由於實際上“局部變量”和“全局變量”這兩個術語已足以涵蓋所有的情況,在這些程序語言中通常不使用“靜態變量”這一術語,而直接以“全局變量”代之。一般來説,在這些程序語言中,靜態變量就是全局變量,而即使在有明確區分全局和靜態變量的程序語言中,在編譯後的代碼裏二者也以相同的方式獲取存儲空間。而今術語“靜態變量”的概念則主要基於C族語言的“static”的定義(即定義2)。
靜態變量常量使用
靜態變量也可以用於存儲常數。具體來説,靜態變量(全局變量及彙編語言裏定義的符號亦同)可用const,constant或final(根據語言決定)等關鍵字標識,這時其值就會在編譯時設定,並且無法在運行時改變。編譯器通常將靜態常量與文本一起置於目標文件的文本區域,而非常量初始化數據則置於數據區;而如若有需要,有些編譯器還可選擇為其開闢專用區;為防止常數變量被錯誤的指針寫入覆蓋,亦可在這塊區域啓用內存保護機制。
靜態變量C語言
在C語言及由其派生出的C++與Objective-C等程序語言中,“static”是用於控制變量的生命週期和連接方式(即其作用域,亦即可見性)的保留字。確切來説,正如C族語言中的extern,auto與register這些保留字一樣,static也是一種存儲類(此處的“類”與面嚮對象語言的“類”的定義不同)標識。每個變量與函數都有以上的一種存儲類標識,如果在聲明中沒有明確標識其存儲類,編譯時就會根據上下文來選擇其默認存儲類,如在源文件裏的所有文件級變量對應的默認存儲類是extern,而在函數體內的變量對應的則是auto,各存儲類的屬性如下表所列。
[1]
存儲類名 | 生命週期 | 作用域 |
---|---|---|
extern | 靜態(程序結束後釋放) | 外部(整個程序) |
static | 靜態(程序結束後釋放) | 內部(僅翻譯單元,一般指單個源文件) |
auto,register | 函數調用(調用結束後釋放) | 無 |
易見存儲類為extern的變量(包括上面提到的未明確聲明存儲類的文件級變量)匹配前段所述靜態變量的定義1,但不匹配定義2。
靜態變量作用
除明確標識出變量的生命週期外,將變量聲明為static存儲類還會根據變量屬性不同而有一些特殊的作用:
靜態變量C示例
#include <stdio.h>void func() { static int x = 0; // 在對func的三次調用中,x只進行一次初始化 printf("%d\n", x); // 輸出x的值 x = x + 1;}int main(int argc, char * const argv[]) { func(); // 輸出0 func(); // 輸出1 func(); // 輸出2 return 0;}
靜態變量C++示例
在C++中,帶有含私有靜態內部變量的類的程序如下所示:
class Request { private: static int count; // 不能為外部調用 string url; // 只能被成員函數調用 public: Request() { count++; } string getUrl() const { return url; } void setUrl(string value) { url = value; } static int getCount() { return count; } }; int Request::count = 0; // count 可以在類聲明外進行初始化