作用域:
作用域規(guī)則告訴我們一個變量的有效范圍,它在哪兒創(chuàng)建,在哪兒銷毀(也就是說超出了作用域)。變量的有效作用域從它的定義點開始,到和定義變量之前最鄰近的開括號配對的第一個閉括號。也就是說,作用域由變量所在的最近一對括號確定。
全局變量:
全局變量是在所有函數(shù)體的外部定義的,程序的所在部分(甚至其它文件中的代碼)都可以使用。全局變量不受作用域的影響,問題可以使用的(也就是說,全局變量的生命期一直到程序的結(jié)束)。如果在一個文件中使用extern關鍵字來聲明另一個文件中存在的全局變量,那么這個文件可以使用這個數(shù)據(jù)。
局部變量:
局部變量出現(xiàn)在一個作用域內(nèi),它們是局限于一個函數(shù)的。局部變量經(jīng)常被稱為自動變量,因為它們在進入作用域時自動生成,離開作用域時自動消失。關鍵字auto可以顯式地說明這個問題,但是局部變量默認為
auto,所以沒有必要聲明為auto。
寄存器變量
寄存器變量是一種局部變量。關鍵字register告訴編譯器“盡可能快地訪問這個變量”。加快訪問速度取決于現(xiàn)實,但是,正如名字所暗示的那樣,這經(jīng)常是通過在寄存器中放置變量來做到的。這并不能保證將變置在寄存器中,甚至也不能保證提高訪問速度。這只是對編譯器的一個暗示。
使用register變量是有限制的。不可能得到或計算register 變量的地址。register變量只能在一個塊中聲明(不可能有全局的或靜態(tài)的register變量)。然而可以在一個函數(shù)中(即在參數(shù)表中)使用register變量作為一個形式參數(shù)。
一般地,不應當推測編譯器的優(yōu)化器,因為它可能比我們做得更好。因此,最好避免使用關鍵字register。
靜態(tài)變量
關鍵字static有一些獨特的意義。通常,函數(shù)中定義局部變量在函數(shù)中作用域結(jié)束時消失。當再次調(diào)用這個函數(shù)時,會重新創(chuàng)建變量的存儲空間,其值會被重新初始化。如果想使局部變量的值在程序的整個生命期里仍然存在,我們可以定義函數(shù)的局部變量為static(靜態(tài)的),并給它一個初始化。初始化只在函數(shù)第一次調(diào)用時執(zhí)行,函數(shù)調(diào)用之間變量的值保持不變,這種方式,函數(shù)可以“記住”函數(shù)調(diào)用之間的一些信息片斷。
我們可能奇怪為什么不使用全局變量。static變量的優(yōu)點是在函數(shù)范圍之外它是不可用的,所以它不可能被輕易改變。這會使錯誤局部化。
外部變量
extern告訴編譯器存在著一個變量和函數(shù),即使編譯器在當前的文件中沒有看到它。這個變量或函數(shù)可能在一個文件或者在當前文件的后面定義。例如extern int i;編譯器會知道i肯定作為全局變量存在于某處。當編譯器看到變量i的定義時,并沒有看到別的聲明,所以知道它在文件的前面已經(jīng)找到了同樣聲明的i 。
常量
const告訴編譯器這個名字表示常量,不管是內(nèi)部的還是用戶定義的數(shù)據(jù)類型都可以定義為const。如果定義了某對象為常量,然后試圖改變它,編譯器將會產(chǎn)生錯誤。在C++中一個const必須有初始值。
volatile變量
限定詞const告訴編譯器“這是不會改變的”(這就是允許編譯器執(zhí)行額外的優(yōu)化);而限定詞volatile則告訴編譯器“不知道何時變化”,防止編譯器依據(jù)變量的穩(wěn)定性作任何優(yōu)化。
參考《Thinking in C++》第一卷第三章