- 編寫高質量代碼:改善C程序代碼的125個建議
- 馬偉 著
- 765字
- 2019-01-01 01:33:15
建議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; }
推薦閱讀
- Mastering RabbitMQ
- DevOps for Networking
- 摩登創客:與智能手機和平板電腦共舞
- Debian 7:System Administration Best Practices
- Java持續交付
- PHP+MySQL+Dreamweaver動態網站開發實例教程
- 3D少兒游戲編程(原書第2版)
- AutoCAD VBA參數化繪圖程序開發與實戰編碼
- Android應用案例開發大全(第二版)
- Python語言科研繪圖與學術圖表繪制從入門到精通
- Getting Started with the Lazarus IDE
- Learning Dynamics NAV Patterns
- Mastering Machine Learning with scikit-learn
- Java Web 從入門到項目實踐(超值版)
- Learning Yeoman