趙魁奎 趙海廷
(1.寧波理工環(huán)境能源科技股份有限公司 浙江 寧波:315806;2.武昌理工學(xué)院 信息工程學(xué)院 湖北 武漢:430223)
?
C++語(yǔ)言變量的生命期與作用域的探討
趙魁奎1趙海廷2
(1.寧波理工環(huán)境能源科技股份有限公司 浙江 寧波:315806;2.武昌理工學(xué)院 信息工程學(xué)院 湖北 武漢:430223)
變量的生命期是變量從創(chuàng)建到消亡的時(shí)間段,也稱為變量的存在性,就是說(shuō)一個(gè)變量是否還存在。變量的作用域是變量能被引用的范圍,也稱為變量的可見(jiàn)性,是指在變量存在的情況下能否被引用。一個(gè)變量若是可見(jiàn)的其必然存在,若其存在卻不一定就可見(jiàn)。主要討論了C++語(yǔ)言中變量的生命期、作用域、存在性及可見(jiàn)性等實(shí)際應(yīng)用的問(wèn)題。
生命期;作用域;存在性;可見(jiàn)性
1.1 C++變量的生命期
變量的生命期就是變量從創(chuàng)建到消亡的時(shí)間段。C++語(yǔ)言變量的生命期可分為靜態(tài)生命期和動(dòng)態(tài)生命期。
如果變量的生命期與系統(tǒng)程序的運(yùn)行時(shí)段相同,則該變量就具有靜態(tài)的生命期。在所有大括號(hào)對(duì)之外定義的變量具有靜態(tài)生命期。若定義變量時(shí)在數(shù)據(jù)類型之前冠以“static”關(guān)鍵字的外部變量或局部變量也具有靜態(tài)生命期。
在大括號(hào)對(duì)內(nèi)定義的變量其生命期從變量的定義點(diǎn)開(kāi)始,結(jié)束于定義該變量所對(duì)應(yīng)大括號(hào)處,這種變量具有動(dòng)態(tài)生命期。
變量的生命期也稱為變量的存在性;在其生命期期間,該變量必然是存在的即具有存在性。
1.2 C++變量的作用域
變量的作用域是變量能被引用的范圍。在變量的生存期間,每個(gè)變量都有各自的作用范圍,在各自的作用域內(nèi)、外,該變量可以是可見(jiàn)的,也可以是不可見(jiàn)的,也稱為變量的可見(jiàn)性。
一個(gè)變量若存在,但它能否被引用,這是該變量的作用域問(wèn)題。變量的作用域討論的是一個(gè)標(biāo)識(shí)符的有效引用范圍。
C++語(yǔ)言變量的作用域可以分為:函數(shù)原型作用域,異常處理參數(shù)作用域,局部作用域,文件作用域、全局作用域和對(duì)象族作用域。
(1)函數(shù)原型作用域
所謂函數(shù)原型作用域就是在函數(shù)說(shuō)明時(shí)形式參數(shù)的作用范圍。
例如:double Area(double radius);
其形參radius的作用范圍就在Area函數(shù)說(shuō)明的小括號(hào)對(duì)內(nèi),在程序的其它地方將沒(méi)有意義,也就是變量radius的作用域就在Area函數(shù)的原型說(shuō)明中。
(2)異常處理參數(shù)作用域
所謂異常處理參數(shù)作用域就是在異常處理時(shí),異常監(jiān)控段拋出異常對(duì)象后,異常處理程序段捕獲異常參數(shù)所具有的作用域。
例如:
try{……;cout?"9/0="?div(c,d)?endl;……;}
catch(int){cout?"撲獲了除數(shù)為'0'異常!"?endl;}
catch(…){……}
上述try{……}監(jiān)控的程序段中,若有異常發(fā)生,將拋出異常對(duì)象,異常對(duì)象將在catch(……)段被捕獲,該異常參數(shù)具有的作用域就是異常參數(shù)作用域。
(3)局部作用域
定義在大括號(hào)對(duì)內(nèi)的變量稱為局部變量,一個(gè)局部變量具有局部于本塊的生命期和作用域;也就是局部變量的作用域從聲明變量處開(kāi)始,一直到塊結(jié)束的大括號(hào)為止。
如果一個(gè)局部變量定義為靜態(tài)的,該變量具有全局的生命期和局部于本塊的局部作用域。
(4)全局作用域和文件作用域
若一個(gè)變量在大括號(hào)對(duì)之外被聲明,該變量具有全局的生命期和全局的作用域。若是多文件系統(tǒng),通過(guò)extern說(shuō)明,還可以在其它文件中引用。
一個(gè)全局變量在定義時(shí),在其數(shù)據(jù)類型關(guān)鍵字前面冠以“static”關(guān)鍵字,這種變量的作用域開(kāi)始于變量定義點(diǎn),結(jié)束于本文件,即該變量具有全局的生命期和本文件的作用域,也就是該變量只能在定義它的文件中引用。
(5)對(duì)象族作用域
在面向?qū)ο蟮腃++系統(tǒng)中,類的數(shù)據(jù)成員在創(chuàng)建該類的對(duì)象時(shí),該類的數(shù)據(jù)成員將被復(fù)制到各個(gè)對(duì)象之中,這些數(shù)據(jù)成員具有對(duì)象族作用域。
靜態(tài)成員變量要在類內(nèi)進(jìn)行靜態(tài)變量的說(shuō)明,在類外進(jìn)行靜態(tài)變量的初始化。該變量在該類的所有對(duì)象間只有一個(gè)拷貝,為所有對(duì)象共享;可以認(rèn)為靜態(tài)成員變量對(duì)該類族的所有對(duì)象具有生命期和作用域。
C++語(yǔ)言程序在內(nèi)存中一般分為如下六個(gè)區(qū):
(1)代碼區(qū):代碼區(qū)為程序代碼在內(nèi)存中的映射。
(2)常量區(qū):常量、字符串等存放在該區(qū)。
(3)初始化數(shù)據(jù)(data)區(qū):已經(jīng)初始化的變量的存儲(chǔ)區(qū)域,初始化了的全局變量和靜態(tài)變量存在該區(qū)域。
(4)未初始化數(shù)據(jù)(BSS)區(qū):全局變量和靜態(tài)變量未初始化的存儲(chǔ)區(qū)域。未初始化的數(shù)據(jù)(BSS)區(qū)位于初始化數(shù)據(jù)區(qū)相鄰的一個(gè)區(qū)。
(5)棧(stack)區(qū):臨時(shí)變量存儲(chǔ)區(qū)。進(jìn)程進(jìn)入該程序塊時(shí)為該局部變量分配內(nèi)存空間,退出塊時(shí)釋放該空間;函數(shù)的參數(shù)也存儲(chǔ)在該區(qū)域。
(6)堆(heap)區(qū):動(dòng)態(tài)申請(qǐng)內(nèi)存分配存儲(chǔ)區(qū)。程序執(zhí)行new運(yùn)算符時(shí)申請(qǐng)存儲(chǔ)空間,執(zhí)行delete運(yùn)算符時(shí)釋放相應(yīng)的存儲(chǔ)空間。
通常又將(3)和(4)區(qū)域稱為靜態(tài)存儲(chǔ)區(qū),5和6區(qū)域稱為動(dòng)態(tài)存儲(chǔ)區(qū)
下面給出闡述上述問(wèn)題的實(shí)際應(yīng)用例子,它包括:File1.cpp、Jbjthshu.cpp和hshuMain.cpp三個(gè)文件。
3.1 File1.cpp
//File1.cpp
#include
int Iqjbl=123;//外部變量定義
extern double Dqjbl;//外部全局變量的說(shuō)明
extern float Fstatic;//外部靜態(tài)全局變量說(shuō)明
void Display()//Display()函數(shù)定義
{cout?"在Display()函數(shù)中,全局變量Dqjbl的值為:"?Dqjbl?endl;
//cout?"在Display()函數(shù)中,靜態(tài)全局變量Fstatic的值為:"?Fstatic?endl;錯(cuò)誤
}
3.2 Jbjthshu.cpp
//Jbjthshu.cpp
#include
void Jbjthshu(intx)
{inty=0;//局部變量初始化
static int Sjbjt=0;//局部靜態(tài)變量初始化
Sjbjt++;//局部靜態(tài)變量后置加1運(yùn)算
cout?"在Jbjthshu()函數(shù)中,函數(shù)參數(shù)x和局部變量y的值為:x="?x?",y="?y?endl;
cout?"在Jbjthshu()函數(shù)中,局部靜態(tài)變量Sjbjt的值為:Sjbjt="?Sjbjt?endl;
}
3.3 hshuMain.cpp
//hshuMain.cpp
#include
class Clock//時(shí)鐘類的聲明
{public://公有成員函數(shù),外部公共接口
//Clock類的構(gòu)造函數(shù)
Clock(int NewH,int NewM,int NewS)
{Hour=NewH;Minute=NewM;Second=NewS;}
void ShowTime()//Clock類的成員函數(shù)
{cout?"現(xiàn)在是"?Hour?"小時(shí)"?Minute?"分鐘"?Second?"秒鐘。"?endl;}
//私有數(shù)據(jù)成員
private: int Hour,Minute,Second;
};
extern Iqjbl;//外部變量的說(shuō)明
extern void Display();//外部函數(shù)的說(shuō)明
extern void Jbjthshu(int);//外部函數(shù)的說(shuō)明
double Dqjbl=12.345;//外部變量定義初始化
//外部靜態(tài)變量的定義及初始化
static float Fstatic=5.4321f;
int div(intx, inty)//外部函數(shù)的定義
{if (y==0) throwy;
returnx/y;
}
void main()
{cout?"在main()主函數(shù)中,全局變量Iqjbl的值為:"?Iqjbl?endl;//①
cout?"在main()主函數(shù)中,靜態(tài)全局變量Fstatic的值為:"?Fstatic?endl;//②
Display();//③外部函數(shù)的調(diào)用
//④帶參外部函數(shù)的調(diào)用
Jbjthshu(5);Jbjthshu(8);
int sum=0;//sum定義為局部變量
//⑤i定義為局部變量
for(inti=1;i<11;i++) sum+=i;
cout?"sum="?sum?endl;
//局部變量定義
inta=8,b=2,c=9,d=0,x=7,y=3;
cout?"除數(shù)為零異常舉例 ";
try//⑥異常監(jiān)控程序段
{cout?"8/2="?div(a,b)?endl;
cout?"9/0="?div(c,d)?endl;
cout?"7/3="?div(x,y)?endl;
}
//異常捕獲程序段,int具有異常參數(shù)作用域
catch(int )
{cout?"撲獲了除數(shù)為'0'異常!"?endl;}
//⑦輸出局部變量i的值
cout?"i="?i?endl;
cout?"對(duì)象當(dāng)前的時(shí)間是:";
//⑧設(shè)置時(shí)間為:7:0:0
Clock MyClock1(7,0,0);
//調(diào)用MyClock1對(duì)象ShowTime()輸出時(shí)間
MyClock1.ShowTime();
}
在上述例子中:
語(yǔ)句①引用的是File1.cpp文件的全局變量,要用“extern Iqjbl;”說(shuō)明,也就是Iqjbl變量具有全局的存在性和全局的可見(jiàn)性。語(yǔ)句②引用的是本文件的靜態(tài)全局變量,在本文件中引用,不需要說(shuō)明;但在File1.cpp文件中不能引用,即Fstatic變量具有全局的生命期,只具有所在文件的作用域;也就是Fstatic具有全局的存在性和本文件的可見(jiàn)性。語(yǔ)句①、②的輸出為:
在main()主函數(shù)中,全局變量Iqjbl的值為:123
在main()主函數(shù)中,靜態(tài)全局變量Fstatic的值為:5.4321
語(yǔ)句③調(diào)用File1.cpp文件的函數(shù),需要“extern void Display();”語(yǔ)句進(jìn)行函數(shù)說(shuō)明。在Display()函數(shù)中,調(diào)用了外部變量Dqjbl,要“extern double Dqjbl;”外部變量說(shuō)明,但靜態(tài)全局變量Fstatic即使用“extern float Fstatic;”進(jìn)行了說(shuō)明也不能進(jìn)行引用,其原因是該變量在其它文件中的可見(jiàn)性為不可見(jiàn)。該語(yǔ)句的輸出為:
“在Display()函數(shù)中,全局變量Dqjbl的值為:12.345”。
語(yǔ)句④兩次調(diào)用Jbjtbl()函數(shù),第1次調(diào)用Jbjthshu(5)函數(shù),輸出為:
“在Jbjtbl()函數(shù)中,函數(shù)參數(shù)x和局部變量y的值為:x=5,y=0”
“在Jbjtbl()函數(shù)中,局部靜態(tài)變量Sjbbl的值為:Sjbjt=1”。
第2次調(diào)用Jbjthshu(8)函數(shù),輸出為:
“在Jbjthshu()函數(shù)中,函數(shù)參數(shù)x和局部變量y的值為:x=8,y=0”
“在Jbjthshu()函數(shù)中,局部靜態(tài)變量Sjbbl的值為:Sjbjt=2”。
Jbjthshu()函數(shù)的形參x和函數(shù)的局部變量y都具有該函數(shù)的生命期和作用域,即它們?cè)谠摵瘮?shù)中有存在性和可見(jiàn)性。而局部靜態(tài)變量Sjbjt具有全局的生命期和局部的作用域,即Sjbjt具有全局的存在性和局部于該函數(shù)的可見(jiàn)性。
語(yǔ)句⑤,在for語(yǔ)句中定義了局部變量i,其后通過(guò)“sum+=i;”進(jìn)行累加,sum的值輸出為:
“sum=55”。
語(yǔ)句⑥,通過(guò)try{……}實(shí)施對(duì)異常監(jiān)控,有異常發(fā)生時(shí),該監(jiān)控段拋出異常對(duì)象,由“catch(int )”對(duì)異常對(duì)象進(jìn)行捕獲,其catch(int )的參數(shù)就具有異常參數(shù)作用域,也就是該參數(shù)只有在該程序段才具有可見(jiàn)性。其輸出為:
“除數(shù)為零異常舉例”
“8/2=4”
“撲獲了除數(shù)為'0'異常!”
語(yǔ)句⑦,輸出局部變量i的值,其輸出值為:
“i=11”
此i是語(yǔ)句⑤在for語(yǔ)句中定義的局部變量,其生命期及作用域均從定義點(diǎn)開(kāi)始到本局部的結(jié)束,也就是其存在性和可見(jiàn)性都是局部的。
語(yǔ)句⑧,創(chuàng)建一個(gè)“Clock MyClock1(7,0,0);”對(duì)象,本語(yǔ)句將在MyClock1對(duì)象中設(shè)置其類中的數(shù)據(jù)成員“Hour、Minute和Second;”分別為:7:0:0。該類的數(shù)據(jù)成員“Hour、Minute和Second”具有類族的存在性和可見(jiàn)性。其輸出為:
“對(duì)象當(dāng)前的時(shí)間是:現(xiàn)在是7小時(shí)0分鐘0秒鐘”。
需要注意:
(1)在hshuMain.cpp文件的main函數(shù)for(inti=1;i<11;i++)中的inti具有從定義點(diǎn)開(kāi)始到本函數(shù)結(jié)束的生命期和作用域;但在Java語(yǔ)言中,i變量只具有本語(yǔ)句的生命期和作用域。
(2)在Jbjthshu.cpp文件的Sjbjt具有全局的生命期和局部于Jbjthshu本函數(shù)的作用域。
變量或?qū)ο蟮拇嬖谛员砻饕粋€(gè)變量或?qū)ο笫欠翊嬖冢蛔兞炕驅(qū)ο蟮目梢?jiàn)性則是指變量或?qū)ο蟠嬖诘那闆r下能否被引用;對(duì)于一個(gè)變量或?qū)ο蠖裕骸按嬖诘牟灰欢梢?jiàn),可見(jiàn)的一定存在”。
[1] 趙海廷等編著.C++引言程序設(shè)計(jì)教程[M].北京:清華大學(xué)出版社,2014.
[2] 嚴(yán)運(yùn)國(guó),趙海廷主編.C++程序設(shè)計(jì)基礎(chǔ)[M].北京:科學(xué)出版社,2005.
[3] 趙海廷,嚴(yán)運(yùn)國(guó)主編.C++程序設(shè)計(jì)基礎(chǔ)導(dǎo)學(xué)[M].北京:科學(xué)出版社,2006.
[4] 趙海廷主編.C++語(yǔ)言程序設(shè)計(jì)[M].北京:北京理工大學(xué)出版社,2009
(責(zé)任編輯:李文英)
Discussion of Life Cycle and Scope of C++ Language Variations
Zhao Kuikui1Zhao Haiting2
(1.Ningbo Ligong Environment and Energy Technology Co., LTD, Ningbo 315806, Zhejiang;2.Wuchang University of Technology, Wuhan 430223, Hubei)
Life cycle of a variation is the period in which a variation is created and disappears; it is also called as the existence of a variation. A variation’s function is the scope in which it can be quoted, that is, the visibility of a variation, which means whether a variation is quoted in the period it exists. A visible variation does exist while an existing variation is not necessary visible. This paper mainly discusses the life cycle, scope, existence, and visibility of C++ language variations.
life cycle; scope; existence; visibility
2016-10-21
2016-11-04
趙魁奎(1981~),男,大學(xué),工程師.E-mail:28712870@qq.com
TP312
A
1671-3524(2016)04-0037-04