本節(jié)我們系統(tǒng)學(xué)習(xí)一下c語言中的變量類型及作用域银伟。
1你虹、全局變量
全局變量是在從定義開始,到整個程序結(jié)束都存在的變量彤避,他是在所有函數(shù)體的外面定義的變量傅物,存儲在靜態(tài)存儲區(qū),所有的代碼都可以訪問琉预,定義如下:
#include <stdio.h>
int a; // 定義全局變量
int main() {
a = 10; // 函數(shù)內(nèi)可以訪問
return 0;
}
需要注意的是董饰,如果在另一個文件內(nèi)需要訪問這個全局變量,或者在這個變量定義之前需要用到他圆米,需要用extern關(guān)鍵詞來做聲明:
#include <stdio.h>
extern int a; // 聲明另一個文件中存在的全局變量
void test() {
a = 12;
}
2卒暂、局部變量
局部變量是定義在{}內(nèi)的普通變量,用auto來修飾(一般可以省略)娄帖,所以又稱為自動變量也祠,局部變量只在{}內(nèi)定義后有效,{}結(jié)束后自動銷毀近速,存儲在椪┖伲空間(一級緩存)內(nèi),他的作用域只限于這個{}內(nèi)削葱,定義如下:
void test(){
auto int a; // 可以和全局變量重名奖亚,在此之后,訪問的a都是局部變量
int b; // 省略auto(一般用法)
register int c; // 告訴編譯器采用寄存器的方式存儲變量(速度快析砸,但是會不會做取決于編譯器)
// 注:寄存器變量只能做局部變量或者形參昔字,同時他無法取得地址
}
3、靜態(tài)變量
局部變量在函數(shù)內(nèi)使用后會被銷毀干厚,有的時候我們希望這個變量在整個程序周期內(nèi)不被銷毀李滴,靜態(tài)變量可以實現(xiàn)這個作用:
void test() {
static int sa=0; // 該語句只會執(zhí)行一次
printf("%d\n", sa);
sa++; // 靜態(tài)變量的內(nèi)容繼承自上一次調(diào)用(此處可以記錄函數(shù)調(diào)用的次數(shù))
}
void test2() {
static int sa=5; // 此處的sa和前面的sa不是一個變量
}
這里我們定義的sa是靜態(tài)變量螃宙,存儲在靜態(tài)存儲區(qū),他在整個程序周期是不能銷毀的所坯,但是不同于全局變量的是谆扎,這個變量只能在定義他的函數(shù)內(nèi)訪問。
4芹助、const修飾詞
const修飾詞修飾的變量(全局堂湖、局部、靜態(tài))状土,在其生命周期內(nèi)無法被修改无蜂。也因此,const常量在初始化的時候必須賦值蒙谓。編譯器會對const常量進(jìn)行優(yōu)化存儲斥季。
5、volatile修飾詞
在前面介紹的各種變量累驮,編譯器可能會根據(jù)電腦的不同進(jìn)行某種優(yōu)化酣倾,比如const類型的變量,因為他是不能改變的谤专,就可以放在讀取較快躁锡,訪問較慢的靜態(tài)存儲區(qū)(這個由編譯器決定是否這樣做,或者其他的做法)置侍,而volatile修飾詞則告訴編譯器映之,這個值是可能變化的,不要給我優(yōu)化蜡坊。說白了杠输,用volatile修飾的變量,每一次都直接訪問該變量地址來取得值算色。例如:
volatile int a; // 采用volatile修飾的變量是直接通過地址訪問的
int b = a;
int c = a;
由于a是直接地址訪問的抬伺,他可能會改變螟够,b和c的值可能不同灾梦,在這里,如果我們不加volatile修飾詞妓笙,編譯器發(fā)現(xiàn)a的值沒有被修改若河,則可能直接繞過變量a的地址,直接調(diào)用前一次得到的數(shù)值來操作寞宫。
volatile在編寫單片機(jī)或者嵌入式等硬件開發(fā)時萧福,使用較多。