首先,看一下以下代碼:
int i = 1; //全域範圍變數i
void Print();
int main(int argc, char* argv[])
{
cout<<"i="<< i<<endl; //語句1
int i = 10; //局部範圍變數i
int j = i; //局部範圍變數j
cout<<"i="<< i<<endl; //語句2
cout<<"j="<< j<<endl; //語句5
for(int k=0;k<10;k++) //語句範圍變數
{
int i= 100; //語句作用變數i
cout<<"i="<<i<<endl; //語句3
}
Print(); //語句4
{
int i = 0;
cout<<"i="<< i<<endl; //語句5
}
return 0;
}
void Print(){
cout<<"i="<< i<<endl;
}
在上述代碼中,輸出1、輸出2和輸出3,分別是多少?
這是一個關於變數的範圍問題,在C++、java等語言中,變數的範圍一般有三種:全域範圍、局部範圍和語句範圍。
在程式中,我們不能僅僅的討論變數的範圍,確切地說,變數的範圍是面向過程編程的說法,而物件導向的編程應該說是名字的範圍比較合理。因為,在C++或java等語言中,一個名字代表著一個與之相關聯的實體,這個實體或是變數、或是函數、或是類型。
變數——是指提供給程式操作的有名字的儲存區。名字——則指的是人類可以識別的標示。在物件導向編程中,有內部類、匿名類、成員函數、成員變數及其訪問等說法。因此,討論範圍時,以其說是變數的範圍,不如用名字的範圍更為合理和充足。
不過,為了簡單起見,我們使用類似C語言程式的說法來討論範圍問題。
全域範圍——定義在所有函數外部的名字;
局部範圍——定義在函數體內的名字;
語句作用於——定義在語句內的名字,例如for語句內定義的名字;
現在,我們來看看程式啟動並執行結果是什嗎?
int i = 1; //全域範圍變數i
int i = 10; //局部範圍變數i
int i= 100; //語句作用變數i
注釋為//語句1的語句輸出的結果是i=1。可見,這個是值是全域變數i的值。
注釋為//語句2的語句輸出結果是i=10。可見,這個值是是局部變數i的值。
注釋為//語句3的語句輸出的結果是i=100。可見,這個值是語句變數i的值。
那麼,語句4的輸出結果是什麼呢?
注釋為//語句4是調用了print函數,而print函數體內是一個輸出變數i的值得語句。那麼,這個i到底是哪個範圍下的i。是main函數下的?還是全域變數i,還是for語句內的?
運行結果告訴我們,語句4的輸出時i=1。
這回很確定的說,print函數裡的i是全域範圍下的i變數。那麼,小瀋陽說:這是為什麼呢?
理由是,全域範圍下的名字是定義在所有函數外部的,顧名思義,它的作用範圍是全域的,覆蓋整個檔案範圍之內。而局部範圍名字只能在某個局部範圍內使用,以一個花括弧{}為單位,例如,一個函數體內。
現在,討論注釋為//語句5的句子輸出是多少,即j的值是多少?
j=i,即把i值賦給j,那麼到底j是全域名字i,還是同j等級的局部名字i呢?
運行結果告訴我們,j==100,因此,我們知道,是局部名字i的值賦給j的。原因是,在一個局部範圍內,局部名字i屏蔽掉了全域名字i。