主要内容 #
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; }