更新於 2024/10/23閱讀時間約 4 分鐘

C 語言指標補充:pass by value / pass by reference

延續上一篇的指標,補充 pass by value 和 pass by reference 的差別。

C 語言指標-程式碼圖解

當我們在程式中呼叫函數時,變數的傳遞方式有兩種:pass by valuepass by reference。這兩者的區別主要在於傳遞的是「值」還是「記憶體位置的參考」。

這個情況在交換數值的時候會特別明顯。

Pass by Value

當變數是以值傳遞時,函數接收到的只是該變數的「複製品/副本」,而非原始的變數。換句話說,在函數中對這個變數的操作,不會影響到主程式(main())中原本的變數

舉例來說,如果遇到 x 和 y 交換的情況但其實是複製地址,不是複製值。

假設我要交換 x 和 y 的值。我的直覺是,設定一個暫時的參數,並讓他們交換。

#include <stdio.h>
#include <cs50.h>

void swap (int a, int b);

int main(void)
{
int x = 1;
int y = 2;

printf("x is %i, y is %i\n",x,y);
swap(x,y);
printf("x is %i, y is %i\n",x,y);
}

void swap (int a, int b)
{
int tmp = a; //a先丟掉tmp裡面
a = b; //此時a的位置是空的,再把b丟進去
b = tmp; // b的位置變空了,再把a從tmp撈回來
}

但出來的結果卻沒有交換,為什麼呢?


因為實際在記憶體的寫在 main 裡面的 function 跟 main 外的 function 存的方式不太同個平面。

所以 swap中的 x 和 y 並非等於 main。而只是他的「副本」(copy)。

這時候只是pass by value。

那這樣怎麼解決呢?

Pass by reference

參考傳遞則完全不同,它傳遞的是變數的「記憶體位置」。因此,函數可以直接操作原變數,而不只是操作一個副本。這樣的傳遞方式在需要修改變數內容時特別有用。

讓他指向值,指向 a 和 b 代表的地址,所以程式碼就要改成:

#include <stdio.h>
#include <cs50.h>

void swap (int *a, int *b);

int main(void)
{
int x = 1;
int y = 2;

printf("x is %i, y is %i\n",x,y);
swap(&x,&y); // 記得丟進去的是指向x和y的地址,所以要加&
printf("x is %i, y is %i\n",x,y);
}

void swap (int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}

總結:

想像你有兩個人要交換手中的兩件物品:

  • 在 pass by value 的情境下,這兩個人都拿著物品的照片(副本),彼此交換照片,但實際的物品並沒有改變。
  • 在 pass by reference 的情境下,他們交換的是實體物品,這樣物品的擁有者也會發生變動。


分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.