2.6 初识名字查找
在前面作用域的介绍中,有这样的一段示例代码:
int sub_mul(int a, int b, int c) { int diff = a - b; return diff * c;}
a = 1; // 错误:a在这里都是不可见的但是,如果外面有一个全局变量 a,那么这段代码就是正确的:
int a = 1; // 全局变量 a
int sub_mul(int a, int b, int c) { int diff = a - b; return diff * c;}
a = 1; // 正确:这里被访问的是全局变量 a实际上,对于所有嵌套的作用域,内部的名字都会覆盖外部作用域中的名字。例如:
int a = 1; // a1{ int a = 2; // a2 { int a = 3; // a3 a += 1; // 在这里,a 是内部的 a3 } a += 1; // 在这里,a 是 a2}a += 1; // 在这里,a 是 a1这样内部可以覆盖外部的设计,让局部代码不需要关心和全局变量的冲突,显著减少了程序员的心智负担。但是,考虑如下的情况:
int a = 1;{ int a = 2; { a += 1; // 这里的 a 是哪个呢? }}这里的 a 是哪个呢?
非限定名字查找
Section titled “非限定名字查找”以目前讲述过的概念而言,读者可以用下面的规则来理解名字查找的过程:
- 声明必须在使用之前。
- 从下往上查找,在当前作用域找不到的话,到外层作用域继续向上查找。
- 如果一个名字找到至少一个对应的声明,就停止查找。
例如,前面的问题中:
int a = 1; // a1{ int a = 2; // a2 { a += 1; // 这里的 a 是 a2 }}名字查找只会向上查找,在如下的代码中:
int a = 1; // a1{ { a += 1; // 这里的 a 是 a1 int a = 2; // a2 } int a = 3; // a3}虽然后面的两个 a 在更内层的作用域中声明,但是在使用的时候,查找的过程是从下往上的,所以这里 a += 1; 中的 a 是外层的 a。
:::