static

【題目】static有什麼用途?

 

在網上流傳很廣的一個答案是:

1、限制變量的作用域

2、設置變量的存儲域

    我覺得這樣答題是不妥當的,有點文不對題的感覺。

 

下面是我給出的答案:

static 類型聲明符在C語言裏面主要有三個用途:

1、聲明靜態局部變量。

2、聲明靜態外部全局變量。

3、聲明靜態外部函數。

 

下面是我整理的有關上面三個用法的解釋說明。另外網友xiaocai0001的《static用法小結》一文有更詳細的解釋,請參考。

http://blog.csdn.net/xiaocai0001/archive/2006/04/14/662921.aspx

靜態局部變量(與auto對比)

1、  存儲空間分配、作用域和生存期

static分配在靜態存儲區,作用域僅僅限於聲明該變量的函數內部。在程序

整個運行期間都不釋放,生存期貫穿於程序運行的整個過程。

auto類型分配在棧上,屬於動態存儲類別,佔動態存儲區空間,作用域僅僅限於聲明該變量的函數內部。函數調用結束後自動釋放,生存期不過是在聲明該變量的函數內部。

2、賦初值時的處理方式

static靜態局部變量在編譯時賦初值,即只賦初值一次;

auto自動變量賦初值是在函數調用時進行,每調用一次函數重新給一次初值,相當於執行一次賦值語句。

3、未賦初值時的處理方式

如果在定義局部變量時不賦初值的話:

static靜態局部變量,編譯時自動賦初值0(對數值型變量)或空字符(對字符變量)。

auto自動變量,如果不賦初值則它的值是一個不確定的值。

 

靜態外部全局變量

在C語言中static還用來聲明靜態外部全局變量,那麼這個全局變量的作用域就被限制在本文件內部。

外部變量(即全局變量)是在函數的外部定義的,它的作用域爲從變量定義處開始,到本程序文件的末尾。如果外部變量不在文件的開頭定義,其有效的作用範圍只限於定義處到文件終了。如果在定義點之前的函數想引用該外部變量,則應該在引用之前用關鍵字extern對該變量作“外部變量聲明”。表示該變量是一個已經定義的外部變量。有了此聲明,就可以從“聲明”處起,合法地使用該外部變量。

而如果我們聲明的全局變量不想被其他文件訪問和使用又該怎麼辦?

那就是在聲明的時候前面加上關鍵字static。



靜態外部函數

 

在C語言中我們的函數默認都是全局的,也就是說你可以調用其他文件中的函數。在使用的時候,我們象前面一樣在頭文件中加上extern就可以了。但是有時候我們寫的函數並不想讓別的文件訪問和調用,那麼我們在聲明函數的時候前面加上static就可以了。

使用內部函數的好處有二:

1、可以讓某些內部函數不爲人所能使用,而僅僅讓調用者使用他能使用的東西,有利於保護代碼。

2、不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它文件中的函數同名。


4. 用static聲明的函數和變量小結

static 聲明的變量在C語言中有兩方面的特徵:


  1)、變量會被放在程序的全局存儲區中,這樣可以在下一次調用的時候還可以保持原來的賦值。這一點是它與堆棧變量和堆變量的區別。
  2)、變量用static告知編譯器,自己僅僅在變量的作用範圍內可見。這一點是它與全局變量的區別。


Tips:
  A.若全局變量僅在單個C文件中訪問,則可以將這個變量修改爲靜態全局變量,以降低模塊間的耦合度;
  B.若全局變量僅由單個函數訪問,則可以將這個變量改爲該函數的靜態局部變量,以降低模塊間的耦合度;
  C.設計和使用訪問動態全局變量、靜態全局變量、靜態局部變量的函數時,需要考慮重入問題;
    D.
如果我們需要一個可重入的函數,那麼,我們一定要避免函數中使用static變量(這樣的函數被稱爲:帶內部存儲器功能的的函數)
      E.
函數中必須要使用static變量情況:比如當某函數的返回值爲指針類型時,則必須是static的局部變量的地址作爲返回值,若爲auto類型,則返回爲錯指針。

    函數前加static使得函數成爲靜態函數。但此處“static”的含義不是指存儲方式,而是指對函數的作用域僅侷限於本文件(所以又稱內部函數)。使用內部函數的好處是:不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它文件中的函數同名。

擴展分析:

      術語static有着不尋常的歷史.起初,在C中引入關鍵字static是爲了表示退出一個塊後仍然存在的局部變量。隨後,staticC中有了第二種含義:用來表示不能被其它文件訪問的全局變量和函數。爲了避免引入新的關鍵字,所以仍使用static關鍵字來表示這第二種含義。最後,C++重用了這個關鍵字,並賦予它與前面不同的第三種含義:表示屬於一個類而不是屬於此類的任何特定對象的變量和函數(Java中此關鍵字的含義相同)

全局變量、靜態全局變量、靜態局部變量和局部變量的區別

變量可以分爲:全局變量、靜態全局變量、靜態局部變量和局部變量。


          存儲區域分,全局變量、靜態全局變量和靜態局部變量都存放在內存的靜態存儲區域,局部變量存放在內存的棧區
         
作用域分,  全局變量在整個工程文件內都有效;靜態全局變量只在定義它的文件內有效;靜態局部變量只在定義它的函數內有效,只是程序僅分配一次內存,函數返回後,該變量不會消失;局部變量在定義它的函數內有效,但是函數返回後失效

    全局變量(外部變量)的說明之前再冠以static 就構成了靜態的全局變量。全局變量本身就是靜態存儲方式, 靜態全局變量當然也是靜態存儲方式。 這兩者在存儲方式上並無不同。這兩者的區別雖在於非靜態全局變量的作用域是整個源程序, 當一個源程序由多個源文件組成時,非靜態的全局變量在各個源文件中都是有效的。 而靜態全局變量則限制了其作用域, 即只在定義該變量的源文件內有效, 在同一源程序的其它源文件中不能使用它。由於靜態全局變量的作用域侷限於一個源文件內,只能爲該源文件內的函數公用, 因此可以避免在其它源文件中引起錯誤。

  從以上分析可以看出, 把局部變量改變爲靜態變量後是改變了它的存儲方式即改變了它的生存期。把全局變量改變爲靜態變量後是改變了它的作用域 限制了它的使用範圍。

  static 函數與普通函數作用域不同。僅在本文件。只在當前源文件中使用的函數應該說明爲內部函數(static),內部函數應該在當前源文件中說明和定義。對於可在當前源文件以外使用的函數,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件

  static全局變量與普通的全局變量有什麼區別:static全局變量只初始化一次,防止在其他文件單元中被引用;
  static局部變量和普通局部變量有什麼區別:static局部變量只被初始化一次,下一次依據上一次結果值;

    static
函數與普通函數有什麼區別:static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝
    
全局變量和靜態變量如果沒有手工初始化,則由編譯器初始化爲0。局部變量的值不可知。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章