在說到static之前,需要先明確變量類型:
而在聊到變量類型之前我們可以將變量的兩個屬性好好學一學
變量的兩個屬性
作用域(scope):
從內存的角度來看,就是變量存放在棧(stack)中,還是 數據段中(Data Segment),那么stack和Data segment又有什么區別呢?
鏈接性(linkage)
分為外部鏈接性(external linkage)和內部鏈接性(internal linkage),從函數的角度來看,就是函數能訪問到的變量范圍。
存儲區
棧(stack
存儲臨時數據,例如內部變量(局部變量)和返回地址;
在下述的四種變量類型中,有且只有內部變量是存儲在棧中。
數據段(Data Segment
數據段是全局變量和靜態變量存放的主要區域,還可能包括程序的只讀數據(如字符串常量)。數據段是程序的只讀部分,用于存儲程序的全局變量和靜態變量。
在程序的整個執行期間,數據段保持不變。
變量類型:
外部變量(External Variable):
也稱為全局變量(Global Variable)。
它們在程序的整個運行期間都是可見的,并且可以在程序的任何部分被訪問。
外部變量具有外部鏈接性,這意味著它們可以在多個編譯單元(如多個源文件)中共享。
內部變量(Internal Variable):
又稱局部變量,它們只在定義它們的塊(例如函數或代碼塊)內部可見。
內部變量具有內部鏈接性,這意味著它們不能在定義它們的塊之外訪問。
靜態外部變量(Static External Variable):
當你在函數或代碼塊之外聲明一個變量,并使用static關鍵字時,它就變成了靜態外部變量。
靜態外部變量具有靜態存儲期,即它們在程序的整個生命周期內都存在,但它們只在定義它們的編譯單元中可見。
即使具有外部鏈接性,使用static關鍵字也會限制其可見性到定義它們的文件內。
靜態內部變量(Static Internal Variable):
這是在函數內部聲明的靜態變量。
與自動存儲期的局部變量不同,靜態內部變量在函數調用結束后不會消失,它們的值在下一次函數調用時仍然保持。
靜態內部變量只在定義它們的函數內可見。
分析static
可以看到有了static這個關鍵字(key word),外部變量就會被限制鏈接性,內部變量就會更改它的作用域,從而擴大了它的生命周期(LifeTime),而且在一個文件編譯(匯編)的時候,只會賦一次初值,這個待會會看到。
1.8示例
示例代碼
#include <stdio.h>int fun() {static int a = 0; return (++a);
}int main(void) {printf("a = %d\n", fun());printf("a = %d\n", fun());return 0;
}
問1:該示例代碼輸出是什么?
答1:
問2:如果fun()中的static int a = 0;去掉static,輸出又是什么呢?
答2:
問3:為什么static修飾的變量在返回值時會出現不同的情況?
我們先來看一下他們的各自的匯編的不同之處吧:、
有static的示例
無static的示例