c/c++ 中變數的儲存類別
1. 變數分類
- 從變數的作用域
- 全域性變數
在函式外部定義的變數被稱作外部變數或全域性變數。 - 區域性變數
在函式內部定義的變數,只在本函式內部有效。
- 全域性變數
- 從變數的儲存時間(生存週期)
- 靜態儲存方式
程式執行期間固定分配的儲存空間。 - 動態儲存方式
程式執行期間動態分配的儲存空間。
- 靜態儲存方式
2. 記憶體分割槽
全域性變數,靜態變數都儲存在“靜態儲存區”;
函式的形式引數,自動變數(未加 static 宣告的區域性變數),函式呼叫時的現場保護和返回地址,這些都儲存在“動態儲存區”。
在 c 語言中,每一個變數和函式都有兩個屬性:資料型別和資料的儲存類別。
資料型別:字元型,整型,浮點型等
儲存類別:靜態儲存和動態儲存。
對變數的宣告有四種基本的型別: auto 變數,static 變數,register 變數,extern 變數。
3. auto 變數
函式中的區域性變數,如果不專門宣告為 static
儲存類別,那麼都是動態分配儲存空間。
關鍵字 auto
可以省略,如果不寫,都隱含確定為“動態儲存類別”。
int fx(int a)
{
auto int b, c = 3; // 等價於 int b, c = 3;
...
}
執行完 fx 函式後,a,b,c 所在的儲存單元自動釋放。
4. static 宣告區域性變數
用static 申請的區域性變數在函式抵用結束時不消失,而是保留原值,下一次呼叫時,該變數值依然保持。
#include <iostream>
void FileOneFxOne()
{
int iA = 0;
static int iStatic = 1;
iA++;
iStatic++;
std::cout << "區域性變數 iA = " << iA << std::endl;
std::cout << "區域性靜態變數 iStatic = " << iStatic << std::endl;
}
int main()
{
std::cout << "第一次呼叫:" << std::endl;
FileOneFxOne();
std::cout << "\n第二次呼叫:" << std::endl;
FileOneFxOne();
return 0;
}
第幾次呼叫 | 起始 | 結束 |
---|---|---|
第一次呼叫 | iA = 0; iStatic = 1 | iA = 1; iStatic = 2 |
第二次呼叫 | iA = 0; iStatic = 2 | iA = 1; iStatic = 3 |
第三次呼叫 | iA = 0; iStatic = 3 | iA = 1; iStatic = 4 |
5. register 變數
一般情況,變數都存在記憶體中,c 語言允許將區域性變數的值放在 CPU 的暫存器中,暫存器的存取速度遠遠大於記憶體的存取速度。
void fx()
{
register int i;
...
}
只有區域性自動變數和形參可以作為暫存器變數,區域性靜態變數不能作為暫存器變數。
當今的優化編譯器可以自動識別使用頻繁的變數,從而自動將這些變數放在暫存器中。
6. 用 extern 宣告外部變數
用 extern
來宣告外部變數,是為了擴充套件外部變數的作用域。
int main()
{
extern A;
A++;
...
}
int A = 0;
int fx()
{
...
}
由於 全域性變數 A 定義在 mian 函式之後,所以如果不使用 extern 關鍵字,編譯器將報錯。
extern 也可以將全域性變數的範圍擴充套件到同一源程式的不同檔案之中,如下所示:
- file1.cpp
#include <iostream>
#include "FileTwo.h"
int iGlobal = 3;
int main()
{
std::cout << "main : iGobal = " << iGlobal << std::endl;
FileTwo();
std::cout << "main : iGobal = " << iGlobal << std::endl;
FileTwo();
return 0;
}
- file2.cpp
#include "FileTwo.h"
#include <iostream>
extern int iGlobal;
void FileTwo()
{
iGlobal++;
std::cout << "FileTwo : iGlobal = " << iGlobal << std::endl;
}
- file2.cpp 標頭檔案
#ifndef FILETWO_H
#define FILETWO_H
void FileTwo();
#endif
輸出結果
main : iGobal = 3
FileTwo : iGlobal = 4
main : iGobal = 4
FileTwo : iGlobal = 5
在一個檔案中定義的外部變數,在另一個檔案中通過 extern 來宣告。
7. 內部函式和外部函式
內部函式:只能被文字中其他函式呼叫。如:
static int fx();
static
使其區域性化,不能被其他檔案引用。
外部函式:在函式的最左端加上關鍵字 extern
,則表示可以被其他函式呼叫,如:
extern int fx();
c語言中規定,如果在定義函式時省略 extern
,則隱含為外部函式,在需要呼叫此函式的檔案中,用extern
對函式做宣告。
8. static 的全域性與區域性
全域性變數:
- 普通全域性變數:作用域是整個源程式,在同一原始檔的不同檔案中可見
- static 全域性變數:作用域是所在的原始檔,只能被定義該變數的檔案中可見
區域性變數:
- 普通區域性變數:
執行時賦值
,每呼叫一次賦一次值,呼叫結束自動釋放。 - static 區域性變數:
程式編譯時賦值
,只初始化一次,函式呼叫結束其值依然存在,不釋放。
函式:
- 普通函式:可以被同一源程式中的其他函式呼叫。
- static 靜態函式:只在定義該函式的檔案中可見,不能被源程式中的其他檔案使用。
9. 參考
《c程式設計》第三版