静态变量
静态变量
一、背景
1 | |
输出:
1 | |
main函数初始化:
- int i=0; → 主函数中的 i 初始值为0。
- i = square(i); → 调用 square(0) ,返回 0*0=0 ,主函数的 i 仍为0。
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,不成立)→ 循环结束。
- 第一次循环(主函数 i=0 ):
循环结束后:
- 最终输出主函数的 i 为3。
关键:
- 静态变量(static):在函数/代码块内定义时,仅初始化一次,生命周期贯穿整个程序。
- 变量作用域:for循环内的 static int i 与主函数的 i 是不同变量,互不影响。
二、静态变量知识点:
两类静态变量的具体使用格式与场景
1. 局部静态变量(函数内 / 代码块内)
格式:在函数体或代码块(如
for、if块)内部声明,添加static。核心特点:仅在声明的函数 / 代码块内可见,但生命周期与程序一致(函数调用结束后不销毁,值保留)。
示例:
1
2
3
4
5
6for(;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;尝试引用,会编译报错(未定义标识符)。
关键注意事项
初始化规则:
- 静态变量只能用「常量表达式」初始化(不能用变量、函数返回值等动态值);
- 未显式初始化时,系统自动初始化为 0(普通局部变量未初始化时是随机垃圾值)。
- 错误示例:
int x=5; static int s=x;(x 是变量,不能初始化静态变量)。
作用域与生命周期区分:
变量类型 作用域(可见范围) 生命周期(存在时间) 局部静态变量 函数 / 代码块内 程序运行期间(全程存在) 全局静态变量 当前 .c 文件内 程序运行期间(全程存在) 普通局部变量 函数 / 代码块内 函数调用期间(调用结束销毁) 普通全局变量 所有文件(需 extern 声明) 程序运行期间(全程存在)
三、全局变量和全局静态变量的区别?
只写 1 个.c 文件时,两者几乎没区别
如果程序只在一个.c文件里写(就像你给出的代码那样,所有代码都在一个文件里),不管是写int g_var = 10;(全局变量)还是static int g_static_var = 10;(全局静态变量),用法完全一样:
- 都能在文件里的任何函数(比如
main、square)里用、修改; - 程序一启动就存在,直到程序结束才消失(不会像函数里的普通变量那样用完就没);
- 没手动赋值的话,默认都是 0。
关键区别:当写多个.c 文件时(实际编程常用)
实际写程序时,经常会把代码分成多个.c文件(比如一个存函数,一个存主逻辑),这时候两者的区别就出来了 ——能不能 “跨文件共享” 和 “重名会不会打架”:
1. 全局变量:能跨文件共享,但容易 “重名打架”
比如有两个文件a.c和b.c:
a.c里写:int g_num = 10;(全局变量)- 想在
b.c里用这个g_num,直接写就能用(加一句简单声明),还能修改它的值,两边的g_num是同一个东西。
但如果b.c里也自己写一个int g_num = 20;(同名全局变量),程序运行时会报错,说 “重复定义了 g_num”—— 相当于两个文件抢同一个名字,打架了。
2. 全局静态变量:不能跨文件共享,但不会 “重名打架”
还是两个文件a.c和b.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/静态变量/