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

posted @ 2019-09-25 18:33  慕慕慕慕  阅读(3383)  评论(0编辑  收藏  举报