全域性變數和區域性變數詳解

2021-06-25 10:22:48 字數 3435 閱讀 4367

1.區域性變數

(1)區域性變數也稱為內部變數,他是在函式體內作定義說明的,其作用域僅限於函式內部,離開該函式後再使用這種變數是非法的。

如:func ()

(2)乙個函式可以為區域性變數定義任何名字,而不用擔心其他函式使用過同樣的名字。 

void main()

void func()    

**中兩個函式都包含乙個變數定義語句。在函式內定義的變數區域性於該函式。main()函式中有乙個變數n,func()函式中也有乙個變數n,但它們是兩個不同位置的變數。

乙個函式可以為區域性變數定義任何名字,而不用擔心其他函式使用過同樣的名字,這個特點和區域性變數的存在性使c++適合於由多個程式設計師共同參與的程式設計專案,專案管理員為程式設計師指定編寫函式的任務,並為程式提供引數和期望的返回值。然後,程式設計師著手編寫函式,而不用了解程式的其他部分和專案中其他程式設計師所使用的變數名。

(3)區域性變數沒有預設初始化。如果區域性變數不被顯式初始化,那麼,其內容是不可預料的。所以區域性變數必須要初始化。

#include

int func1();

int func2();

void main()

int func1()

int func2()

執行結果為:

12345

在func1()中,定義了區域性變數n,並給其初始化為12345。在func2()中,定義了區域性變數m,沒有初始化。 可是在將該變數值返回後,在主函式中輸出該值,卻發現為12345,恰好就是funcl()函式中初始化的值。這說明,func2()中,沒有顯式初始化的區域性變數m,c++也未給其預設初始化,其值保留為原記憶體位置的值。這是函式的調節機制造成的。

(4)區域性變數從儲存方式上可分為動態(auto)儲存型別和靜態(static)儲存型別。

動態儲存型別的區域性變數都是動態的分配儲存空間,資料儲存在動態儲存區(棧)中。函式呼叫結束後自動釋放,生存期是在宣告該變數的函式執行過程。

靜態儲存型別的區域性變數則是靜態的分配儲存空間,資料儲存在靜態儲存區中。在程式整個執行期間都不釋放,生存期貫穿於程式執行的整個過程。但是其他函式不能呼叫靜態區域性變數,當再次進入該函式時,將儲存上次的結果。

函式中的區域性變數,如不專門宣告為static儲存類別,預設都是動態地分配儲存空間的,我們在平時的宣告變數的過程中auto都是預設省略的。

2.全域性變數

(1)全域性變數也稱為外部變數,是在函式的外部定義的,它的作用域為從變數定義處開始,到本程式檔案的末尾。全域性變數全部存放在靜態儲存區,在程式開始執行時給全域性變數分配儲存區,程式行完畢就釋放。在程式執行過程中它們佔據固定的儲存單元,而不動態地進行分配和釋放。如果外部變數不在檔案的開頭定義,其有效作用域只限於定義處到檔案終。如果乙個函式修改了某個全域性變數,則所有其他的函式都會看到修改後的這個全域性變數

(2)全域性變數有預設的初始化。

對於全域性變數,如果在定義的時候不做初始化,則系統將自動為起賦值,數值型為0;字元型為空'/0'。

全域性變數的弊端,增加記憶體開銷,降低函式的通用性

(3)對全域性變數的引用。

定義全域性變數時理想的位置是在檔案的開頭,當這些函式以及同乙個程式中的其他源程式檔案中的某些函式需要使用該全域性變數時,在函式內部對該變數使用extern 加以說明 說明他是外部的 。

如果在定義點之前的函式想引用該外部變數,則應該在引用之前用關鍵字extern對該變數作「外部變數宣告」。表示該變數是乙個已經定義的外部變數。有了此宣告,就可以從「宣告」處起,合法地使用該外部變數。其有效作用域就被拓展到從這個檔案extern宣告處到檔案結束。

(4)對全域性變數的宣告和對全域性變數的定義的區別。

對外部變數的說明,只是宣告該變數是在外部定義過的乙個全域性變數在這裡引用 ;而對全域性變數的定義則是要對其分配儲存單元。乙個全域性變數只能定義一次,可是卻可以多次引用。

(5)static(靜態)全域性變數與普通的全域性變數的區別。

