2.4 存储类

本篇学习 `auto`、`static`、`extern`、`register` 的含义,并能区分存储期、作用域和链接属性。

存储类

概念说明

存储类描述的是变量或函数在程序中的存储位置、生命周期和可见范围。 它解决的不是“变量是什么类型”,而是“这个名字能活多久、在哪些地方能被看到、是不是能跨文件访问”。

学这一节时,最容易混淆的是三件事:

  • 作用域:名字在哪些代码位置可见。
  • 存储期:对象从什么时候创建,到什么时候销毁。
  • 链接属性:同一个名字能否在多个源文件之间共享。

staticextern 容易让人一开始就绕晕,原因也在这里。 static 更强调存储期或内部链接,extern 更强调“定义在别处,我这里只引用它”。

语法/规则

  1. 普通局部变量默认具有自动存储期,函数调用结束后通常就失效。
  2. static 局部变量只初始化一次,函数多次调用时会保留上一次的值。
  3. static 用在文件作用域变量或函数前,通常表示仅在当前源文件内部可见。
  4. extern 用于声明一个在其他文件或其他位置定义的全局对象。
  5. register 表示建议编译器优先使用寄存器保存变量,但现代编译器通常会自己决定优化方式。
  6. 存储类不会改变变量的基本数据类型,但会影响初始化时机、生命周期和可见范围。
  7. 同一个名字是否能跨文件共享,不只看作用域,还要看链接属性。

示例

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

void visit(void) {
    static int count = 0;
    count++;
    printf("count = %d\n", count);
}

int main(void) {
    visit();
    visit();
    visit();
    return 0;
}

输出结果:

1
2
3
count = 1
count = 2
count = 3

这里的 count 虽然写在函数内部,但它不是每次进入 visit 时都重新创建。 这正是 static 局部变量和普通局部变量最关键的区别。

常见错误

  1. 以为 static 局部变量会在每次进入函数时重新初始化。
  2. 只写了 extern 声明,却没有真正提供对应的定义。
  3. 把生命周期、作用域和链接属性混成同一件事,导致全局变量设计混乱。
  4. 把本该只在当前文件使用的名字暴露成外部可见,增加不必要的耦合。
  5. 误以为 register 一定会带来性能提升,忽略现代编译器本来就会自动优化。
本文禁止转载
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
最近构建时间:2026-04-17 19:07:48 CST
载入天数...载入时分秒...
发表了 1 篇文章 · 发表了 152 篇笔记 · 总计 18 万 0 千字