1. 程式人生 > >c語言-函式的傳值與傳址

c語言-函式的傳值與傳址

第1篇文章

最近筆者在學習Zed A. Shaw寫的《“笨辦法”學c語言》,但在處理函式形參是值或指標時,顯得有點力不從心。故在查詢資料後,將學習所得記錄下來,以便加深記憶。

示例程式碼↓

// 函式的傳值與傳址示例程式碼
#include<stdio.h>

// 函式宣告,exchange交換函式
void exchange_value(int a,int b); // 傳值
void exchange_pointer(int *a,int *b); // 傳址

int main(int argc,char *argv[])
{
    int x = 10;
    int y = 2;
    printf("NO.1: x=%d,y=%d\n",x,y);

    exchange_value(x,y);
    printf("NO.2: x=%d,y=%d\n",x,y);

    exchange_pointer(&x,&y);
    printf("NO.2: x=%d,y=%d\n",x,y);

    return 0;
}

// 函式實現
void exchange_value(int a,int b)
{
    int temp = a;
    a = b;
    b = temp;
}

void exchange_pointer(int *a,int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

執行結果如下:

exchange_value函式沒有效果,而exchange_pointer成功交換了x和y。

筆者理解如下: 

呼叫(被調)函式時,函式形參將獲得實參值的一份拷貝,即傳值:a = 10,b = 2,傳址:a = 儲存 x 的地址, b = 儲存 y 的地址。因為形參的值是拷貝來的,所以被調函式對拷貝資料的任何操作都不會影響主調函式中的實參的值。下面針對兩種方式分別來討論。

  1. exchange_value:形參 a,b 分別被賦值為10,2 ,函式體內的操作與主調函式無關。這就如同(不太準確 :)又寫了一個main()函式,並定義了a,b兩個整數型變數,所以任何操作都不影響主調函式中變數的值。
  2. exchange_pointer:形參 a,b 分別被賦值為儲存 x 的地址和儲存 y 的地址,同樣函式體內的操作與主調函式無關,但這個略有不同。首先假設儲存x的地址為100(實際地址不會如此簡單),儲存y的地址為104,如表1.1。
    表1.1初始狀態
    記憶體地址 &x——100 &y——104
    記憶體儲存的值 10 2
        將引數傳遞給exchange_pointer後,如表1.2
    表1.2
    記憶體地址 a = &x——100 b = &y——104
    記憶體儲存的值 10 2
    *a 即訪問a所儲存的記憶體地址的值,所以「int temp = *a;*a = *b;*b = temp;」 實際上是將a所儲存的地址指向的值與b所儲存的地址指向的值交換。如表1.3
    表1.3最終狀態
    記憶體地址 a = &x——100 b = &y——104
    記憶體儲存的值 2 100
    所以,主調函式再次呼叫x(即  *(&x) ,下同)和y時,值發生改變。

總結:傳值不改變主調函式中變數的值,傳址通過間接訪問操作(*)改變儲存在相應記憶體地址的值來修改主調函式中變數的值。

                                                                           -完-                                                       2018.10.5

參考書籍:

[1].《c和指標》-Kenneth A. Reek,人民郵電出版社

[2]. 《C Primer Plus 中文版(第6版)》- Stephen Prata,人民郵電出版社