語法書 / AA 競程語法書 上冊 / 第三單元 / 變數範圍(Scope)

3.8 變數範圍(Scope)

圖 3-3:變數作用域(Scope)

當程式變大時,變數會越來越多。我們需要理解每個變數在程式的哪個地方可以被使用。這就是變數範圍(Scope)的概念。

區塊(Block)

在 C++ 中,大括號 {} 圍起來的區域稱為一個區塊。每個區塊有自己的作用域。

{
    // 這是一個區塊
    int x = 5;  // x 在這個區塊內宣告
    cout << x;  // 在這裡可以使用 x
}
// 這裡無法使用 x(超出了它的作用域)

作用域規則

  • 變數只能在它被宣告的區塊以及更深層的巢狀區塊內使用
  • 離開宣告它的區塊後,變數自動銷毀

範例程式碼:作用域示意

#include <iostream>
using namespace std;

int main() {  // main 函式的區塊開始
    int x = 10;  // 在 main 區塊宣告 x

    cout << "outer x: " << x << endl;  // 輸出:10

    if (x > 5) {  // if 的區塊開始
        int y = 20;  // 在 if 區塊宣告 y
        cout << "inner y: " << y << endl;  // 輸出:20
        cout << "inner sees x: " << x << endl;  // 輸出:10
    }  // if 區塊結束,y 銷毀

    // cout << y << endl;  // ✗ 編譯錯誤:y 超出作用域
    cout << "outer still has x: " << x << endl;  // ✓ 輸出:10

    return 0;
}

執行結果

outer x: 10
inner y: 20
inner sees x: 10
outer still has x: 10

變數遮蔽(Variable Shadow)

如果在內層區塊宣告一個和外層同名的變數,內層的變數會「遮蔽」(隱藏)外層的變數。這很容易造成 bug。

#include <iostream>
using namespace std;

int main() {
    int x = 10;  // 外層的 x

    cout << "outer x: " << x << endl;  // 輸出:10

    {
        int x = 20;  // ✗ 內層的 x(同名,遮蔽了外層的 x)
        cout << "inner x: " << x << endl;  // 輸出:20
    }

    cout << "outer x: " << x << endl;  // 輸出:10(外層 x 沒變)

    return 0;
}

執行結果

outer x: 10
inner x: 20
outer x: 10

全域變數(Global Variables)

如果在所有函式外(也就是 main 之外——main 本身就是一個函式)宣告變數,它就是全域變數,可以在任何地方使用(但這通常不是好習慣):

#include <iostream>
using namespace std;

int global_x = 100;  // 全域變數

int main() {
    cout << global_x << endl;  // 可以使用
    return 0;
}

動手試試看

寫一個程式,在 main 函式中宣告 x = 5,然後在一個 if 區塊內宣告另一個 x = 10。輸出兩層的 x,驗證遮蔽的效果。然後,修改程式使用不同的變數名,看清楚之後程式更容易理解。