c++笔记_名字的作用域


前言

不论是在程序的什么位置,使用到的每个名字都会指向一个特定的实体:变量、函数、类型等。然而,同一个名字如果出现在程序的不同位置,也可能指向的是不同实体。


一、作用域是什么?

作用域(scope)是程序的一部分,在其中名字有其特定的含义。C++语言中大多数作用域都以花括号分隔。

同一个名字在不同的作用域中可能指向不同的实体。名字的有效区域始于名字的声明语句,以声明语句所在的用于末端为结束。

代码如下(示例):

#include<iostream>
using namespace std;
//从这段代码分析作用域
int main(void)
{
	int sum = 0;
	//sum用于存放从1到10所有数的和
	for(int val = 1; val <= 10 ;++val)
		sum += val;		//等价于sum = sum + val
		cout<<"1到10的和等于"<<sum<<endl;
	return 0;
}

上面的代码分别使用了3个名字:main、sum和val。

名字mian定义于所有花括号之外,它和其他大多数定义在函数体之外的名字一样拥有全局作用域(global scope)。一旦声明后,全局作用域的名字在整个程序的范围内都可以使用。

比如:

#include<iostream>
using namespace std;

int a = 1;						//函数体之外定义变量a

int main(void)
{
	cout<<a<<endl;				//因为名字a定义于所有花括号之外,所以它拥有全局作用域,因此名字a可以在整个程序的范围内使用。
	return 0;
}

回到第一个代码片段,名字sum定义于main函数所限定的作用域之内,从声明sum开始直到main函数结束为止都可以访问它,但是出了main函数所在的块就无法访问了,因此说变量sum拥有块作用域(block scope)。名字val定义于for语句内,在for语句之内可以访问val,但是在main函数的其他部分就不能访问它了。
比如:

#include<iostream>
using namespace std;
void visit();			//函数原型
int main(void)
{
	int sum = 0;			
	for(int val = 1; val <= 10 ;++val)
	{	
		sum += val;
	}								
	cout<<"1到10的和等于"<<sum<<endl;
	cout<<val<<endl;			//错误:无法访问val,因为val实在for语句内,所用只能在for语句花括号内才能访问,无法在for语句之外访问
	return 0;
}
void visit()
{	
	cout<<sum<<endl;	//无法访问main函数中变量sum,因为变量sum实在main函数内,所用sum拥有的是块作用域,而不是全局作用域
}

二、嵌套的作用域

作用域能彼此包含,被包含(或者说被嵌套)的作用域称为内层作用域(inner scope),包含着别的作用域的作用域被称为外城作用域(outer scope)。

作用域中一旦声明了某个名字,它所嵌套着的所有作用域中的都能访问该名字。同时,允许在内层作用域中重新定义外层作用域已有的名字:

#include<iostream>
using namespace std;
//该程序仅用于说明:函数内部不宜定义于全局变量同名的新变量
int reused = 42;	//reused拥有全局用作域(全局变量)
int main(void)
{
	int unique= 0;		//unique 拥有块作用域
	cout<<"#1:"<<"reused = "<<reused<<" "<<"unique = "<<unique<<endl;
	
	int reused = 0;		//新建局部变量reused,覆盖了全局变量reused(优先选择局部变量)
	cout<<"#2:"<<"reused = "<<reused<<" "<<"unique = "<<unique<<endl;

	cout<<"#3:"<<"reused = "<<::reused<<" "<<"unique = "<<unique<<endl;	//使用::作用域运算符访问全局变量
	return 0;
}

代码输出:

#1:reused = 42 unique = 0
#2:reused = 0 unique = 0
#3:reused = 42 unique = 0

代码分析:
输出#1 出现在局部变量reused定义之前,所以这条语句使用了全局作用域中定义的名字reused,输出42和0。

输出#2 发生在局部变量reused定义之后,此时局部变量reused正在作用域内,所以第二条输出语句使用的是局部变量reused而非全局变量,输出0和0。

输出#3 使用作用域操作符(:: )来覆盖默认的作用域规则,因为全局作用域本身并没有名字,所以当作用域操作符的左侧为空时,向全局作用域发出请求获取作用域操作符右侧名字对应的变量。所以第三条输出语句使用全局变量reused,输出42个0。

建议:如果函数有可能用到某全局变量,则不宜在定一个同名的局部变量。

总结

1:作用域是什么?->作用域(scope)是程序的一部分,在其中名字有其特定的含义。C++语言中大多数作用域都以花括号分隔。
2:全局变量要怎么定义?->全局变量需要在函数体之外(花括号外)进行定义
3:全局变量的作用域范围?->全局变量在整个程序范围内都能使用。
4:怎么访问全局变量?->使用作用域操作符(:: )进行访问,比如cout<<::a;
5:如果函数体内定义了与全局变量同名的变量名,会发生什么?->如果函数体内定义了与全局变量同名的变量名,那么如果不使用作用域操作符访问该变量,则会默认优先访问局部变量(函数体内与全局变量同名的变量)。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页