C語言C++語言中靜態變數和靜態函數

來源:互聯網
上載者:User

 

c語言中需要記憶體來存放資料。而記憶體主要分為兩類:靜態儲存區和動態儲存裝置區;

 

1.靜態儲存區分為:唯讀資料(READONLY  DATA)區、以讀寫資料(RW DATA)區、未初始化區(BSS)。它們都是在程式編譯串連階段確定的,在程式執行的階段不會改變。

 

2.動態儲存裝置區分為堆和棧。都是程式執行的過程中動態分配的,大小也隨之動態變化。從記憶體管理的實現的角度看來,堆使用的鏈表實現的,而棧使用的是線性儲存的方法。

 

:棧是先進後出,實際的操作中,棧記憶體可以有滿棧和空棧的情況,滿棧的情況下,棧指標當前的位子是已經使用的的棧地區;空棧的情況是,棧指標當前的位子是沒有使用的棧地區,所以兩種情況的出入棧,指標和資料的操作先後順序是不同的。
滿棧時:入棧,是先移動指標,在放入資料;出棧則是先出資料,在移動指標;
空棧時:入棧,是先放入資料,在移動指標。出棧則是先移動指標,在出資料;

 

C語言必須注意的幾個問題:
1.記憶體泄露:申請一塊記憶體,但沒有釋放,程式結束也沒回收,導致其他程式不能使用
2.野指標:指一個記憶體指標已經被釋放free或者realloc,但指標依然在使用。避免野指標的情況,將記憶體的指標置為NULL,並在程式使用的時候判斷該記憶體是否為NULL,如為空白,則認為該記憶體已經釋放,不對記憶體進行訪問。
3.非法釋放記憶體:原則上講只有被malloc(),calloc()或realloc()分配並通過傳回值返回返回的記憶體才能被釋放,否則釋放除此以外的記憶體都是非法的。即使有一個指標是*p是malloc,那麼對p1=p++,這個時候free(p1)也是不合法的,但free(p)確實可以的。同樣釋放函數中的局部變數也是非法的.還有一種情況是,對一個堆記憶體釋放兩次也是錯誤的用法。因為free()函數是不能釋放未分配的堆記憶體。在程式使用free釋放記憶體之後,應該將指標置為NULL,free一個NULL地址是沒有問題的。

 

c中:

在介紹之前,先討論一下 堆,棧,自由儲存區,全域/靜態儲存區和常量儲存區
堆:用new分配,free釋放
自由儲存區:malloc分配,delete釋放
棧:編譯器管理的局部變數和函數參數等。
全域/靜態儲存區:儲存靜態變數和全域變數
字元常量區:常量儲存的記憶體
也就是說static修飾函數的僅有一個意思:就是告訴編譯器,我是一個內建函式,不要隨便的用我。

1.  static 變數

  靜態變數的類型 說明符是static。 靜態變數當然是屬於靜態儲存方式,但是屬於靜態儲存方式的量不一定就是靜態變數。 例如外部變數雖屬於靜態 儲存方式,但不一定是靜態變數,必須由 static加以定義後才能成為靜態外部變數,或稱靜態全域變數。

2. 靜態局部變數
  靜態局部變數屬於靜態儲存方式,它具有以下特點:
(1)靜態局部變數在函數內定義  它的生存期為整個來源程式,但是其範圍仍與自動變數相同,只能在定義該變數的函數內使用該變數。退出該函數後, 儘管該變數還繼續存在,但不能使用它。

(2)允許對構造類靜態局部量賦初值  例如數組,若未賦以初值,則由系統自動賦以0值。
(3)對基本類型的靜態局部變數若在說明時未賦以初值,則系統自動賦予0值。而對自動變數不賦初值,則其值是不定的。 根據靜態局部變數的特點, 可以 看出它是一種生存期為整個來源程式的量。雖然離開定義它的函數後不能使用,但如再次調用定義它的函數時,它又可繼續使用, 而且儲存了前次被調用後留下的 值。 因此,當多次調用一個函數且要求在調用之間保留某些變數的值時,可考慮採用靜態局部變數。雖然用全域變數也可以達到上述目的,但全域變數有時會造成 意外的副作用,因此仍以採用局部靜態變數為宜。

