關於C語言中的靜態函數


在C語言中用static聲明限定外部變量與函數,可以將其后聲明的對象的作用域限定為被編譯源文件的剩余部分。通過static限定外部對象,可以達到隱藏外部對象的目的。如果把函數聲明為static類型,則該函數名除了對該函數聲明所在的文件可見外,其他文件都無法訪問。也就是只能被本文件中的函數調用,而不能被同一程序中的其他文件的函數調用。

 

 C語言程序可以看成由一系列外部對象構成,這些外部對象可能是變量或函數。而內部變量是指定義在函數內部的函數參數及變量。外部變量定義在函數之外,因此可以在許多函數中使用。由於C語言不允許在一個函數中定義其它函數,因此函數本身只能是外部的

 

由於C語言代碼是以文件為單位來組織的,在一個源程序所有源文件中,一個外部變量或函數只能在某個文件中定義一次,而其它文件可以通過extern聲明來訪問它(定義外部變量或函數的源文件中也可以包含對該外部變量的extern聲明)。

 

static則可以限定變量或函數為靜態存儲。如果用static限定外部變量與函數,則可以將該對象的作用域限定為被編譯源文件的剩余部分。通過static限定外部對象,可以達到隱藏外部對象的目的。因而,static限定的變量或函數不會和同一程序中其它文件中同名的相沖突。如果用static限定內部變量,則該變量從程序一開始就擁有內存,不會隨其所在函數的調用和退出而分配和消失。

 

C語言中使用靜態函數的好處

1) 靜態函數會被自動分配在一個一直使用的存儲區,直到退出應用程序實例,避免了調用函數時壓棧出棧,速度快很多。

2) 關鍵字“static”,譯成中文就是“靜態的”,所以內部函數又稱靜態函數。但此處“static”的含義不是指存儲方式,而是指對函數的作用域僅局限於本文件。 使用內部函數的好處是:不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它文件中的函數同名,因為同名也沒有關系。

 

補充1static變量

 

C/C++中的變量根據作用域(知道該名字的程序文本區)和生命期(程序執行過程中對象存在的時間)分為全局變量、靜態全局變量、局部變量和靜態局部變量。

 

局部變量前面加關鍵字static進行聲明,該變量就是一個static局部變量。static局部變量的特點是它位於靜態存貯區,生命期為整個程序執行期間,在函數調用結束后,它的值仍然存在,並可能影響到下一次調用的過程。但它的作用域僅限於定義該變量的函數。

 

全局變量本身就是靜態存儲方式, 靜態全局變量當然也是靜態存儲方式。但是他們的作用域不同,非靜態全局變量的作用域是整個源程序(多個源文件可以共同使用); 而靜態全局變量則限制了其作用域, 即只在定義該變量的源文件內有效, 在同一源程序的其它源文件中不能使用它。

 

 

問題:Static的理解

  關於static變量,請選擇下面所有說法正確的內容:

  A、若全局變量僅在單個C文件中訪問,則可以將這個變量修改為靜態全局變量,以降低模塊間的耦合度;

  B、若全局變量僅由單個函數訪問,則可以將這個變量改為該函數的靜態局部變量,以降低模塊間的耦合度;

  C、設計和使用訪問動態全局變量、靜態全局變量、靜態局部變量的函數時,需要考慮重入問題;

  D、靜態全局變量過大,可那會導致堆棧溢出。

  答案與分析:

對於D:靜態變量放在程序的全局數據區,而不是在堆棧中分配,所以不可能導致堆棧溢出,D是錯誤的。

  因此,答案是A、B、C。

  問題:不可重入函數

  曾經設計過如下一個函數,在代碼檢視的時候被提醒有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類型,則返回為錯指針。

 

補充2C++  static成員

 

需要一個成員為整個類的全體對象而非某個對象服務。同時又力求不破壞類的封裝性,即要求此成員隱藏在類的內部,對外不可見,static成員可以是私有成員。每個static數據成員是與類關聯的對象,並不是與該類對象相關聯。

 

類的static成員的優點:

1)  static成員的名字是在類的作用域當中,因此可以避免與其他類的成員或全局對象的名字沖突。

2)  可以實施封裝。static成員可以是私有成員,而全局對象不行。

3)  通過閱讀程序容易看出,static成員是與特定類關聯的。這種可見性清晰地顯示程序員的意圖。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM