官术网_书友最值得收藏!

建議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;
}

主站蜘蛛池模板: 昭平县| 信丰县| 卢湾区| 衢州市| 阜新市| 金湖县| 阿拉尔市| 焦作市| 襄垣县| 大足县| 苗栗市| 浦城县| 重庆市| 土默特右旗| 日喀则市| 吉林市| 台山市| 正阳县| 佛山市| 建阳市| 河北省| 闽清县| 枣庄市| 河源市| 邹平县| 巩义市| 乌什县| 阿荣旗| 平阴县| 肥城市| 淮南市| 瓦房店市| 禄劝| 徐汇区| 门源| 邻水| 崇明县| 夏河县| 牡丹江市| 蒲城县| 苍山县|