3.靜態全域變數
  全域變數(外部變數)的說明之前再冠以static 就構 成了靜態全域變數。全域變數本身就是靜態儲存方式, 靜態全域變數當然也是靜態儲存方式。 這兩者在儲存方式上並無不同。這兩者的區別雖在於非靜態全域 變數的範圍是整個來源程式, 當一個來源程式由多個源檔案組成時,非靜態全域變數在各個源檔案中都是有效。 而靜態全域變數則限制了其範圍, 即只在 定義該變數的源檔案內有效, 在同一來源程式的其它源檔案中不能使用它。由於靜態全域變數的範圍局限於一個源檔案內,只能為該源檔案內的函數公用, 因此 可以避免在其它源檔案中引起錯誤。從以上分析可以看出, 把局部變數改變為靜態變數後是改變了它的儲存方式即改變了它的生存期。把全域變數改變為靜態變數 後是改變了它的範圍, 限制了它的使用範圍。因此static 這個說明符在不同的地方所起的作用是不同的。

4. static 函數…..

內建函式和外部函數:當一個來源程式由多個源檔案組成時,C語言根據函數能否被其它源檔案中的函數調用,將函數分為內建函式和外部函數。

(1) 內建函式(又稱靜態函數)
  如果在一個源檔案中定義的函數,只能被本檔案中的函數調用,而不能被同一程式其它檔案中的函數調用,這種函數稱為內建函式。定義一個內建函式,只需在函數類型前再加一個“static”關鍵字即可,如下所示:
    static  函數類型  函數名(函數參數表)
      {……}
  關鍵字“static”,譯成中文就是“靜態”,所以內建函式又稱靜態函數。但此處“static”的含義不是指儲存方式,而是指對函數的範圍僅局限於本檔案。使用內建函式的好處是:不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它檔案中的函數同名,因為同名也沒有關係。

2 外部函數
  外部函數的定義:在定義函數時,如果沒有加關鍵字“static”,或冠以關鍵字“extern”,表示此函數是外部函數:
    [extern]  函數類型  函數名(函數參數表)
      {……}
調用外部函數時,需要對其進行說明:
[extern]  函數類型  函數名(參數類型表)[,函數名2(參數類型表2)……];

[案例]外部函數應用。
(1)檔案mainf.c
  main()
   {  extern void input(…),process(…),output(…);

    input(…);  process(…);  output(…);

    }

(2)檔案subf1.c
  ……
  extern  void input(……)                           /*定義外部函數*/
  {……}

(3)檔案subf2.c
  ……
  extern  void process(……)                     /*定義外部 函數*/
  {……}
(4)檔案subf3.c
  ……
  extern void output(……)                        /*定義外部函數*/
  {……}

C++中的靜態成員變數和靜態成員函數

  (1)類待用資料成員在編譯時間建立並初始化:在該類的任何對象建立之前就存在,不屬於任何對象,而非靜態類成員變數則是屬於對象所有的。類待用資料成員只有一個拷貝,為所有此類的對象所共用。特別需要注意的一點是:待用資料成員不能在類中初始化(對於常量靜態類變數有待考證,好像可以在類外或main()函數之前定義,初始化可以放在類中),一般在類外和main()函數之前初始化,預設時初始化為0。待用資料成員用來定義類的各個對象所公有的資料,比全域變數更安全。

  (2)類靜態成員函數屬於整個類,不屬於某個對象,由該類所有對象共用。靜態成員可定義為inline函數。一般情況下靜態成員函數用於訪問同一類中的待用資料成員或全域變數,而不訪問非靜態成員,如需訪問非靜態成員,需要將對象作為參數,通過對象名訪問該對象的非靜態成員。靜態成員函數也可以在類外定義,此時不可以用static修飾。靜態成員函數存在的原因是什麼呢?主要是在建立任何對象之前可用它來訪問待用資料成員,普通函數不能實現此功能。

  C++靜態成員和靜態成員函數的使用:靜態成員的調用格式:類名::待用資料成員名、對象名.待用資料成員名、對象指標->待用資料成員、對象引用.待用資料成員(但類中很少會出現公有資料成員,這段僅僅討論文法,未考慮實際運用中的資料封裝問題)。靜態成員函數的調用格式:類名::靜態成員函數名、對象名.靜態成員函數名、對象指標->靜態成員函數名、對象引用.待用資料成員。靜態成員函數沒有this指標,因它不與特定對象相聯絡,調用時推薦使用“類名::靜態成員函數名”格式。總結來說,在有對象的情況下,可以用調用普通類成員函數、普通成員變數的方式調用靜態成員函數和靜態成員變數。從這裡可以看出靜態成員變數和靜態成員函數的使用應該是在不建立任何對象的情況下調用它們。其應用可以參見設計模式中Singleton pattern。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.