1. 程式人生 > >C/C++中作用域詳解(轉)

C/C++中作用域詳解(轉)

防止 局部作用域 gist 文件中 方式 為什麽不使用 形式參數 lan archive

作用域規則告訴我們一個變量的有效範圍,它在哪兒創建,在哪兒銷毀(也就是說超出了作用域)。變量的有效作用域從它的定義點開始,到和定義變量之前最鄰近的開括號配對的第一個閉括號。也就是說,作用域由變量所在的最近一對括號確定。

(1) 全局變量:

全局變量是在所有函數體的外部定義的,程序的所在部分(甚至其它文件中的代碼)都可以使用。全局變量不受作用域的影響(也就是說,全局變量的生命期一直到程序的結束)。如果在一個文件中使用extern關鍵字來聲明另一個文件中存在的全局變量,那麽這個文件可以使用這個數據。

(2) 局部變量:

局部變量出現在一個作用域內,它們是局限於一個函數的。局部變量經常被稱為自動變量,因為它們在進入作用域時自動生成,離開作用域時自動消失。關鍵字auto可以顯式地說明這個問題,但是局部變量默認為auto,所以沒有必要聲明為auto。

(3) 寄存器變量

寄存器變量是一種局部變量。關鍵字register告訴編譯器“盡可能快地訪問這個變量”。加快訪問速度取決於現實,但是,正如名字所暗示的那樣,這經常是通過在寄存器中放置變量來做到的。這並不能保證將變置在寄存器中,甚至也不能保證提高訪問速度。這只是對編譯器的一個暗示。

使用register變量是有限制的:(1) 不可能得到或計算register 變量的地址; (2) register變量只能在一個塊中聲明(不可能有全局的或靜態的register變量)。然而可以在一個函數中(即在參數表中)使用register變量作為一個形式參數。

一般地,不應當推測編譯器的優化器,因為它可能比我們做得更好。因此,最好避免使用關鍵字register

(4) 靜態變量

關鍵字static有一些獨特的意義。通常,函數中定義局部變量在函數中作用域結束時消失。當再次調用這個函數時,會重新創建變量的存儲空間,其值會被重新初始化。如果想使局部變量的值在程序的整個生命期裏仍然存在,我們可以定義函數的局部變量為static(靜態的),並給它一個初始化。初始化只在函數第一次調用時執行,函數調用之間變量的值保持不變,這種方式,函數可以“記住”函數調用之間的一些信息片斷。這也就是所謂的靜態局部變量,具有局部作用域,它只被初始化一次,自從第一次被初始化直到程序運行結束都一直存在,它和全局變量的區別在於全局變量對所有的函數都是可見的,而靜態局部變量只在定義自己的函數體內始終可見。

我們可能奇怪為什麽不使用全局變量。static局部變量的優點是在函數範圍之外它是不可用的,所以它不可能被輕易改變。這會使錯誤局部化。

此外同樣存在靜態全局變量,具有全局作用域,它與全局變量的區別在於如果程序包含多個文件的話,它作用於定義它的文件裏,不能作用到其它文件裏,即被static關鍵字修飾過的變量具有文件作用域。這樣即使兩個不同的源文件都定義了相同名字的靜態全局變量,它們也是不同的變量。

(5) 外部變量

extern告訴編譯器存在著一個變量和函數,即使編譯器在當前的文件中沒有看到它。這個變量或函數可能在一個文件或者在當前文件的後面定義。例如extern int i;編譯器會知道i肯定作為全局變量存在於某處。當編譯器看到變量i的定義時,並沒有看到別的聲明,所以知道它在文件的前面已經找到了同樣聲明的i。

(6) const常量

const告訴編譯器這個名字表示常量,不管是內部的還是用戶定義的數據類型都可以定義為const。如果定義了某對象為常量,然後試圖改變它,編譯器將會產生錯誤。在C++中一個const必須有初始值。

(7) volatile變量

限定詞const告訴編譯器“這是不會改變的”(這就是允許編譯器執行額外的優化);而限定詞volatile則告訴編譯器“不知道何時變化”,防止編譯器依據變量的穩定性作任何優化。

從分配內存空間看:全局變量,靜態局部變量,靜態全局變量都在靜態存儲區分配空間,而局部變量在棧裏分配空間

轉自:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777433.html

C/C++中作用域詳解(轉)