c語言中的存儲類型有`auto`, `extern`, `register`,`static` 這四種,存儲類型說明了該變量要在進程的哪一個段中分配內存空間,可以為變量分配內存存儲空間的有數據區、BBS區、棧區、堆區。
自動存儲類型修飾符指定了一個局部變量為自動的,這意味著,**每次執行到定義該變量的語句塊時,都將會為該變量在內存中產生一個新的拷貝,並對其進行初始化**。實際上,如果不特別指明,局部變量的存儲類型就默認為自動的,因此,加不加`auto`都可以。
1 //函數默認的存儲類型也是auto。 2 int main() 3 { 4 //在這個例子中,m的聲明無論是否包含auto,執行的效果都是一樣的,即默認為auto, 5 auto int m = 99; 6 printf("%d\n", m); 7 return 0; 8 }
被聲明為靜態類型的變量,無論是全局的還是局部的,都存儲在數據區中,其生命周期為整個程序,如果是靜態局部變量,其作用域為一對{}內,如果是靜態全局變量,其作用域為當前文件。靜態變量如果沒有被初始化,則自動初始化為0。**靜態變量只能夠初始化一次,在隨後的運行過程中,都將保持程序上一次使用的值。**
1 //對比auto類型變量和static類型的變量在執行過程中的差別 2 #include <stdio.h> 3 int main() 4 { 5 int i; 6 for(i = 0; i < 3; i++) 7 { 8 auto int m = 20; 9 static int n = 20; 10 printf("m%d is %d, ",i,m); 11 printf("n%d is %d;",i,n); 12 printf("\n"); 13 m++; 14 n++; 15 } 16 return 0; 17 }
運行結果:
m0 is 20, n0 is 20; m1 is 20, n1 is 21; m2 is 20, n2 is 22;
通常,`extern`都是用於聲明在另一個轉換單元中定義的變量。即`extern`用來聲明在當前文件中引用在當前項目中的其它文件中定義的全局變量。如果全局變量未被初始化,那麼將被存在BBS區中,且在編譯時,自動將其值賦值為0,如果已經被初始化,那麼就被存在數據區中。全局變量,不管是否被初始化,其生命周期都是整個程序運行過程中,為了節省內存空間,在當前文件中使用extern來聲明其它文件中定義的全局變量時,就不會再為其分配內存空間。
聲明為寄存器存儲類型的變量,除了程序無法得到其地址外,其余都和自動變量一樣。聲明為register的變量在由內存調入到CPU寄存器後,則常駐在CPU的寄存器中,因此訪問register變量將在很大程度上提高效率,因為省去了變量由內存調入到寄存器過程中的好幾個指令周期。
各存儲類型比較
從這個表中可以看出,C程序的標識符作用域有三種:*局部、全局、文件*。標識符的作用域決定了程序中的哪些語句可以使用它,換句話說,就是標識符在程序其他部分的可見性。通常,標識符的作用域都是通過它在程序中的位置隱式說明的。