1、概述
static 聲明的變數在c語言中有兩方面的特徵:
1)、變數會被放在程式的全域儲存區中,這樣可以在下一次調用的時候還可以保持原來的賦值。這一點是它與堆棧變數和堆變數的區別。
2)、變數用static告知編譯器,自己僅僅在變數的作用範圍內可見。這一點是它與全域變數的區別。
2、問題:static的理解
關於static變數,請選擇下面所有說法正確的內容:
a、若全域變數僅在單個c檔案中訪問,則可以將這個變數修改為靜態全域變數,以降低模組間的耦合度;
b、若全域變數僅由單個函數訪問,則可以將這個變數改為該函數的靜態局部變數,以降低模組間的耦合度;
c、設計和使用訪問動態全域變數、靜態全域變數、靜態局部變數的函數時,需要考慮重入問題;
d、靜態全域變數過大,可那會導致堆疊溢位。
答案與分析:
對於a,b:根據本篇概述部分的說明b),我們知道,a,b都是正確的。
對於c:根據本篇概述部分的說明a),我們知道,c是正確的(所謂的函數重入問題,下面會詳細闡述)。
對於d:靜態變數放在程式的全域資料區,而不是在堆棧中分配,所以不可能導致堆疊溢位,d是錯誤的。
因此,答案是a、b、c。
3、問題:不可重新進入函數
曾經設計過如下一個函數,在代碼檢視的時候被提醒有bug,因為這個函數是不可重新進入的,為什嗎?
unsigned int sum_int( unsigned int base )
{
unsigned int index;
static unsigned int sum = 0; // 注意,是static類型的。
for (index = 1; index <= base; index++)
{
sum += index;
}
return sum;
}
答案與分析:
所謂的函數是可重新進入的(也可以說是可預測的),即:只要輸入資料相同就應產生相同的輸出。
這個函數之所以是不可預測的,就是因為函數中使用了static變數,因為static變數的特徵,這樣的函數被稱為:帶“內部儲存空間”功能的的函數。因此如果我們需要一個可重新進入的函數,那麼,我們一定要避免函數中使用static變數,這種函數中的static變數,使用原則是,能不用盡量不用。
將上面的函數修改為可重新進入的函數很簡單,只要將聲明sum變數中的static關鍵字去掉,變數sum即變為一個auto 類型的變數,函數即變為一個可重新進入的函數。
當然,有些時候,在函數中是必須要使用static變數的,比如當某函數的傳回值為指標類型時,則必須是static的局部變數的地址作為傳回值,若為auto類型,則返回為錯指標。