《编写高质量代码:改善c程序代码的125个建议》——建议9:尽量不要在可重入函数中使用静态(或全局)变量

简介:

本节书摘来自华章计算机《编写高质量代码:改善c程序代码的125个建议》一书中的第1章,建议9,作者:马 伟 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

建议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所示。


05a3f58a98150cf7fa1e27bd33b9b459b36c7b44

由于全局变量与静态变量一样,都是静态存储方式,因此,它同样可以导致不可重入函数,如下面的代码所示:

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;
}
相关文章
下一篇
无影云桌面