程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言變量存儲類型介紹

C語言變量存儲類型介紹

編輯:關於C語言

C語言中對變量的說明包括兩方面的內容:變量類型以及變量的存儲類型。變量類型如:int(整形),char(字符型)是用來說明變量所占用的內存空間的大小。變量存儲類型用來說明變量的作用范圍。

C語言的變量存儲類型有:自動類、寄存器類、靜態類和外部類。

局部變量是指在函數內部說明的變量(有時也稱為自動變量),用關鍵字auto進行說明。 所有的非全程變量都被認為是局部變量,所以auto實際上從來不用。局部變量在函數調用時自動產生,但不會自動初始化, 隨函數調用的結束,這個變量也就自動消失了,下次調用此函數時再自動產生,還要重新賦值,退出時又自動消失。

靜態變量用關鍵字static聲明。根據變量的類型可以分為靜態局部變量和靜態全程變量。

  1. 靜態局部變量
  2. 它與局部變量的區別在於:在函數退出時,這個變量始終存在,但不能被其它函數使用,當再次進入該函數時,將保存上次的結果。其它與局部變量一樣。

  3. 靜態全程變量
  4. 靜態全程變量就是指只在定義它的源文件中可見而在其它源文件中不可見的變量。它與全程變量的區別是:全程變量可以再說明為外部變量(extern),被其它源文件使用,而靜態全程變量卻不能再被說明為外部的,即只能被所在的源文件使用。

    • 外部變量用關鍵字extern聲明。為了使變量除了在定義它的源文件中可以使用外,還可以被其它文件使用,就要將全程變量通知每一個程序模塊文件,此時可用 extern來說明。
    • 寄存器變量通常在比較注重在執行速度的情況下使用。其思想是告訴編譯程序把該變量放在某個CPU寄存器中。因為數據在寄存器中操作比在內存中快,這樣就提高了程序代碼的執行速度。寄存器變量的說明是在變量名及類型之前加上關鍵字register。值得注意的是取地址運算符&不能作用於寄存器變量。

下面結合具體代碼來分析一下變量的種類。

在file1.c的開頭聲明i是全程變量,並初始化為1。而在main函數內部,說明了兩個自動變量i和j,這樣在main內部出現的i就是自動變量。

file1.c

#include <stdlib.h> 
#include <stdio.h> 
int reset(); 
int next(); 
int last(); 
int sum(int ); 
int i=1; 
void main() 
{ 
    auto int i,j; 
    i=reset(); 
    for(j=1;j<=3;j++) 
    { 
        printf("i=%dtj=%dn",i,j); 
        printf("next(i)=%dn",next()); 
        printf("last(i)=%dn",last()); 
        printf("sum(i+j)=%dn",sum(i+j)); 
    } 
} 

file2.c文件一開始就定義了變量i,並聲明為靜態變量,因此它的使用范圍只在當前文件中使用。然而從函數sum中定義來看,其內部用到的i是形式參數,j是內部靜態變量,它們與以前的i, j都不同。

file2.c文件

static int i=10; 
int next() 
{ 
    return(i+=1); 
} 
int last() 
{ 
    return(i-=1); 
} 
int sum(int i) 
{ 
    static int j=5; 
    return(i=j+=i); 
} 

在file3.c的開頭說明i是外部的,表明它與file1.c定義的i是同一個變量,所以reset的值返回的就是這個i的當前值1。

file3.c文件

extern int i; 
reset() 
{ 
    return(i); 
} 

具體執行過程分析如下:

  1. 首先程序經過編譯後生成可執行文件,運行可執行文件後,函數從Main函數體進入,在初始化的過程中得到i為全局變量,初值為1。
  2. 進入main函數後首先調用函數reset(),進入文件file3.c,文件file3.c聲明i為外部變量,所以此時i的值為1,則返回的值為1。函數reset()執行完後返回主函數,繼續執行循環體中的程序。
  3. 循環體首先調用函數next(),程序進入file2.c文件,判斷i為靜態變量,所以此時i的值為10,執行next()之後i的值為11,返回值為11,並將11作為i的值。當調用last()函數時,判斷i的值為11,執行函數後,i的值變為10,並將10作為i的值。最後執行函數sum(i),此時值的注意的是執行程序時傳遞的是形參,即第一次調用時實際計算的值為sum(i+j=2),這樣調用函數sum(i)後執行的結果為i=5+2=7,即為執行的結果。
  4. 依次類推,分別為7,10,14。 通過以上的程序可以理解不同的存儲類型的作用范圍不同,在程序設計中如何靈活的使用各種不同的存儲類型是能夠使程序更靈活。

附:運行結果

i=1 j=1 
next(i)=11 
last(i)=10 
sum(i+j)=7 
i=1 j=2 
next(i)=11 
last(i)=10 
sum(i+j)=10 
i=1 j=3 
next(i)=11 
last(i)=10 
sum(i+j)=14

解析static關鍵字

static在c裡面可以用來修飾變量,也可以用來修飾函數。

先看用來修飾變量的時候。變量在c裡面可分為存在全局數據區、棧和堆裡。其實我們平時所說的堆棧是棧而不包含對,不要弄混。

int a;
main()
{
	int b ; 
	int c* = (int *)malloc(sizeof(int));
}

a是全局變量,b是棧變量,c是堆變量。

static對全局變量的修飾,可以認為是限制了只能是本文件引用此變量。有的程序是由好多.c文件構成。彼此可以互相引用變量,但加入static修飾之後,只能被本文件中函數引用此變量。

static對棧變量的修飾,可以認為棧變量的生命周期延長到程序執行結束時。一般來說,棧變量的生命周期由OS管理,在退棧的過程中,棧變量的生命也就 結束了。但加入static修飾之後,變量已經不在存儲在棧中,而是和全局變量一起存儲。同時,離開定義它的函數後不能使用,但如再次調用定義它的函數 時,它又可繼續使用, 而且保存了前次被調用後留下的值。

static對函數的修飾與對全局變量的修飾相似,只能被本文件中的函數調用,而不能被同一程序其它文件中的函數調用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved