静态变量

静态变量

一、背景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
int square(int i);
void main(){
int i=0;
i=square(i);
for(;i<3;i++){
static int i=1;
i+=square(i);
printf("%d,",i);
}
printf("%d\n",i);
}

int square(int i){
return i*i;
}

输出:

1
2, 6, 42, 3
  1. main函数初始化:

    • int i=0; → 主函数中的 i 初始值为0。
    • i = square(i); → 调用 square(0) ,返回 0*0=0 ,主函数的 i 仍为0。
  2. for循环执行(循环条件: i<3 ,主函数的 i 初始为0):

    • 第一次循环(主函数 i=0 ):
      • 定义 static int i=1; (静态变量,仅初始化一次)。
      • i += square(i); → i = 1 + square(1) = 1 + 1 = 2 。
      • 输出 2 。
      • 主函数的 i 自增为1。
    • 第二次循环(主函数 i=1 ):
      • 判断 i<3 (1<3,成立)→ 执行循环体。
      • 静态变量 i 已存在,直接使用当前值2。
      • i += square(i); → i = 2 + square(2) = 2 + 4 = 6 。
      • 输出 6, 。
      • 主函数的 i 自增为2。
    • 第三次循环(主函数 i=2 ):
      • 判断 i<3 (2<3,成立)→ 执行循环体。
      • 静态变量 i 当前值为6 。
      • i += square(i); → i = 6 + square(6) = 6 + 36 = 42
      • 输出 42 。
      • 主函数的 i 自增为3。
    • 判断 i<3 (3=3,不成立)→ 循环结束。
  3. 循环结束后:

    • 最终输出主函数的 i 为3。

关键:

  • 静态变量(static):在函数/代码块内定义时,仅初始化一次,生命周期贯穿整个程序。
  • 变量作用域:for循环内的 static int i 与主函数的 i 是不同变量,互不影响。

二、静态变量知识点:

两类静态变量的具体使用格式与场景

1. 局部静态变量(函数内 / 代码块内)

  • 格式:在函数体或代码块(如 forif 块)内部声明,添加 static

  • 核心特点:仅在声明的函数 / 代码块内可见,但生命周期与程序一致(函数调用结束后不销毁,值保留)。

  • 示例

    1
    2
    3
    4
    5
    6
    for(;i<3;i++)
    {
    static int i=1; // 局部静态变量:仅在该for循环块内可见
    i+=square(i);
    printf("%d,",i);
    }

    这里的

    1
    static int i=1

    就是典型的局部静态变量:

    • 首次进入循环块时初始化(仅初始化 1 次,后续循环不再重新初始化);
    • 每次循环后值保留,下次进入块时直接使用上次的结果。

2. 全局静态变量(函数外 / 文件级)

  • 格式:在所有函数外部声明,添加 static

  • 核心特点:生命周期与程序一致,但作用域仅限于当前 .c 文件(其他文件无法通过 extern 引用)。

  • 示例

    1
    2
    3
    4
    5
    6
    7
    // 文件 a.c
    static int g_static = 10; // 全局静态变量:仅在 a.c 中可见

    void test() {
    g_static++; // 函数内可访问和修改
    printf("%d", g_static);
    }

    若在另一个文件b.c

    中用

    1
    extern int g_static;

    尝试引用,会编译报错(未定义标识符)。

关键注意事项

  1. 初始化规则

    • 静态变量只能用「常量表达式」初始化(不能用变量、函数返回值等动态值);
    • 未显式初始化时,系统自动初始化为 0(普通局部变量未初始化时是随机垃圾值)。
    • 错误示例:int x=5; static int s=x;(x 是变量,不能初始化静态变量)。
  2. 作用域与生命周期区分

    变量类型 作用域(可见范围) 生命周期(存在时间)
    局部静态变量 函数 / 代码块内 程序运行期间(全程存在)
    全局静态变量 当前 .c 文件内 程序运行期间(全程存在)
    普通局部变量 函数 / 代码块内 函数调用期间(调用结束销毁)
    普通全局变量 所有文件(需 extern 声明) 程序运行期间(全程存在)

三、全局变量和全局静态变量的区别?

只写 1 个.c 文件时,两者几乎没区别

如果程序只在一个.c文件里写(就像你给出的代码那样,所有代码都在一个文件里),不管是写int g_var = 10;(全局变量)还是static int g_static_var = 10;(全局静态变量),用法完全一样:

  • 都能在文件里的任何函数(比如mainsquare)里用、修改;
  • 程序一启动就存在,直到程序结束才消失(不会像函数里的普通变量那样用完就没);
  • 没手动赋值的话,默认都是 0。

关键区别:当写多个.c 文件时(实际编程常用)

实际写程序时,经常会把代码分成多个.c文件(比如一个存函数,一个存主逻辑),这时候两者的区别就出来了 ——能不能 “跨文件共享”“重名会不会打架”

1. 全局变量:能跨文件共享,但容易 “重名打架”

比如有两个文件a.cb.c

  • a.c里写:int g_num = 10;(全局变量)
  • 想在b.c里用这个g_num,直接写就能用(加一句简单声明),还能修改它的值,两边的g_num是同一个东西。

但如果b.c里也自己写一个int g_num = 20;(同名全局变量),程序运行时会报错,说 “重复定义了 g_num”—— 相当于两个文件抢同一个名字,打架了。

2. 全局静态变量:不能跨文件共享,但不会 “重名打架”

还是两个文件a.cb.c

  • a.c里写:static int g_static_num = 10;(全局静态变量)
  • 想在b.c里用这个g_static_num,根本用不了,程序会说 “找不到这个变量”—— 它就像a.c的 “私有变量”,只给a.c自己用。

但如果b.c里也写static int g_static_num = 20;(同名全局静态变量),完全没问题!因为两个g_static_num是 “各自文件的私有财产”,互不干扰,a.c里的还是 10,b.c里的还是 20,不会打架。

总结:用 “大白话” 记区别

特性(只记这 2 点就行) 全局变量 全局静态变量
能不能给其他文件用? 能(共享) 不能(私有)
不同文件重名会怎样? 报错(打架) 没事(互不干扰)
  • 如果你只写一个.c文件,两者用着没区别;
  • 以后写多个文件时,想让变量给其他文件用,就用全局变量;想让变量只在自己文件里用、不跟别人重名,就用全局静态变量。

静态变量
http://example.com/2025/11/29/静态变量/
作者
王柏森
发布于
2025年11月29日
许可协议