C++语言变量的生命期与作用域的探讨
2016-03-17赵魁奎赵海廷
赵魁奎 赵海廷
(1.宁波理工环境能源科技股份有限公司 浙江 宁波:315806;2.武昌理工学院 信息工程学院 湖北 武汉:430223)
C++语言变量的生命期与作用域的探讨
赵魁奎1赵海廷2
(1.宁波理工环境能源科技股份有限公司 浙江 宁波:315806;2.武昌理工学院 信息工程学院 湖北 武汉:430223)
变量的生命期是变量从创建到消亡的时间段,也称为变量的存在性,就是说一个变量是否还存在。变量的作用域是变量能被引用的范围,也称为变量的可见性,是指在变量存在的情况下能否被引用。一个变量若是可见的其必然存在,若其存在却不一定就可见。主要讨论了C++语言中变量的生命期、作用域、存在性及可见性等实际应用的问题。
生命期;作用域;存在性;可见性
1 C++变量的生命期与作用域
1.1 C++变量的生命期
变量的生命期就是变量从创建到消亡的时间段。C++语言变量的生命期可分为静态生命期和动态生命期。
如果变量的生命期与系统程序的运行时段相同,则该变量就具有静态的生命期。在所有大括号对之外定义的变量具有静态生命期。若定义变量时在数据类型之前冠以“static”关键字的外部变量或局部变量也具有静态生命期。
在大括号对内定义的变量其生命期从变量的定义点开始,结束于定义该变量所对应大括号处,这种变量具有动态生命期。
变量的生命期也称为变量的存在性;在其生命期期间,该变量必然是存在的即具有存在性。
1.2 C++变量的作用域
变量的作用域是变量能被引用的范围。在变量的生存期间,每个变量都有各自的作用范围,在各自的作用域内、外,该变量可以是可见的,也可以是不可见的,也称为变量的可见性。
一个变量若存在,但它能否被引用,这是该变量的作用域问题。变量的作用域讨论的是一个标识符的有效引用范围。
C++语言变量的作用域可以分为:函数原型作用域,异常处理参数作用域,局部作用域,文件作用域、全局作用域和对象族作用域。
(1)函数原型作用域
所谓函数原型作用域就是在函数说明时形式参数的作用范围。
例如:double Area(double radius);
其形参radius的作用范围就在Area函数说明的小括号对内,在程序的其它地方将没有意义,也就是变量radius的作用域就在Area函数的原型说明中。
(2)异常处理参数作用域
所谓异常处理参数作用域就是在异常处理时,异常监控段抛出异常对象后,异常处理程序段捕获异常参数所具有的作用域。
例如:
try{……;cout≪"9/0="≪div(c,d)≪endl;……;}
catch(int){cout≪"扑获了除数为'0'异常!"≪endl;}
catch(…){……}
上述try{……}监控的程序段中,若有异常发生,将抛出异常对象,异常对象将在catch(……)段被捕获,该异常参数具有的作用域就是异常参数作用域。
(3)局部作用域
定义在大括号对内的变量称为局部变量,一个局部变量具有局部于本块的生命期和作用域;也就是局部变量的作用域从声明变量处开始,一直到块结束的大括号为止。
如果一个局部变量定义为静态的,该变量具有全局的生命期和局部于本块的局部作用域。
(4)全局作用域和文件作用域
若一个变量在大括号对之外被声明,该变量具有全局的生命期和全局的作用域。若是多文件系统,通过extern说明,还可以在其它文件中引用。
一个全局变量在定义时,在其数据类型关键字前面冠以“static”关键字,这种变量的作用域开始于变量定义点,结束于本文件,即该变量具有全局的生命期和本文件的作用域,也就是该变量只能在定义它的文件中引用。
(5)对象族作用域
在面向对象的C++系统中,类的数据成员在创建该类的对象时,该类的数据成员将被复制到各个对象之中,这些数据成员具有对象族作用域。
静态成员变量要在类内进行静态变量的说明,在类外进行静态变量的初始化。该变量在该类的所有对象间只有一个拷贝,为所有对象共享;可以认为静态成员变量对该类族的所有对象具有生命期和作用域。
2 C++语言程序的内存空间分配
C++语言程序在内存中一般分为如下六个区:
(1)代码区:代码区为程序代码在内存中的映射。
(2)常量区:常量、字符串等存放在该区。
(3)初始化数据(data)区:已经初始化的变量的存储区域,初始化了的全局变量和静态变量存在该区域。
(4)未初始化数据(BSS)区:全局变量和静态变量未初始化的存储区域。未初始化的数据(BSS)区位于初始化数据区相邻的一个区。
(5)栈(stack)区:临时变量存储区。进程进入该程序块时为该局部变量分配内存空间,退出块时释放该空间;函数的参数也存储在该区域。
(6)堆(heap)区:动态申请内存分配存储区。程序执行new运算符时申请存储空间,执行delete运算符时释放相应的存储空间。
通常又将(3)和(4)区域称为静态存储区,5和6区域称为动态存储区
3 变量生命期和作用域的举例
下面给出阐述上述问题的实际应用例子,它包括:File1.cpp、Jbjthshu.cpp和hshuMain.cpp三个文件。
3.1 File1.cpp
//File1.cpp
#include
int Iqjbl=123;//外部变量定义
extern double Dqjbl;//外部全局变量的说明
extern float Fstatic;//外部静态全局变量说明
void Display()//Display()函数定义
{cout≪"在Display()函数中,全局变量Dqjbl的值为:"≪Dqjbl≪endl;
//cout≪"在Display()函数中,静态全局变量Fstatic的值为:"≪Fstatic≪endl;错误
}
3.2 Jbjthshu.cpp
//Jbjthshu.cpp
#include
void Jbjthshu(intx)
{inty=0;//局部变量初始化
static int Sjbjt=0;//局部静态变量初始化
Sjbjt++;//局部静态变量后置加1运算
cout≪"在Jbjthshu()函数中,函数参数x和局部变量y的值为:x="≪x≪",y="≪y≪endl;
cout≪"在Jbjthshu()函数中,局部静态变量Sjbjt的值为:Sjbjt="≪Sjbjt≪endl;
}
3.3 hshuMain.cpp
//hshuMain.cpp
#include
class Clock//时钟类的声明
{public://公有成员函数,外部公共接口
//Clock类的构造函数
Clock(int NewH,int NewM,int NewS)
{Hour=NewH;Minute=NewM;Second=NewS;}
void ShowTime()//Clock类的成员函数
{cout≪"现在是"≪Hour≪"小时"≪Minute≪"分钟"≪Second≪"秒钟。"≪endl;}
//私有数据成员
private: int Hour,Minute,Second;
};
extern Iqjbl;//外部变量的说明
extern void Display();//外部函数的说明
extern void Jbjthshu(int);//外部函数的说明
double Dqjbl=12.345;//外部变量定义初始化
//外部静态变量的定义及初始化
static float Fstatic=5.4321f;
int div(intx, inty)//外部函数的定义
{if (y==0) throwy;
returnx/y;
}
void main()
{cout≪"在main()主函数中,全局变量Iqjbl的值为:"≪Iqjbl≪endl;//①
cout≪"在main()主函数中,静态全局变量Fstatic的值为:"≪Fstatic≪endl;//②
Display();//③外部函数的调用
//④带参外部函数的调用
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≪"除数为零异常举例 ";
try//⑥异常监控程序段
{cout≪"8/2="≪div(a,b)≪endl;
cout≪"9/0="≪div(c,d)≪endl;
cout≪"7/3="≪div(x,y)≪endl;
}
//异常捕获程序段,int具有异常参数作用域
catch(int )
{cout≪"扑获了除数为'0'异常!"≪endl;}
//⑦输出局部变量i的值
cout≪"i="≪i≪endl;
cout≪"对象当前的时间是:";
//⑧设置时间为:7:0:0
Clock MyClock1(7,0,0);
//调用MyClock1对象ShowTime()输出时间
MyClock1.ShowTime();
}
4 变量生命期和作用域举例的说明
在上述例子中:
语句①引用的是File1.cpp文件的全局变量,要用“extern Iqjbl;”说明,也就是Iqjbl变量具有全局的存在性和全局的可见性。语句②引用的是本文件的静态全局变量,在本文件中引用,不需要说明;但在File1.cpp文件中不能引用,即Fstatic变量具有全局的生命期,只具有所在文件的作用域;也就是Fstatic具有全局的存在性和本文件的可见性。语句①、②的输出为:
在main()主函数中,全局变量Iqjbl的值为:123
在main()主函数中,静态全局变量Fstatic的值为:5.4321
语句③调用File1.cpp文件的函数,需要“extern void Display();”语句进行函数说明。在Display()函数中,调用了外部变量Dqjbl,要“extern double Dqjbl;”外部变量说明,但静态全局变量Fstatic即使用“extern float Fstatic;”进行了说明也不能进行引用,其原因是该变量在其它文件中的可见性为不可见。该语句的输出为:
“在Display()函数中,全局变量Dqjbl的值为:12.345”。
语句④两次调用Jbjtbl()函数,第1次调用Jbjthshu(5)函数,输出为:
“在Jbjtbl()函数中,函数参数x和局部变量y的值为:x=5,y=0”
“在Jbjtbl()函数中,局部静态变量Sjbbl的值为:Sjbjt=1”。
第2次调用Jbjthshu(8)函数,输出为:
“在Jbjthshu()函数中,函数参数x和局部变量y的值为:x=8,y=0”
“在Jbjthshu()函数中,局部静态变量Sjbbl的值为:Sjbjt=2”。
Jbjthshu()函数的形参x和函数的局部变量y都具有该函数的生命期和作用域,即它们在该函数中有存在性和可见性。而局部静态变量Sjbjt具有全局的生命期和局部的作用域,即Sjbjt具有全局的存在性和局部于该函数的可见性。
语句⑤,在for语句中定义了局部变量i,其后通过“sum+=i;”进行累加,sum的值输出为:
“sum=55”。
语句⑥,通过try{……}实施对异常监控,有异常发生时,该监控段抛出异常对象,由“catch(int )”对异常对象进行捕获,其catch(int )的参数就具有异常参数作用域,也就是该参数只有在该程序段才具有可见性。其输出为:
“除数为零异常举例”
“8/2=4”
“扑获了除数为'0'异常!”
语句⑦,输出局部变量i的值,其输出值为:
“i=11”
此i是语句⑤在for语句中定义的局部变量,其生命期及作用域均从定义点开始到本局部的结束,也就是其存在性和可见性都是局部的。
语句⑧,创建一个“Clock MyClock1(7,0,0);”对象,本语句将在MyClock1对象中设置其类中的数据成员“Hour、Minute和Second;”分别为:7:0:0。该类的数据成员“Hour、Minute和Second”具有类族的存在性和可见性。其输出为:
“对象当前的时间是:现在是7小时0分钟0秒钟”。
需要注意:
(1)在hshuMain.cpp文件的main函数for(inti=1;i<11;i++)中的inti具有从定义点开始到本函数结束的生命期和作用域;但在Java语言中,i变量只具有本语句的生命期和作用域。
(2)在Jbjthshu.cpp文件的Sjbjt具有全局的生命期和局部于Jbjthshu本函数的作用域。
5 结束语
变量或对象的存在性表明一个变量或对象是否存在;变量或对象的可见性则是指变量或对象存在的情况下能否被引用;对于一个变量或对象而言:“存在的不一定可见,可见的一定存在”。
[1] 赵海廷等编著.C++引言程序设计教程[M].北京:清华大学出版社,2014.
[2] 严运国,赵海廷主编.C++程序设计基础[M].北京:科学出版社,2005.
[3] 赵海廷,严运国主编.C++程序设计基础导学[M].北京:科学出版社,2006.
[4] 赵海廷主编.C++语言程序设计[M].北京:北京理工大学出版社,2009
(责任编辑:李文英)
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~),男,大学,工程师.E-mail:28712870@qq.com
TP312
A
1671-3524(2016)04-0037-04