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

2021-07-12 01:51:49 字數 4456 閱讀 3128

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()

(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。

所謂靜態儲存方式是指在程式執行期間分配固定的

儲存空間的方式

變數的儲存方式可分為:「靜態儲存」和「

動態儲存」兩種。

靜態儲存

變數通常是在變數定義時就分定

儲存單元並一直保持不變,直至整個程式結束。

全域性變數即屬於此類儲存方式。

動態儲存

變數是在程式執行過程中,使用它時才分配

儲存單元,使用完畢立即釋放。

典型的例子是函式的

形式引數,在函式定義時並不給行參分配

儲存單元,只是在函式被呼叫時,才予以分配,呼叫函式完畢立即釋放。

如果乙個函式被多次呼叫時,則反覆地分配、釋放

形參變數的 儲存單元。

靜態儲存

變數是一直存在的,而

動態儲存變數則時而存在時而消失。通常把由於

變數儲存方式不同而產生的特性稱為變數的生存期。

生存期表示了

變數存在的時間,生存期和

作用域時從時間和空間這兩個不同的角度來描述變數的特性,這兩者即有聯絡,又有區別。

乙個變數究竟屬於哪一種儲存方式,並不能僅從其

作用域來判斷,還應有明確的儲存型別說明。

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

c語言中需要記憶體來存放資料。而記憶體主要分為兩類 靜態儲存區和動態儲存區 1.靜態儲存區分為 唯讀資料 readonly data 區 以讀寫資料 rw data 區 未初始化區 bss 它們都是在程式編譯連線階段確定的,在程式執行的階段不會改變。2.動態儲存區分為堆和棧。都是程式執行的過程中動態...

c語言中靜態變數和靜態函式

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

c語言靜態變數和靜態函式

static c語言 c語言程式可以看成由一系列外部物件構成,這些外部物件可能是變數或函式。而內部變數是指定義在函式內部的函式引數及變數。外部變數定義在函式之外,因此可以在許多函式中使用。由於c語言不允許在乙個函式中定義其它函式,因此函式本身只能是 外部的 由於c語言 是以檔案為單位來組織的,在乙個...