跳至正文
View Categories

1 min read

主要内容 #

1. 什么是作用域 #

这里有一段例程,请编译运行。并说明,在编译的时候,遇到了什么问题。

#include < iostream >
using namespace std;
int main()
{
    if(true)
    {
        int a(79);
    }
    std::cout << "a = " << a << std::endl;
    return 0;
}

可以看到,编译器提示:a 没有定义
这是为什么呢?

在 C++ 中,变量 a 定义 if 的 {} 内,所以在超过 {} 的区域,a 是不存在的!
这里 if 的 {} 区域,就被称为 a 的“作用域”

其实,说白了,所谓的变量 a 的 “作用域”,就是变量 a 可以被识别,被使用的区域。

C++ 中规定,作用域主要是由大括号“{ }”确定的。
变量在作用域内才是有效的。
运行到作用域结束时,变量就会被彻底删除。

2. 变量的作用域 #

2.1 大括号 #

请看下面的代码:

#include < iostream >
using namespace std;
int main()
{
    {
        int a(79); // 从定义 a 这行开始,到大括号结束,都属于 a 的作用域;
        int b(79); // 从定义 b 这行开始,到大括号结束,都属于 b 的作用域;
        int c(79); // 从定义 c 这行开始,到大括号结束,都属于 c 的作用域;
    }

    std::cout      // 这里不属于 a 的作用域。
        << "a = " 
        << a 
        << std::endl;

    return 0;
}

在 C++ 程序中,大括号可以直接框定一个封闭的区域。
在这个区域内定义的变量,在这个区域之外,不可使用。

这是一个很有用的功能。

  • 复用代码,解决“变量重复定义”的编译错误。
// 此代码是有问题的,“变量 dashima_a 重复定义”。
#include < iostream >
using namespace std;
int main()
{
    int dashima_a(79); 
    std::cout << "dashima_a = " << dashima_a << std::endl;

    int dashima_a(80); 
    std::cout << "dashima_a = " << dashima_a << std::endl;

    int dashima_a(81); 
    std::cout << "dashima_a = " << dashima_a << std::endl;

    return 0;
}

加上大括号,就可以解决上面的问题。

// 此代码是正确的。
#include < iostream >
using namespace std;
int main()
{
    {
        int dashima_a(79); 
        std::cout << "dashima_a = " << dashima_a << std::endl;
    }

    {
        int dashima_a(80); 
        std::cout << "dashima_a = " << dashima_a << std::endl;
    }

    {
        int dashima_a(81); 
        std::cout << "dashima_a = " << dashima_a << std::endl;
    }

    return 0;
}

2.2 if 的大括号 #

其实所谓 if 的作用域,本质还是看大括号的范围。

#include < iostream >
using namespace std;
int main()
{
    if(true)
    {
        int a(79); // 从定义 a 这行开始,到大括号结束,都属于 a 的作用域;
        int b(79); // 从定义 b 这行开始,到大括号结束,都属于 b 的作用域;
        int c(79); // 从定义 c 这行开始,到大括号结束,都属于 c 的作用域;
    }
    std::cout      // 这里不属于 a 的作用域。
        << "a = " 
        << a 
        << std::endl;

    if(true)
        int a(79); // 只有这一行,都属于 a 的作用域;
                   // 这一行开始,已经不属于 a 的作用域;
                   // 而且,这里的 a 和 上面的 a 不是同一个变量,请解释为什么。

    return 0;
}

答案:
两个变量虽然都叫做 a ,但是属于不同的作用域。当上面的 a 在执行到作用域边缘时,
这个 a 就会被“释放”,也就是“从程序中删除”,这个变量 a 就不再存在了。
当执行到下面的 a 时,新创建的 a 是一个完全不同于之前的新变量。

2.3 while 的大括号 #

其实所谓 while 的作用域,本质还是看大括号的范围。

#include < iostream >
using namespace std;
int main()
{
    while(true)
    {
        int a(79); // 从定义 a 这行开始,到大括号结束,都属于 a 的作用域;
        int b(79); // 从定义 b 这行开始,到大括号结束,都属于 b 的作用域;
        int c(79); // 从定义 c 这行开始,到大括号结束,都属于 c 的作用域;
        break;
    }
    std::cout      // 这里不属于 a 的作用域。
        << "a = " 
        << a 
        << std::endl;

    while(true)
        int a(79); // 只有这一行,都属于 a 的作用域;
                   // 这一行开始,已经不属于 a 的作用域;
                   // 而且,这里的 a 和 上面的 a 不是同一个变量,原因同上。
 
    return 0;
}

习题 #

课后练习