作用域规则
概念说明
作用域决定了一个名字在程序的哪些位置可以被访问。 在 C 语言里,常见的作用域包括块作用域和文件作用域,不同位置定义的变量可见范围不同。
作用域只回答“这里能不能访问这个名字”,并不等于“对象现在还活着”。
比如局部 static 变量的生命周期覆盖整个程序运行过程,但它的名字仍然只在局部块中可见。
如果内层代码定义了和外层同名的变量,内层名字会暂时遮蔽外层名字。 这类问题编译通常不会报错,但很容易让程序行为和预期不一致。
语法/规则
- 在花括号内部定义的局部变量,通常只在当前代码块内可见。
- 在函数外定义的全局变量,通常从定义位置开始到文件末尾可见。
- 内层代码块可以定义与外层同名的变量,这会发生遮蔽。
- 文件作用域名字如果不加
static,通常可以被其他源文件通过extern引用。 - 作用域和生命周期不是同一回事,局部
static变量就是典型例子。 - 块级变量的意义通常越局部越好,这样更不容易误用。
- 同名变量过多会显著降低可读性,尤其是在嵌套代码块中。
示例
| |
输出结果:
| |
这里最外层的全局 value 被 main 里的局部 value 遮蔽,而局部 value 又被内部块里的同名变量再次遮蔽。
常见错误
- 忘记变量遮蔽,误以为当前使用的是外层变量。
- 在代码块外访问块内变量,结果直接编译报错。
- 把“能访问到”误解成“生命周期还在”,忽略了对象实际已经失效的问题。
- 在多个层级重复使用相同变量名,导致阅读和调试都变得困难。
- 用全局变量解决本可以通过参数传递解决的问题,扩大了名字的可见范围和耦合面。