1. 程式人生 > >c/c++ 中變數的儲存類別

c/c++ 中變數的儲存類別

1. 變數分類

  1. 從變數的作用域
    • 全域性變數
      在函式外部定義的變數被稱作外部變數或全域性變數。
    • 區域性變數
      在函式內部定義的變數,只在本函式內部有效。
  2. 從變數的儲存時間(生存週期)
    • 靜態儲存方式
      程式執行期間固定分配的儲存空間。
    • 動態儲存方式
      程式執行期間動態分配的儲存空間。

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 的全域性與區域性

全域性變數:

  1. 普通全域性變數:作用域是整個源程式,在同一原始檔的不同檔案中可見
  2. static 全域性變數:作用域是所在的原始檔,只能被定義該變數的檔案中可見

區域性變數:

  1. 普通區域性變數:執行時賦值,每呼叫一次賦一次值,呼叫結束自動釋放。
  2. static 區域性變數:程式編譯時賦值,只初始化一次,函式呼叫結束其值依然存在,不釋放。

函式:

  1. 普通函式:可以被同一源程式中的其他函式呼叫。
  2. static 靜態函式:只在定義該函式的檔案中可見,不能被源程式中的其他檔案使用。

9. 參考

《c程式設計》第三版