3.4 作用域规则

本篇学习块作用域、文件作用域、变量遮蔽与生命周期差异,并能判断一个名字在什么位置可见。

作用域规则

概念说明

作用域决定了一个名字在程序的哪些位置可以被访问。 在 C 语言里,常见的作用域包括块作用域和文件作用域,不同位置定义的变量可见范围不同。

作用域只回答“这里能不能访问这个名字”,并不等于“对象现在还活着”。 比如局部 static 变量的生命周期覆盖整个程序运行过程,但它的名字仍然只在局部块中可见。

如果内层代码定义了和外层同名的变量,内层名字会暂时遮蔽外层名字。 这类问题编译通常不会报错,但很容易让程序行为和预期不一致。

语法/规则

  1. 在花括号内部定义的局部变量,通常只在当前代码块内可见。
  2. 在函数外定义的全局变量,通常从定义位置开始到文件末尾可见。
  3. 内层代码块可以定义与外层同名的变量,这会发生遮蔽。
  4. 文件作用域名字如果不加 static,通常可以被其他源文件通过 extern 引用。
  5. 作用域和生命周期不是同一回事,局部 static 变量就是典型例子。
  6. 块级变量的意义通常越局部越好,这样更不容易误用。
  7. 同名变量过多会显著降低可读性,尤其是在嵌套代码块中。

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <stdio.h>

int value = 100;

int main(void) {
    int value = 10;

    printf("inner value = %d\n", value);
    {
        int value = 1;
        printf("block value = %d\n", value);
    }

    return 0;
}

输出结果:

1
2
inner value = 10
block value = 1

这里最外层的全局 valuemain 里的局部 value 遮蔽,而局部 value 又被内部块里的同名变量再次遮蔽。

常见错误

  1. 忘记变量遮蔽,误以为当前使用的是外层变量。
  2. 在代码块外访问块内变量,结果直接编译报错。
  3. 把“能访问到”误解成“生命周期还在”,忽略了对象实际已经失效的问题。
  4. 在多个层级重复使用相同变量名,导致阅读和调试都变得困难。
  5. 用全局变量解决本可以通过参数传递解决的问题,扩大了名字的可见范围和耦合面。
本文禁止转载
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
最近构建时间:2026-04-17 19:07:48 CST
载入天数...载入时分秒...
发表了 1 篇文章 · 发表了 152 篇笔记 · 总计 18 万 0 千字