- 编写高质量代码:改善C程序代码的125个建议
- 马伟 著
- 765字
- 2025-03-16 17:14:06
建议9:尽量不要在可重入函数中使用静态(或全局)变量
前面介绍过,静态变量的存储方式与全局变量一样,都是静态存储方式。因此,在使用全局变量、静态变量的函数时,需要考虑重入问题。所谓的可重入函数是指函数可以由多于一个的任务并发使用,而不必担心数据错误。反之,不可重入函数不能由超过一个的任务所共享,除非能够确保函数的互斥性(或者使用信号量,或者在代码的关键部分禁用中断)。
来看一个不可重入函数的示例,代码如下所示:
size_t sum_index( size_t index ) { size_t i; static size_t sum=0; for (i = 1; i <= index; i++) { sum += i; } return sum; }
上面的sum_index函数之所以是不可重入的,就是因为函数中使用了static变量。前面已经阐述过,静态局部变量是在编译时赋初值的,且只赋初值一次,在程序运行时它已有初值。以后在每次调用函数时不再重新赋初值,而是保留上次函数调用结束时的值。所以,这样的函数又被称为带“内部存储器”功能的函数。
函数sum_index的调用示例如下:
int main(void) { printf("%d\n",sum_index(1)); printf("%d\n",sum_index(2)); printf("%d\n",sum_index(3)); }
运行结果如图1-44所示。

图1-44 调用sum_index函数的运行结果
由于全局变量与静态变量一样,都是静态存储方式,因此,它同样可以导致不可重入函数,如下面的代码所示:
size_t g_sum = 0; size_t sum_index( size_t index ) { size_t i; for (i = 1; i <= index; i++) { g_sum += i; } return g_sum; }
因此,如果需要一个可重入的函数,那么一定要尽量避免使用static变量与全局变量,能不用则尽量不用。当然,有些时候在函数中是必须使用static变量的,比如当某函数的返回值为指针类型时,则必须以static局部变量的地址为返回值,若为auto类型,则返回为错指针。
如果我们需要将上面的函数修改为可重入的函数,其实也很简单,只要将声明sum变量中的static关键字去掉,将变量sum变为一个auto类型的变量,函数即可变为一个可重入的函数。如下面的代码所示:
size_t sum_index( size_t index ) { size_t i; size_t sum=0; for (i = 1; i <= index; i++) { sum += i; } return sum; }