C語言_瞭解一下C語言中的四種儲存類別

OldBoy~發表於2018-01-02

C語言是一門通用計算機程式語言,應用廣泛。C語言的設計目標是提供一種能以簡易的方式編譯、處理低階儲存器、產生少量的機器碼以及不需要任何執行環境支援便能執行的程式語言。

C語言中的四種儲存類別:auto(自動的)、static(靜態的)、register(暫存器的)、extern(外部的)

1、auto(自動的)
例:auto int a;定義的整形變數a的儲存方式是自動儲存的,也就是說動態的分配儲存空間和釋放儲存空間。比如說,在一個呼叫函式裡定義的變數,當我們呼叫這個函式時,CPU在動態儲存區分配一個儲存空間,這個儲存空間用來放變數a的值,當呼叫函式執行完之後,CPU會釋放這個儲存空間(也可以這樣理解,之前定義a時,CPU把一個儲存空間給了a,a對這個儲存空間有了使用權,其他的人無法去佔用這個儲存空間,當CPU釋放這個儲存空間時,也就意味著這個儲存空間是無主的,其他的人可以佔用它)。還有需要注意的是,當我們再次呼叫這個函式時,CPU分配的儲存空間的地址並不一定是之前的地址,也就有了這樣的一種情況,當我們定義一個變數時,不給它初始值,它的值是不確定的。
我們之前編寫程式的時候很少用到auto定義變數,其實我們之前定義的變數前面沒有加static,編譯系統會預設為是auto的儲存方式,都會把變數存放在動態儲存區。

例如:

int f(int a) /*定義 f 函式,a 為引數*/
{auto int b,c=3; /*定義 b,c 自動變數*/
……
}

a 是形參,b,c 是自動變數,對 c 賦初值 3。執行完 f 函式後,自動釋放 a,b,c 所佔的儲存單元。

關鍵字 auto 可以省略,auto 不寫則隱含定為“自動儲存類別”,屬於動態儲存方式。

2、static(靜態的)
例:static int a;定義的整形變數a的儲存方式是靜態儲存的,靜態區域性變數是放在靜態儲存區內分配儲存單元的,在整個程式執行期間都不釋放,跟全域性變數一樣長期佔用記憶體。但是靜態變數和全域性變數還是不一樣的,比如說,靜態變數只能在所定義的函式內引用,靜態區域性變數在函式呼叫結束後是仍然存在的,但不能被其他函式引用。
靜態區域性變數是在編譯時賦初值的,即只賦初值一次,在程式執行時它已經有了初值,以後每次呼叫函式時不再對其重新複製,而只是保留上次函式呼叫結束時的值。在定義靜態區域性變數時,如不賦初值,則編譯時自動賦初值為0。
有時在程式設計中定義一個全域性變數,只限於被所在原始檔引用,而不想讓其他檔案引用,則可在定義全域性變數前面加static。
3、register(暫存器的)
對於一些頻繁使用的變數,程式在執行的過程中,每次用到這些變數的時候,都要從記憶體取出來,運算完了之後還要寫到記憶體中去,迴圈執行的次數越多,花費的時間就越多,為提高效率,C++允許將區域性變數放在CPU的暫存器上,需要用到時直接從暫存器上取出參加運算,就不用再到記憶體中取;
例:register int i,sum=0;

for(i=0;i<10000;i++)
sum+=i;

i和sum都是頻繁使用的變數,所以將他們定義為暫存器變數。

當今的優化編譯系統能夠識別使用頻繁的變數,從而自動將這些變數放在暫存器中,而不需要設定為register。因此,用register宣告變數是不必要的。
4、extern(外部的)
要理解extern的作用,前提要對全域性變數有所瞭解。
全域性變數的作用域只限於從定義那一行開始,到檔案最後一行,終究只限於所在原始檔中。如若想在其他原始檔引用其他原始檔的全域性變數,則要在其他原始檔宣告該變數是extern的(來自外部的,其他原始檔的),這樣擴大了全域性變數的作用域。
例:char flag=1;

extern char falg;

賦初值是在定義時進行,外部變數宣告不能賦初值,不能更改。

以上內容摘自[百度百科]

下面來個實際例子來測試下普通變數和靜態變數

fileOne.h標頭檔案如下:

#ifndef DMTestVariable_fileOne_h
#define DMTestVariable_fileOne_h
 
// 宣告全域性變數
extern int globalVariable;
 
void addOne();
void testStaticGlobal();
 
#endif

fileOne.c檔案如下

#include <stdio.h>
#include "fileOne.h"
 
// 靜態全域性變數
static int staticGlobalVariable = 12;
 
void addOne()
{
    // 全域性變數加1
    globalVariable += 1;
}
 
void testStaticGlobal()
{
    // 靜態全域性變數加1
    staticGlobalVariable += 1;
    printf("靜態全域性變數:%d\n",staticGlobalVariable);
}

main.c檔案如下:

#include <stdio.h>
#include "fileOne.h" // 定義性宣告全域性變數 int globalVariable = 10; void test() { // 靜態區域性變數 static int staticLocalVariable = 20; staticLocalVariable += 1; printf("靜態區域性變數值:%d\n",staticLocalVariable); } int main(int argc, const char * argv[]) { int i; // 區域性變數測試 int localVariable = 15; printf("區域性變數%d\n",localVariable); // 全域性變數測試 addOne(); printf("全域性變數:%d\n",globalVariable); // 靜態區域性變數的測試 for (i = 0 ; i < 2; i++) { test(); } // 靜態全域性變數 for (i = 0 ; i < 2; i++) { testStaticGlobal(); } return 0; }

結果如下:

總結如下:
全域性變數,具有全域性作用域,只需在一個原始檔中定義,就可以作用於所有的原始檔,當然其他不包含全域性變數定義的原始檔需要用extern關鍵字再次宣告這個全域性變數,如程式碼中的

// 定義性宣告全域性變數
int globalVariable = 10;

全域性變數,定義在main.c原始檔中,在fileOne.c原始檔中使用時有以下程式碼再次宣告

// 宣告全域性變數
extern int globalVariable;

靜態全域性變數,只能在其所在檔案模組中的函式中使用,其他檔案模組中的函式不能訪問。如程式碼中的

// 靜態全域性變數
static int staticGlobalVariable = 12;

只能在fileOne.c原始檔中使用,不能在main.c原始檔中使用。
區域性變數:只能在定義該變數的函式體內使用。如程式碼中的

// 區域性變數測試
int localVariable = 15;

只能在main函式中使用。

靜態區域性變數:在函式內定義,但當函式退出後,靜態區域性變數始終存在,其佔用的記憶體單元不會被釋放,直到程式結束時才被釋放。退出函式後儘管該靜態區域性變數還存在,但是不能使用它,如果再次呼叫定義該靜態區域性變數的函式,它又可以繼續使用,而且儲存了上次呼叫之後留下的值。如程式碼中的

// 靜態區域性變數
static int staticLocalVariable = 20;

第一次呼叫test()函式輸出的此靜態區域性變數值為21,第二次呼叫函式test()輸出的此靜態區域性變數值為22。

相關文章