C++ 作用域
标识符的作用域
一、作用域的定义
作用域是一个标识符在程序正文中有效的区域,即定义的变量可以被应用的有效区域。
二、作用域的分类
1.函数原型作用域
函数原型作用域是C++程序中最小的作用域。在函数原型声明时形式参数的作用范围就是函数原型作用域。
例如,对于如下函数声明:
double area (double radius);
标识符radius的作用范围就在函数area形参列表的左右括号之间,在程序的其他地方不能引用这个标识符。从这里就可看出,radius的作用域称为函数原型作用域。
2.局部作用域
首先,我们看到书上的例子
void fun(int a){
int b=a;
cin>>b;
if(b>0){
int c;
...
}
}
在这个函数中,形参列表里声明了形参a,在函数体内声明了变量b,并用a的值初始化b。接下来,在if语句内,又声明了变量c。a,b和c都具有局部作用域,只是它们分别属于不同的局部作用域。
形参的作用域:从形参列表中的声明开始,到整个函数体结束之处为止。
函数体内声明变量的作用域:从声明处开始,一直到声明所在的块结束的大括号为止。
看了书上的例子后,再看以下的示例:
#include <iostream>
using namespace std;
int main ()
{
// 局部变量声明
int a, b;
int c;
// 实际初始化
a = 10;
b = 20;
c = a + b;
cout << c;
return 0;
}
运行结果如图。
3.类作用域
对于类X的某成员m的,它具有类作用域。访问m的方式有如下3种:
(1)如果X中没有声明同名的局部作用域标识符,那么可以直接访问m。
Student student;
student.show();
(2)使用x.m或X::m。这是访问对象成员的最基本方法。注意,X::m的方式用于访问类的静态成员。
void Student::show(){
cout<<Student::name<<endl;
}
(3)使用ptr->m,其中ptr为指向X类的一个对象的指针。
Student *student = new Student();
student->show();
4.命名空间作用域
命名空间的语法形式:
namespace 命名空间名(
命名空间名内的各种声明
)
使用方法:using语句
using 命名空间名::标识符名;
using namespace 命名空间名;
第一种,使得在当前作用域中可以直接引用该标识符,不能使用命名空间内的其他标识符;
第二种则可以直接引用该命名空间内的任何标识符。
命名空间的嵌套:
namespace OuterNs{
namespace InnerNs{
class SomeClass(...);
}
}
想要引用其中的SomeClass类十分复杂,需要使用OuterNs::InnerNs::SomeClass的语法形式。
三、实例验证
1.实验目的:用实验证明该知识点的使用
2.实验过程:
#include <iostream>
using namespace std;
int i; //在全局命名空间中的全局变量
namespace Ns{
int j; //在Ns命名空间中的全局变量
}
int main(){
i=5; //为全局变量i赋值
Ns::j=6; //为全局变量j赋值
{
using namespace Ns; //使当前块中可以直接引用Ns命名空间的标识符
int i; //局部变量,局部作用域
i=7;
cout<<"i="<<i<<endl; //测试
cout<<"j="<<j<<endl; //测试
}
cout<<"i="<<i<<endl; //测试
return 0;
}
运行结果:
结果分析:
代码中,变量 i 具有命名空间作用域,它属于全局命名空间,有效范围直到文件尾。在主函数开始处给 i 赋初值5,接下来又声明了同名变量并赋初值7。第一次输出的结果是7,这是因为具有局部作用域的变量 i 把具有命名空间作用域的 i 隐藏了,于是具有命名空间作用域的 i 变得不可见。
直到第一个块运行结束,输出的 i 的值为7,这说明具有局部作用域的 i 不在有效范围之内了,现在处在有效范围内的变量只有具有命名空间作用域的那个变量。
而对于j,它具有命名空间作用域,它被声明在命名空间 Ns 中,在主函数中通过 Ns::j 的方式引用,为其赋值,接下来在块中,通过 using namespace Ns 使得该命名空间的标识符可以在该块中被直接引用,因此输出时可以直接使用标识符 j 。