細(xì)說C++全局變量、局部變量和靜態(tài)局部變量
2020-05-23 14:28:40
供稿:網(wǎng)友
我們已經(jīng)在前面學(xué)習(xí)了變量,并且能夠熟練地使用它。可是,僅僅靠這些知識(shí),有些問題仍然無(wú)法得到解決。
標(biāo)志符
首先要來介紹一下什么是標(biāo)志符。在程序設(shè)計(jì)的過程中,經(jīng)常要給變量、函數(shù)甚至是一些數(shù)據(jù)類型起名字(還包括以后的類名,對(duì)象名等)。我們把這些用戶根據(jù)一些規(guī)定,自己定義的各種名字統(tǒng)稱為標(biāo)志符(Identifier)。顯然,標(biāo)志符不允許和任何保留字相同。
全局變量和局部變量
在函數(shù)這一章節(jié)中,我們說過函數(shù)體內(nèi)聲明的變量?jī)H在該函數(shù)體內(nèi)有效,別的函數(shù)是無(wú)法使用的。并且在函數(shù)運(yùn)行結(jié)束后,這些變量也將消失了。我們把這些在函數(shù)體內(nèi)聲明的變量稱為局部變量(Local Variable)。
然而,可能會(huì)遇到這樣的問題:我們想要?jiǎng)?chuàng)建一個(gè)變量作為數(shù)據(jù)緩沖區(qū)(Buffer),分別供數(shù)據(jù)生成、數(shù)據(jù)處理和數(shù)據(jù)輸出三個(gè)函數(shù)使用,三個(gè)函數(shù)都要能夠讀取或修改這個(gè)變量的值。顯然通過傳遞參數(shù)或返回值來解決這個(gè)問題是非常麻煩的。
那么,我們能否建立一個(gè)變量能夠讓這三個(gè)函數(shù)共同使用呢?在C++中,我們可以在函數(shù)體外聲明一個(gè)變量,它稱為全局變量(global variable)。所謂全局,是指對(duì)于所有函數(shù)都能夠使用。當(dāng)然,在該變量聲明之前出現(xiàn)的函數(shù)是不知道該變量的存在的,于是也就無(wú)法使用它了。另外,如果我們聲明了一個(gè)全局變量之后沒有對(duì)它進(jìn)行初始化操作,則編譯器會(huì)自動(dòng)將它的值初始化為0。
下面,我們就用全局變量來實(shí)現(xiàn)剛才提出的那個(gè)問題:(程序11.1.1)
#include "iostream.h"
#include "stdlib.h"//用于產(chǎn)生隨機(jī)數(shù),不必理會(huì)
#include "time.h"//用于產(chǎn)生隨機(jī)數(shù),不必理會(huì)
#include "iomanip.h"//用于設(shè)置域?qū)?br />void makenum();
void output();
void cal();
int main()
{
srand(time(NULL));//用于產(chǎn)生隨機(jī)數(shù),不必理會(huì)
for (int i=0;i<4;i++)
{
makenum();//產(chǎn)生隨機(jī)數(shù)放入緩沖區(qū)
cal();//對(duì)緩沖區(qū)的數(shù)進(jìn)行處理
output();//輸出緩沖區(qū)的數(shù)值
}
return 0;
}
int buffer;//定義全局變量,以下函數(shù)都能使用它
void makenum()
{
cout <<"Running make number..." <<endl;
buffer=rand();//把產(chǎn)生的隨機(jī)數(shù)放入緩沖區(qū)
}
void cal()
{
cout <<"Running calculate..." <<endl;
buffer=buffer%100;
}
void output()
{
cout <<"Running output..." <<endl;
cout <<setw(2) <<buffer <<endl;
}
運(yùn)行結(jié)果:
Running make number...
Running calculate...
Running output...
48
Running make number...
Running calculate...
Running output...
47
Running make number...
Running calculate...
Running output...
24
Running make number...
Running calculate...
Running output...
90
以上為某次運(yùn)行得到的隨機(jī)結(jié)果??梢?,使用全局變量使得多個(gè)函數(shù)之間可以共享一個(gè)數(shù)據(jù),同時(shí)從理論上實(shí)現(xiàn)了函數(shù)之間的通訊。
靜態(tài)局部變量
全局變量實(shí)現(xiàn)了函數(shù)之間共享數(shù)據(jù),也使得變量不再會(huì)因?yàn)槟硞€(gè)函數(shù)的結(jié)束而消亡。但是,新問題又出現(xiàn)了:一個(gè)密碼檢測(cè)函數(shù)根據(jù)調(diào)用(用戶輸錯(cuò)密碼)的次數(shù)來限制他進(jìn)入系統(tǒng)。如果把調(diào)用次數(shù)存放在一個(gè)局部變量里,顯然是不可行的。雖然全局變量可以記錄一個(gè)函數(shù)的運(yùn)行次數(shù),但是這個(gè)變量是被所有函數(shù)共享的,每個(gè)函數(shù)都能修改它,實(shí)在很危險(xiǎn)。我們現(xiàn)在需要的是一個(gè)函數(shù)運(yùn)行結(jié)束后不會(huì)消失的,并且其他函數(shù)無(wú)法訪問的變量。
C++中,我們可以在函數(shù)體內(nèi)聲明一個(gè)靜態(tài)局部變量(Static Local Variable)。它在函數(shù)運(yùn)行結(jié)束后不會(huì)消失,并且只有聲明它的函數(shù)中能夠使用它。聲明一個(gè)靜態(tài)局部變量的方法是在聲明局部變量前加上static,例如:
static int a;
和全局變量類似,如果我們沒有對(duì)一個(gè)靜態(tài)局部變量做初始化,則編譯器會(huì)自動(dòng)將它初始化為0。
下面,我們就用靜態(tài)局部變量來模擬一下這個(gè)密碼檢測(cè)函數(shù)的功能:(程序11.1.2)
#include "iostream.h"
#include "stdlib.h"
bool password();//密碼檢測(cè)函數(shù)
int main()
{
do
{
}
while (password()!=true);//反復(fù)檢測(cè)密碼直到密碼正確
cout <<"歡迎您進(jìn)入系統(tǒng)!" <<endl;
return 0;
}
bool password()
{
static numOfRun=0;//聲明靜態(tài)局部變量存放函數(shù)調(diào)用次數(shù)
if (numOfRun<3)
{
int psw;
cout <<"第" <<++numOfRun <<"次輸入密碼" <<endl;
cin >>psw;
if (psw==123456)
{
return true;
}
else
{
cout <<"密碼錯(cuò)誤!" <<endl;
return false;
}
}
else
{
cout <<"您已經(jīng)輸錯(cuò)密碼三次!異常退出!" <<endl;
exit(0);//退出程序運(yùn)行
}
}
第一次運(yùn)行結(jié)果:
第1次輸入密碼
111111
密碼錯(cuò)誤!
第2次輸入密碼
222222
密碼錯(cuò)誤!
第3次輸入密碼
0
密碼錯(cuò)誤!
您已經(jīng)輸錯(cuò)密碼三次!異常退出!
第二次運(yùn)行結(jié)果:
第1次輸入密碼
000000
密碼錯(cuò)誤!
第2次輸入密碼
123456
歡迎您進(jìn)入系統(tǒng)!
使用靜態(tài)局部變量可以讓函數(shù)產(chǎn)生的數(shù)據(jù)更長(zhǎng)期更安全地存儲(chǔ)。如果一個(gè)函數(shù)運(yùn)行和它以前的運(yùn)行結(jié)果有關(guān),那么一般我們就會(huì)使用靜態(tài)局部變量。