void f() {
static int cnt = 0;
cnt++;
cout << cnt << " ";
}
int main() {
f(); f(); f();
return 0;
}
输出:1 2 3
static局部变量核心考点
static int cnt = 0;:只在第一次调用函数的时候初始化一次,后续调用不再执行cnt=0。- 变量不存栈上,存静态存储区;函数结束,cnt的值不会销毁,保留上次的值。
执行流程:
- 第1次
f():cnt初始化为0 → cnt++ → cnt=1,输出1 - 第2次
f():不再执行static初始化,沿用旧值1 → cnt++ → cnt=2,输出2 - 第3次
f():cnt=2 → cnt++ → cnt=3,输出3
对比普通局部变量(去掉static)
void f(){
int cnt=0;
cnt++;
cout<<cnt<<" ";
}
每次进入函数都重新赋值cnt=0,输出:1 1 1。
CSP高频坑
- static局部变量初始化仅一次,不是每次函数调用都初始化。
- 生命周期:整个程序运行期间;作用域依旧只在函数内部,外面不能直接访问cnt。
变式练习:
void g(){
static int a=10;
a+=2;
cout<<a<<" ";
}
int main(){
g();g();
}
输出?👉12 14。
扩展:static局部变量 vs 全局变量
生命周期一样,但作用域不一样,不完全等效!
//全局变量
int cnt = 0;
void f(){
cnt++;
cout<<cnt;
}
void f(){
static int cnt=0;
cnt++;
cout<<cnt;
}
✔相同点
- 都放在静态存储区,不是栈;程序启动分配内存,程序结束才释放。
- 初始化只做一次。
- 函数调用结束,变量值保留,不会被销毁。
❗关键区别(CSP必考点)
1. 作用域(可见范围)
- static局部变量:仅函数内部可以访问,函数外面
main不能直接写cnt;外面看不见。
void f(){
static int cnt=0;
}
int main(){
cnt = 100; //编译报错!main看不见f里面的static cnt
}
- 全局变量:整个文件所有函数都可以直接访问。
int cnt=0;
void f(){}
int main(){
cnt=100; //合法,随便改
}
2. 初始化时机
- 全局变量:main执行之前就完成初始化。
- static局部变量:第一次调用这个函数的时候,才初始化。
void f(){
static int x=100; //第一次跑到f()才执行x=100
}
如果程序从头到尾没有调用f(),这个x永远不会初始化。
全局变量,不管函数跑不跑,main之前就初始化完毕。
3. 名字冲突
static局部变量名字只在函数内有效,别的函数可以再定义同名static变量,互不干扰。 全局变量整个文件不能重名。
一句话总结
生命周期等价,但是作用域不等价。static局部变量相当于“藏在函数里面的全局变量”,外面访问不到。
做题小坑
阅读程序看到static int x=0;写在函数里面:
- 值会跨调用保留;
- 但是别的函数不能直接用这个x。
变式
void A(){
static int t=1; t++; cout<<t;
}
void B(){
static int t=100;t++;cout<<t;
}
int main(){
A();A();B();
}
输出:2 3 101,两个t互不干扰。

