C语言函数内静态类型声明代码是否仅读取执行一次?
问题解答
关于静态变量声明的执行逻辑
你给出的fun()函数代码如下:
int fun(int n){ static int a = 4; return (a+=n); }
结论很明确:第二次及之后调用fun()时,确实不会执行第2行的静态变量声明初始化逻辑,直接进入第3行的计算返回流程。
要理解这个点得先搞清楚C语言静态局部变量的实现规则:
- 静态局部变量的内存分配、初始化操作是程序启动阶段就一次性完成的,存储在静态存储区,生命周期贯穿整个程序运行全程,和函数调用多少次没有关系。
- 编译器生成函数的汇编指令时,根本不会给第2行的静态变量声明初始化生成每次调用都要执行的运行时代码——不管是第几次调用,进入函数后直接就走后面的可执行逻辑。哪怕是第一次调用,也不存在“执行到第2行才给a赋值4”的过程,程序刚跑起来的时候这个a就已经是4了,第2行的作用只是告诉编译器“这个a是fun函数私有的静态变量,名字叫a,初始值4,除了fun内部其他代码不能碰”。
关于和全局变量实现的等价性
你给出的全局变量版本fun2()代码如下:
int a = 4; int fun2(int n){ return(a+=n); }
两个版本单次/多次调用的数值计算结果是完全一致的,但二者并不完全等价,核心差异在变量的作用域和访问权限:
fun()里的静态局部变量a,作用域被严格限制在fun()函数内部,函数外的任何代码都无法直接访问、修改这个变量,也不会和其他位置定义的同名变量产生命名冲突,封装性更好。fun2()里的a是全局变量,作用域覆盖整个编译单元,甚至可以被其他编译单元通过extern声明访问,程序里任意位置的代码都能直接读写这个a的值,很容易被意外修改,也容易和其他同名全局变量触发重定义报错。
举个最直观的区别:如果在函数外写一句a = 0;,在fun2版本里这行代码合法,会直接把用于计算的a改成0,后续所有fun2的调用结果都会被影响;但在fun版本里,这行代码要么因为找不到变量a直接编译报错,要么操作的是另一个完全独立的同名变量,根本碰不到fun内部存的那个a。
内容的提问来源于stack exchange,提问作者Elrisas
相关产品推荐
相关产品推荐

