【时时三省】(C语言基础)静态局部变量(static局部变量)
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省
有时希望函数中的局部变量的值在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,在下一次再调用该函数时,该变量已有值(就是上一次函数调用结束时的值)。这时就应该指定该局部变量为“静态局部变量”,用关键字static进行声明。通过下面简单的例子可以了解它的特点。
例题:
考察静态局部变量的值。
编写程序:
运行结果:
7 8 9
程序分析:
循环共执行 3 次,每次调用 f(2) (因 a=2 固定传入),核心变化在 b 和 c :
1. 第 1 次调用 f(2)
- b = 0 → b + 1 = 1 (重新初始化)
- c = 3 → c + 1 = 4 (首次自增)
- 返回值: 2(a) + 1(b) + 4(c) = 7 , printf 输出 7 。
2. 第 2 次调用 f(2)
- b = 0 → b + 1 = 1 (重新初始化)
- c = 4 → c + 1 = 5 (基于上次结果自增)
- 返回值: 2 + 1 + 5 = 8 , printf 输出 8 。
3. 第 3 次调用 f(2)
- b = 0 → b + 1 = 1 (重新初始化)
- c = 5 → c + 1 = 6 (基于上次结果自增)
- 返回值: 2 + 1 + 6 = 9 , printf 输出 9 。
关键结论
- auto 变量(如 b ):作用域局限于函数内,每次进入函数重新初始化,值不跨调用保留。
- static 变量(如 c ):虽作用域也在函数内,但存储在静态区,值会跨函数调用保留,是程序输出 7、8、9 递增的核心原因。
- 整体流程: main 循环调用 f , f 通过不同存储类型变量的特性,实现返回值逐次递增,最终输出 7、8、9 。
说明:
( 1 )静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,分配在动态存储区空间而不在静态存储区空间,函数调用结束后即释放。
( 2 )对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。而对自动变量赋初值,不是在编译时进行的,而是在函数调用时进行的,每调用一次函数重新给一次初值,相当于执行一次赋值语句。
( 3 )如果在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符\0 '(对字符变量)。而对自动变量来说,它的值是一个不确定的值。这是由于每次函数调用结束后存储单元已释放,下次调用时又重新另分配存储单元,而所分配的单元中的内容是不可知的。
( 4 )虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用它的。因为它是局部变量,只能被本函数引用,而不能被其他函数引用。
什么情况下需要用局部静态变量呢?需要保留函数上一次调用结束时的值时,例如可以用下面方法求n !。
例题2:
输出1到5的阶乘值。
解题思路:
可以编一个函数用来进行连乘,如第1次调用时进行1乘1,第2次调用时再乘以2,第3次调用时再乘以3,依此规律进行下去。
编写程序:
运行结果:
说明:
( 1 )每次调用fac ( i ),输出一个i !,同时保留这个i !的值以便下次再乘( i +1 )。
( 2 )如果函数中的变量只被引用而不改变值,则定义为静态局部变量(同时初始化)比较方便,以免每次调用时重新赋值。
但是应该看到,用静态存储要多占内存(长期占用不释放,而不能像动态存储那样一个存储单元可以先后为多个变量使用,节约内存),而且降低了程序的可读性,当调用次数多时往往弄不清静态局部变量的当前值是什么。因此,若非必要,不要多用静态局部变量。