## 總結一下C++中變量的存儲類別以及變量的作用域。
(1)標示符的存儲類別決定了標示符在內存中存在的時間(我們可以理解標示符就是確定一個變量的符號,也就是我們所說的變量名)
## 二:存儲類別
(1)靜態存儲類別:靜態存數類別變量(我們簡稱靜態變量),從程序的開始處就存在,其生命期伴隨整個程序。
(2)自動存儲類別:當變量時自動存儲類別時,變量在進入到定義它們的程序快時定義它,在離開它們所在的程序塊(作用域)時銷毀它,因此成為自動變量。其中關鍵字auto和register用來聲明自動類型的變量,
## 三:自動存儲類型:
(1) 只有在函數中的局部變量才是自動存儲類型的,我們在MAIN函數中定義的變量一般都是自動變量,關鍵字auto可以不寫,默認情況局部變量就是自動變量(我們把自動存儲類別的變量叫自動變量)如下圖:
~~~
int a;
int b;?
~~~
都是自動變量
(2)自動變量還有一種寄存器變量,既使用關鍵字register,我們把經常被調用的變量聲明為寄存器變量,顧名思義,讓變量存在于寄存器中,達到更加快速的存儲,這個我們了解即可,現在很多編譯器帶有可以識別頻繁使用變量的功能,不需要程序員手動設置。
根據最小特權原則,我們應該定義自動變量。代碼應該只被賦予它僅能完成設計任務的權限,無需更多權限。
## 四:靜態存儲類別
(1)關鍵字extern和static用于靜態存儲類別的變量,靜態存數類別變量(我們簡稱靜態變量),從程序的開始處就存在,其生命期伴隨整個程序,一直存在程序的執行過程,但是:即便是靜態變量,也并不意味著這些變量(專業來說叫:標識符),在整個程序都是能用的(或者說是可以訪問的),這一點在下面有專門的實例。
(2)對于靜態變量,許多被誤認為和全局變量一致,這一點是錯誤的**,static變量僅僅在變量的作用范圍內可見,而全局變量是在所有地方都可見的,這就是static變量與全局變量的區別,**我們要糾正一點:存儲類別(存數類型)和變量的作用域是兩個獨立的問題。
我們應該遵循最小特權原則,不去使用全局變量。
(3)我們解釋一下,全局變量和靜態變量的區別:全局變量是不顯示用static修飾的全局變量,但全局變量默認是靜態的,作用域是整個工程,在一個文件內定義的全局變量,在另一個文件中,通過extern 全局變量名的聲明,就可以使用全局變量。
全局靜態變量是顯示用static修飾的全局變量,作用域是所在的文件,其他的文件即使用extern聲明也不能使用。
## 五:標識符(變量)的作用域
(1)程序中可以使用標識符的范圍成為標識符 的作用域,其中我們稱標識符為變量,更加專業。例如:我們在一個語句塊中聲明了一個局部的變量,那么只能在該語句塊中使用該變量。
(2)其中作用域大致分為四個:
全局作用域:此變量對于從其聲明處到文件結束,都是已知的。
局部作用域:一個語句塊中聲明的變量,其作用域在于該語句塊中。
函數原型作用域:就是函數的形參列表中。
這里著重標記一下局部作用域:當語句塊是嵌套的,并且外層語句塊中的一個標識符和內層語句塊中的標識符名字一致時,外層語句塊中的標識符被隱藏,直到內層語句塊結束。
## 六 注意:
(1)我們應該避免使用全局變量,使用全局變量可能在不需要訪問變量時卻錯誤的訪問變量,違反最小特權原則。僅用于特定函數中的變量應該聲明為那個函數的局部變量,而不是全局變量。
(2)應該避免使用會隱藏在外部作用域中名稱的變量名,這可以通過在程序中避免使用相同的標識符。
上述總結說明了變量的類型以及作用域,此時我們舉個程序,列舉上述出現的情況。如下:
~~~
#include<iostream>
using namespace std;
void use_Global(); //聲明函數
void use_Local();
void use_Static_Local();
int a=1; //在函數外定義一個全局的變量
int main()
{
cout<<"the value of global a in the main function is "<<a<<endl;
//<span style="color:#ff0000;">輸出全局變量的值,值為 1</span>
int a=10; //在MAIN函數中定義一個同名字的局部變量
cout<<"now ,in the main function , local a is "<<a<<endl;
//<span style="color:#ff0000;">輸出局部變量,此時全局變量被隱藏,此時的輸出的值為 10</span>
{ //在語句塊中定義局部變量
int a=7;
cout<<"int the scope ,local a is "<<a<<endl; //<span style="color:#ff0000;">輸出值為:7</span>
}
cout<<"local a in the main's outer scope is"<<a<<endl;
//<span style="color:#ff0000;">脫離語句塊,輸出變量,輸出值為:10</span>
use_Local(); //使用函數,函數中定義一個局部變量
use_Static_Local(); //使用函數,函數中定義一個靜態局部變量
use_Global(); //使用函數,函數中使用全局變量
use_Local();
use_Static_Local();
use_Global();
return 0;
}
void use_Global()
{
cout<<"\n global a is "<<a<<endl;//<span style="color:#ff0000;">此作用域中,沒有定義同名的標識符,所以輸出的全局變量,值為10</span>
cout<<"enter the use_Global function "<<endl;
a++;
cout<<"\n global a is "<<a<<" on the exit "<<endl;
}
void use_Local()
{
int a=20;
cout<<"enter the function use_Local, the a is "<<a<<endl;
a++;;
cout<<"exit the function use_Local, the a is "<<a<<endl;
}
void use_Static_Local()
{
static int a=5; //定義靜態變量,函數調用結束后,仍存在,但是僅在此函數中可以調用,脫離此作用域,就不行。
cout<<"enter the function use_Static_Local, the a is "<<a<<endl;
a++;;
cout<<"exit the function use_Static_Local, the a is "<<a<<endl;
}
~~~
