C 語言初學教材 - 第五章 範圍規則

自動型變數在程式中有一定的效力範圍,通常效力範圍是指用大括弧 { } 圍起來的程式區塊。宣告在所有函數外的變數,所有函數均可使用,但是一旦函數中宣告相同名稱的變數,就只能使用函數內所定義的變數了。



下例說明範圍規則的使用
#include <stdio.h>

void test1(void);
void test2(void);

int a = 0;

int main(void)
{
    int a = 1;
    
    printf("a = %d\n", a);
    test1();
    test2();
    printf("\n");
    
    {
        int a = 2;
        printf("a = %d\n", a);
        test1();
        test2();
        printf("\n");
    }
    
    {
        printf("a = %d\n", a);
        test1();
        test2();
        printf("\n");
    }

    return 0;
}

void test1(void)
{
    int a = 3;
    printf("a = %d\n", a);
}

void test2(void)
{
    printf("a = %d\n", a);
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:scopetest.c
    功能:示範變數的範圍規則
    作者:張凱慶
    時間:西元2010年7月 */


我們分別在第 6 行、第 10 行、第 18 行及第 37 行都宣變數 a ,同時依序給 0 、 1 、 2 、 3 的值。先來編譯看看執行結果



程式依序印出三組數字,然後用空行分開。印出第一組數字的程式碼為
printf("a = %d\n", a);
test1();
test2();
printf("\n");


這裡,印出的第一個 a 為函數 main() 所定義的 a ,印出第二個 a 則是函數 test1() 所定義的 a ,而 test2() 沒有定義任何的變數 a ,所以印出的第三個 a 是定義在第 6 行,也就是宣告在所有函數外的 a 。


印出第二組數字的程式碼為
{
    int a = 2;
    printf("a = %d\n", a);
    test1();
    test2();
    printf("\n");
}


這是在一個程式區塊內,同時宣告定義了另一個 a ,所以印出的第一個 a 為程式區塊定義的 a ,然後依序呼叫 test1() 及 test2() 印出第二個 a 及第三個 a 。


印出第三組數字的程式碼為
{
    printf("a = %d\n", a);
    test1();
    test2();
    printf("\n");
}


這是另一個程式區塊,由於裡頭沒有宣告定義任何的變數 a ,所以印出的第一個 a 為之前第 10 行定義的 a ,也就是說在之前程式區塊內所定義的 a ,離開程式區塊後就失去效力。接著依序呼叫 test1() 及 test2() 印出第二個 a 及第三個 a 。


函數定義本身屬於個別的程式區塊,因此不同函數可定義相同名稱的變數,互相不會干擾各自的執行。任何程式區塊內定義的變數,通常都稱為區域變數,表示他們的效力只在某個特定的區域,而像定義在所有函數外的變數,有時被稱為全域變數,代表所有函數均可使用,無須另外宣告定義。


利用全域變數有其方便的地方,但也常常帶來不良的副作用,因此使用全域變數要謹慎跟小心,沒有必要的話,大多使用區域變數即可。


問題與討論
  1. 比較全域變數與區域變數的異同。
  2. 全域變數有可能會帶來什麼樣的副作用?




沒有留言: