常數、列舉數定義後直接是常數值,函數屬於功能模組,我們已經陸續討論過不少函數的參數及回傳值,現在,我們把焦點集中在通常定易於函數中的識別字,也就是變數。
每一個變數都有型態、名稱及所儲存的數值,除了這些,變數還有儲存類型、佔用期間、範圍、連結等特性,如下
特性 | 說明 |
---|---|
儲存類型 | 分為自動型及靜態型,自動型的變數在離開所屬範圍後,資料就會被銷毀,靜態型則會保留原值 |
佔用期間 | 變數可被使用的有效期限,有些只存在一下子,有些反覆的被建立、刪除,有些能保存到程式執行結束 |
範圍 | 變數能夠被使用的區域 |
連結 | 分成內部連結及外部連結,內部連結是指變數在單一原始檔的使用情況,外部連結則是多個原始檔的使用情況 |
C 語言有四個儲存類型指定詞,四個都屬於關鍵字,分別是 auto 、 register 、 static 及 extern ,利用這些儲存類型指定詞可以指定變數的儲存類型,同時連帶指定變數的佔用期間、範圍、連結等特性。
但是我們從來沒有用過任一個儲存類型指定詞,不是嗎?是的,因為 C 語言預設沒有添加任何儲存類型指定詞的宣告,全都屬於 auto ,所以,當宣告一個迴圈變數 i ,如下
int i;
等同於
auto int i;
auto 與 register 的儲存類型屬於自動型,而 static 及 extern 屬於靜態型。所謂自動型變數是指佔用期間與範圍都只在某一特定的程式區塊內,離開所屬的程式區塊,便無法再使用相關的自動型變數。
一般來說變數宣告時,沒有添加任何儲存類型指定詞都屬於 auto ,這個我們已經看過很多例子。若是將變數宣告為 register ,這是建議編譯器把變數放到電腦 CPU 的暫存器中,因為有可能經常運用 register 類型的變數,放到暫存器可以加快程式的執行。
然而許多編譯器本身會作最佳化的動作,因此就算沒有特別把經常使用的變數宣告為 register ,編譯器自己也會直接把這些變數設定為 register ,也就是執行時直接放到暫存器裡。
所謂的靜態型變數就是程式執行期間都會保有其值,例如以下程式將函數 test1() 中的變數 a 宣告為 static
#include <stdio.h> void test1(void); void test2(void); int main(void) { test1(); test2(); test1(); test2(); test1(); test2(); test1(); test2(); test1(); test2(); test1(); test2(); test1(); test2(); test1(); test2(); return 0; } void test1(void) { static int a = 0; printf("在 test1() , a = %d\n", a++); } void test2(void) { int a = 0; printf("在 test2() , a = %d\n", a++); } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:statictest.c 功能:示範靜態變數的使用 作者:張凱慶 時間:西元2010年7月 */
編譯後執行,如下
宣告為 static 的變數 a 會一直保有原值,因此每一次呼叫函數 test1() , a 都會遞增,而在函數 test2() 的自動型變數 a ,隨著每一次呼叫 test2() 都會重新被建立賦予初值。
static 是用為內部連結,我們在往後的部份才會介紹用為外部連結的 extern 。
問題與討論
- 說明變數具備的各項特性。
- 靜態型變數跟自動型變數有何不同?
沒有留言:
張貼留言