發信人: ax.bbs@bbs.ee.nthu.edu.tw. (athena), 信區: test
標  題: 星星流講座 0028
發信站: ☆清華電機☆ (Sat Jun 17 14:50:46 1995)
轉信站: star

星星流講座 0028         C 語言教室

第 5 講 之 4            作為函數參數的指標
                        Topic: Pointers as function parameters

前面說過函數的參數視同函數的區域變數,但是這表示傳給函數的參數
其值永遠不會被更動嗎?那你就猜錯了。請先看看下面的程式:

/* para.c */
#include <stdio.h>

void foo (int a, int *b);

void main (void)
{
    int a, b;
    a = 3;
    b = 4;
    foo (a, &b);
    printf ("%d %d\n", a, b);
}

void foo (int a, int *b)
{
    a = 4;
    *b = 5;
}

執行結果:

3 5

細心的讀者應該發現到 b 的值竟然被 foo 這個函數改變了,這是為什麼呢?
在 C 語言中,函數的參數可以用兩種方法來傳遞:傳值 (call by value) 或
傳址 (call by reference)。傳值就是直接把變數的值傳入函數中,而傳址則
是把參數的位址傳入函數。
上面的例子中,由於傳入 foo 的是 b 的位址,
所以 foo 能夠改變 b 的值,請看下面圖表的說明:

        call by value

        ┌┐                 ┌┐
        └┘     -------->   └┘  ------------------>  foo()
        變數 a   複製一個 a        把複製品傳給 foo()
                                   複製品成為 foo() 的區域變數
                                   複製品和原來變數 a 無關了


        call by reference

               ■ 指向變數 b 的指標 &b
                |
        ┌┐<---+
        └┘       ---------->  ■  ------------------>  foo()
        變數 b     複製一個 &b      把複製品傳給 foo()
                   &b 仍然指向 b    複製品成為 foo() 的區域變數
                                    複製品仍然指向 b
                                    所以 foo() 能夠更動 b

函數參數傳值和傳址的差異是非常重要的觀念,請各位務必弄清楚了。