變量從存在的時間(生存期)角度來分,可以分為動態儲存方式和靜態儲存方式。
所謂靜態存儲方式是指在程序運行開始時由系統分配固定的儲存空間的方式。
動態儲存方式則是在程序運行期間根據需要進行動態的分配儲存空間的方式。
存儲空間分為3部分:(1)程序區(2)靜態存儲區(3)動態存儲區。
在C語言中,每一個變量和函數都有兩個屬性:數據類型和數據的存儲類別。
對數據型(如整型,字符型等):儲存類別指的是數據在內存中的儲存方式。具體包含四種:自動的(auto),靜態的(static),寄存器的(register),外部的(extern)。根據變量的儲存類別,可以知道變量的作用域和生存期。
1、auto變量
函數中的局部變量,如不專門聲明為static儲存類別,都是動態的分配存儲空間(棧),數據存儲在動態存儲區中。
函數中的形參和在函數中定義的變量(包括在復合語句中定義的變量),都屬此類,在調用該函數時,系統會給它們分配存儲空間,在函數調用結束時,自動釋放這些存儲空間。
例:int f(int a) /*定義為f函數,a為形參*/
{
auto int b,c=3; /*定義b,c為自動變量*/
}
關鍵字auto可以省略,auto不寫則默認為“自動存儲類別”。
2、用stastic聲明局部變量
有時希望函數中的局部變量的值在函數調用結束后不消失,即存儲單元不釋放。
這時就應指定局部變量為“靜態局部變量”,用static進行聲明。
例:
#include <stdafx.h> #include<stdio.h> int f(int a) { auto b=0; static int c=3; b=b+1; c=c+1; return(a+b+c); } void main() { int a=2,i; for(i=0;i<3;i++) { printf("%d\n",f(a)); } }
說明:(1)靜態局部變量屬於靜態存儲類別,在靜態存儲區內分配存儲單元。在函數整個運行期間都不釋放,而自動變量屬於動態存儲類別,占動態存儲空間而不占靜態存儲空間,函數調用結束后釋放。
(2)對靜態局部變量是在編譯時賦初值的,即只賦初值一次,在程序運行時已有初值。
(3)若在定義局部變量時不賦初值的話,則對靜態局部變量來說,編譯時自動賦初值0(對數值型變量)或空字符(對字符型變量),對自動變量來說,不賦初值則它的值是一個不確定的值。
(4)雖然靜態局部變量在函數調用結束后仍然存在,但其他函數是不能引用它的。
例:輸出從1到5的階乘值。
#include <stdafx.h> #include<stdio.h> int fac(int a) { static int f=1; f=f*a; return(f); } void main() { int i ; for(i=1;i<=5;i++) { printf("%d!=%d\n",i,fac(i)); } }
3、register變量
一般情況下,變量存放在內存中。
但若一些變量使用過於頻繁則會浪費很多時間(cpu處理數據與內存讀取數據有時間差)。
為提高程序執行效率,C語言允許將局部變量的值放在CPU寄存器中,需要時直接取出參加運算,不必再到內存中去存取。
這種變量稱為寄存器變量,用關鍵字register作聲明。
例:輸出1到n階乘的值。
#include <stdafx.h> #include<stdio.h> int fac(int n) { static int i ,f=1; for(i=1;i<=n;i++) { f*=i; } return(f); } void main() { int i,n; scanf("%d",&n); for(i=1;i<=n;i++) { printf("%d!=%d\n",i,fac(i)); } }
4、用extern聲明外部變量
有時要用extern來聲明外部變量,以擴展外部變量的作用域。
例:
#include <stdafx.h> #include<stdio.h> int max(int x,int y) { int z; z=x>y?x:y; return(z); } void main() { extern int A,B; printf("%d\n",max(A,B)); } int A=13,B=8;
其實extern的作用就是告訴編譯器讀到AB時知道其為全局變量,其值可能在程序的任意一個地方。