一个内存位置需要被识别,它由一个名称来识别,称为变量。一个程序的长度,从上到下,有不同的部分,做不同的事情。有些部分是相关的,但在长度上是不连续的。不连续的部分的长度间隔有其他部分,这些部分与其他部分相关。
一个作用域是一组相关的部分,在这里可以使用或看到一个变量。作用域有名称。全局变量是一个可以在程序的每个作用域中看到的变量。一个全局变量可以有不同的类型。这篇文章解释了如何在常见的作用域中看到一个全局变量。
文章内容
- 相关部分
- 全局范围和全局变量
- 区块范围和全局变量
- 普通函数作用域和全局变量
- 类的范围和全局变量
- 总结
相关部分
考虑一下下面的程序。
#include <iostream>
using namespace std;
int it = 5;
float ft = 2.7;
int fn1 (int integ = it)
{
/* statements */
return integ;
}
float fn2 (float flt = ft)
{
/* statements */
return flt;
}
int main()
{
cout << fn1() << endl;
cout << fn2() << endl;
return 0;
}
输出结果是:
5
2.7
变量 "it "和ft是不同的类型。首先考虑变量 "it":"it "是在其声明行中看到的。一些行被跳过。然后在fn1()的签名中可以看到它。在fn1()的整个主体中也可以看到它。一些行和一部分被跳过。然后可以在main()函数的整个主体中看到它。实际上,在main()函数的第一条语句中,通过fn1()函数的调用,可以间接地看到它。刚才已经说明了变量 "it "的部分内容。
现在考虑一下变量ft:ft在其声明行中被看到。一些行和一个部分(fn1定义)被跳过。一个空行被跳过。然后在fn2()的签名中看到了它。在fn2()的整个主体中可以看到它。然后可以在main()函数的整个主体中看到它。实际上,在main()函数的第二条语句中,通过fn2()函数的调用,可以间接地看到它。刚才已经说明了变量'ft'的部分内容。
全局范围和全局变量
当程序员刚开始输入一个文件时,这就是全局范围。考虑一下下面的程序。
#include <iostream>
using namespace std;
char var = ‘E’;
int main()
{
cout <<var<<'\n';
cout <<::var<<'\n';
return 0;
}
输出结果是:
E
E
在这个程序中,var的部分或范围从var的声明点开始,一直向下延伸到翻译单元(文件)的结束。
main()函数的主体本身就是一个不同的作用域;全局作用域嵌套了main()函数作用域。
变量var是一个全局范围的变量,因为它可以在文件中的任何地方看到,从它被声明的地方开始。在main()函数作用域中可以看到它。在前面的程序中,"it "和ft是全局范围变量。每个变量都可以在其声明行、函数作用域和main()函数作用域中看到。
为了从不同的作用域访问一个全局变量(全局作用域的变量),直接使用变量名或在其前面加上作用域解析操作符::,如上面的程序所示。
解释代码:C++中的所有程序都应该至少以本程序开始的前两行为起点。这两行是
#include <iostream>
using namespace std;
这里的第一行不是一个语句;它是一个指令,一个包含指令。它包括了输入/输出流库,它负责向终端发送输出和接收键盘的输入。终端和键盘一起被称为控制台。这个库被称为iostream库(即输入/输出流库)。
程序中的第二行不是指令,它是一个语句,以分号结束。它说在它下面使用的任何名称都来自标准名称空间,除非另有说明。读者可能会感兴趣,知道命名空间有一个范围;然而,这将不会在本文中讨论。
前两行下面的语句是一个char变量的完整声明。在main()函数中,前两行以稍微不同的方式向终端打印同一个变量的值。
区块范围和全局变量
复合语句的例子是if、while、do、for或switch语句。这些复合语句中的每一个都可以有一个块。块范围变量是指在块中定义的变量。它的范围从它的声明点开始,到它的块的结束点结束。一个全局变量通常是在这个块之外和之上定义的。一个全局变量可以在这个块外、这个块的头行和块内看到。下面的程序用一个if块来说明这一点。
#include <iostream>
using namespace std;
int i = 5;
int main()
{
cout << "First i is: " << i << endl;
if (i == 5) {
cout << "Second i is same: " << i << endl;
}
return 0;
}
输出的结果是:
First i is: 5
Second i is same: 5
if-block是一个嵌套到main()函数作用域的块,而main()函数作用域是一个嵌套到全局作用域的块。这个程序表明,全局变量可以在嵌套块中看到。
嵌套块中的重写
一个全局变量可以在嵌套块中被覆盖。也就是说,在嵌套块中,全局变量可以被同名的变量所取代。在下面的程序中,i在嵌套块中被另一个实体--float取代。而这就是规则。嵌套作用域中与作用域外的变量同名的变量会覆盖该外层变量。所以,对于嵌套的作用域来说,在嵌套的作用域外声明的同名变量不能在嵌套的作用域内看到;因为嵌套的作用域内的变量已经在嵌套的作用域内占据了它的位置。嵌套的范围内的那个变量从它的声明点到它的块的末尾都可以看到。嵌套的范围内的那个不需要与嵌套的范围外的那个有任何关系。这个程序是
#include <iostream>
using namespace std;
int i = 5;
int main()
{
cout << "First i is: " << i << endl;
if (i == 5) {
float i = 7.0;
cout << "Second i is different: " << i << endl;
}
return 0;
}
输出的结果是:
First i is: 5
Second i is different: 7
重载变量的名称是一样的,而且仍然可以是相同的类型。
普通函数范围和全局变量
考虑一下下面的程序。
#include <iostream>
using namespace std;
int fn (int integ);
int i = 5;
int fn (int integ = i)
{
/* statements */
return integ;
}
int main()
{
cout << fn() << endl;
return 0;
}
函数fn()的声明区域由其原型的 "int fn (int integ); "一行、全局范围内的定义部分和主函数体中的调用语句组成,输出为5。所有这些行和部分构成了函数fn()的范围。fn()的函数签名是函数范围的一部分(也是主体的一部分)。现在,全局变量i已经在fn函数的所有行或部分中出现。
考虑一下下面的程序,有类和实例化的对象。
#include <iostream>
using namespace std;
int i = 5;
class Calc {
private:
int pM = i;
public:
void mfn(int inte = i)
{
cout << inte << endl;
}
};
class DCla: public Calc
{
public:
int dM = i;
};
int main()
{
Calc obj;
obj.mfn();
DCla dObj;
cout << dObj.dM << endl;
return 0;
}
输出结果是:
5
5
该程序有一个基类,Calc,和它的派生类,Dcla。基类对派生类是公开的:这意味着派生类可以看到基类的受保护成员。所以Calc类的部分是它的块和派生类Dcla的块。也就是说,Calc这个类的范围有两个部分。现在,全局变量i可以在这两个部分看到。
结论
一个内存位置需要被识别,它由一个名称来识别,称为变量。一个程序的长度,从上到下,有不同的部分,做不同的事情。有些部分是相关的,但在长度上是不连续的。不连续的部分的长度间隔有其他部分,这些部分与其他部分相关。
一个作用域是一组相关的部分,在这里可以使用或看到一个变量。作用域有名称。全局变量是一个可以在程序的每个作用域中看到的变量。一个全局变量可以是任何类型的。