C語言中的作用域,鏈接屬性和存儲類型
作用域
當變量在程序的某個部分被聲明的時候,他只有在程序的一定漁區才能被訪問,編譯器可以確認4種不同類型的作用域:文件作用域,函數作用域,代碼塊作用域和原型作用域
1.代碼塊作用域:位於一對花括號之間的所有語句稱為一個代碼塊.任何在代碼塊的開始位置聲明的標識符都具有代碼塊作用域,表示他可以被這個代碼塊中的所有語句訪問.(例子中:f,g函數,i)
2.文件作用域:任何在所有代碼塊之外聲明的標識符都具有文件作用域,他表示這些標識符從他們的聲明之處直到他所在的源文件結尾處都是可以訪問的.(例子中:a,b)
3.原型作用域:原型作用域只適用於在函數原型中聲明的參數名.(例子中:c,h)
4.函數作用域
例子:
int a;
int b(int c);
int d (int e){
int f:
int g(int h);
...
{
int f,g,i;
}
{
int i;
}
}
鏈接屬性
當組成一個程序的各個源文件分別被編譯之後,所有的目標文件以及那些從一個或者多個函數庫中引用的函數鏈接在一起,形成可執行程序,如果相同的標識符出現在幾個不同的源文件中.標識符的鏈接屬性決定如何處理這些標識符.
鏈接屬性一共有三種:external(外部),internal(內部)和none(無)
1.none:沒有鏈接屬性的標識符(none)總是被當做單獨的個體.
2.internal:標識符在同一個源文件內的所有聲明都指同一個實體,但位於不同源文件的多個聲明則分屬於不同實體
3.external:標識符不論聲明多少次,位於幾個源文件都表示同一個實體.
例子:
typedef char *a;
int b;
int c(int d){
int e;
int f(int g);
}
默認情況下:b,c,f的鏈接屬性為external,其余標識符為none.
關鍵字extern和static用於在聲明中修改標識符的鏈接屬性.如果在默認是external屬性前加上static,可以使他的屬性變為internal.
比如上述 static int b;和static int c(int d)就變成這個源文件私有,不能被其他文件訪問.
static只對默認屬性為external的聲明才有效果,對默認是none的效果完全不一樣.
extern可以吧none屬性的標識符變為external屬性.
比如上述extern int e修改之後可以使用其他源文件的e標識符
存儲類型
在程序中,變量存儲類型決定他何時創建,何時銷毀,以及他的值保持多久.有三個地方可以用於存儲變量:普通內存,運行時堆棧,硬件寄存器.
普通內存:凡是在任何代碼塊之外聲明的變量總是存儲於靜態內存中.這類變量稱為靜態變量,這類變量在程序啟動時創建,終止時銷毀.
運行時堆棧:在代碼塊內部聲明的變量的默認存儲類型是自動的,稱為自動變量.如果在代碼塊內部聲明的變量前面加上static,這個變量的存儲類型就改變為靜態,程序運行中一直存在
硬件寄存器:使用關鍵字register聲明的變量表示寄存器變量,保存在硬件的寄存器中.他只能對自動變量聲明
C語言中的作用域,鏈接屬性和存儲類型