非靜態全域性變數的作用域是整個源程式,當乙個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是有效的。而靜態全域性變數則限制了其作用域,即只在定義該變數的原始檔內有效, 在同一源程式的其它原始檔中不能使用它。由於靜態全域性變數的作用域侷限於乙個原始檔內,只能為該原始檔內的函式公用,因此可以避免在其它原始檔中引起錯誤。

(6)區域性變數能和全域性變數重名,但是區域性變數會遮蔽全域性變數。在函式內引用這個變數時,會用到同名的區域性變數,而不會用到全域性變數。這對extern宣告的全域性變數也一樣。

順便梳理一下:

3.程式的記憶體區域

並不是所有的變數時時刻刻都是可知的。一些變數在整個程式中都是可見的,它們稱為全域性變數;一些變數只能在乙個函式中可知,稱為區域性變數。要了解變數的這些屬性,應先弄清程式在記憶體中的分布區域。

乙個程式將作業系統分配給其執行的記憶體塊分為4個區域:

(1)**區,存放程式的**,-----程式中的各個函式**塊。

(2)全域性資料區,存放程式的全域性資料和靜態資料。----全域性變數、靜態區域性變數

(3)堆區,存放程式的動態資料。-----動態申請的資料,如new出來的資料

(4)棧區,存放程式的區域性資料,即各個函式中的資料。------區域性變數

即:一般全域性變數存放在資料區,區域性變數存放在棧區,動態變數存放在堆區,函式**放在**區。 

4.靜態變數的特點:

(1)一次儲存:靜態區域性變數只被初始化一次,下一次初始化根據上一次的結果值,有點類似於c++中類的靜態成員變數,即無論該型別生成多少個例項物件,所有的物件共用乙個靜態變數,到這裡就是無論這個函式呼叫多少次,該靜態變數只初始化一次,並沒有因為超出其生存期而被銷毀,只是外部不可見而已,用個例子說明之:

void  fun1( int  v )

int main( int  arc, char  *args[ ])

執行的結果是:value :50  value : 50

說明在第二次呼叫fun1( )時的初始化value的採用的是上一次value的值,value在靜態區的儲存空間並沒有因為fun1( )的結束而被釋放,即體現了一次儲存;

(2)作用域限定:

靜態修飾的作用域限定,能同時體現在函式與變數上;

a)對於函式而言,任何用static修飾的函式,其作用域僅為當前原始檔,而對外部來說這個函式是不可見的,即只有和其在同一原始檔中的函式才能呼叫這個靜態函式;反過來說,如果乙個函式僅僅被同一原始檔中的其他函式呼叫,那麼這個函式應該宣告為靜態的,這樣做的好處在於:可以一定程度上的解決不同原始檔之間函式的命名衝突問題;

b)對於變數而言,static修飾的全域性變數,只在當前原始檔中有效,對外部不可見,外部檔案不能夠引用;靜態全域性變數的意義就是不讓「外部」引用,是單個原始檔裡的全域性變數,即是編譯階段的全域性變數,而不是連線階段的全域性變數。

通過上面的分析,我們不難得出以下結論:

1、靜態函式與普通函式的區別在於:靜態函式不可以被同一原始檔以外的函式呼叫。

2、靜態區域性變數與普通區域性變數的區別在於:靜態區域性變數只初始化一次,下一次初始化實際上是依然是上一次的變數;

3、靜態全域性變數與普通全域性變數的區別在於:靜態全域性變數的作用域僅限於所在的原始檔。

全域性變數和區域性變數

全域性變數 可以被不同的函式 類或檔案呼叫的變數,在函式外定義。區域性變數 只能在函式內使用,定義在函式內。區域性變數的使用 class myclass def myfun num 12 print myfun num num 正確 def myfun2 num num 1 print mufun ...

全域性變數和區域性變數

區域性變數 在方法中開闢的變數,只在方法中有效 區域性變數在定義時不會初始化,要顯式的給它乙個值 如未給它乙個初始值,雖然編譯的時候會通過,但是執行的時候會產生為初始化錯誤!方法呼叫 執行完,區域性變數便會自動釋放。在方法內的語句塊中建立的變數在編譯時假如未初始,如若使用,也會報未初始化錯誤!呼叫的...

全域性變數和區域性變數

通常的認為是定義在函式外面的就稱之為全域性變數 函式體內的稱之為區域性變數 在函式中與全域性變數同名的時候 情形1 函式內部的變數名如果第一次出現,且出現在 前面,即被視為定義乙個區域性變數。num 100 定義乙個全域性變數 defdemo num 100 這裡面的實際上是定義了乙個區域性的變數 ...