一个变量名自从被声明或者被定义之后就可以应用了(例如sizeof和typeof需要变量声明,而地址操作符需要变量定义)。变量名可以开始被应用的那个点即变量的声明点。C++中变量的声明点即是在变量的声明或定义之后,而在变量的初始化之前。例如,
int num_apples;
int num_oranges = 4;
int num_fruits = num_apples + num_oranges; //成立,但读取一个没有初始化的变量结果是未知的
num_apples = 4; //可以写入
我们强调变量的声明点是在变量的初始化之前,所以变量的初始化也可以用到刚刚声明过的变量名。例如,
int num_apples = 2 * num_apples + 3; //语法成立
赋值号后面的num_apples是成立的,因为是在变量名的声明点之后。但是读取num_apples的结果是未知的,所以num_apples虽然被初始化,却被一个未知值初始化,结果仍然是未知的。
变量名的声明点这个词对很多人来说比较陌生,因为大部分教科书没有强调这个概念,但是他对我们理解变量名的作用域是很有用处的。一个变量名并不是在整个程序中都有效的,也并不一定在整个程序中都代表同一个变量(同一段内存空间)。变量名在程序中代表同一个变量的区域即是这个变量名对这个变量的作用域。变量名是从声明点开始有效的,他的作用域取决于不同的场合。在本小节我们只介绍两个最基本的概念:全局变量和局部变量。
全局变量是针对整个程序有效的变量。全局变量的作用域从声明点开始,一直到这个程序文件的结束。而局部变量仅仅在局部有效,局部变量一般被花括号包起来。他的作用域从声明点开始,一直到花括号结束。例如,
int global_var;
{
int local_var;
local_var = 10;
}
global_var = 5;
local_var = global_var + 1; //错误,local_var未定义
局域变量在花括号中间的作用域也叫做块作用域,我们可以把花括号括起来的部分看成一个块。C++中块里可以包括另外一个块,例如,
{
int outer_var = 10;
{
int inner_var;
inner_var = outer_var + 3;
}
inner_var = outer_var + 4; //错误
}
C++中,内部块的变量名可以和外部的名字相同,这时内部的名字就暂时隐藏了外部的名字,一直到该块结束。例如,
int outer_var = 10;
{
int outer_var = 5;
std::cout << outer_var << std::endl;
}
std::cout << outer_var << std::endl;