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

1. 變量分類

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

2. 內存分區

參考《Windows內存管理

全局變量,靜態變量都存儲在“靜態存儲區”;

函數的形式參數,自動變量(未加 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程序設計》第三版

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章