temp = a; a = b; b = temp;
簡單說,就是先把變數 a 的值暫存到 temp ,然後將 b 的值存到 a 之中,最後再將 temp 的值回存到 b 之中。
那要怎麼把這個功能寫成函數呢?直接照上面的方式寫可以嗎?
#include <stdio.h> void swap(int n1, int n2); int main(void) { int a = 3; int b = 5; printf("a = %d, b = %d\n", a, b); swap(a, b); printf("呼叫 swap() 之後, a = %d, b = %d\n", a, b); return 0; } void swap(int n1, int n2) { int temp = n1; n1 = n2; n2 = n1; } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:swaptestw.c 功能:將兩個數字對調,錯誤的例子 作者:張凱慶 時間:西元2010年7月 */
編譯後執行,結果如下
編譯執行的結果直接給我們答案了,為什麼呢?因為 C 語言是採用傳值呼叫,任何傳遞到函數中的參數都是拷貝後的值,所以變數 a 與變數 b 傳遞給函數 swap() 也是拷貝後的值,也就是 n1 及 n2 。 n1 及 n2 在 swap() 中做了什麼調整或改變,這都侷限在 swap() 裡頭,並不會影響到 main() 裡的 a 及 b 。
如果我們要利用函數對調兩個變數的值,我們應該要利用指標做參數,因為指標能將變數的記憶體位置變數傳遞給函數,然後在對調函數中用取值運算子得到變數所儲存的值,進行兩個變數的對調工作。
正確的版本如下
#include <stdio.h> void swap(int *n1Ptr, int *n2Ptr); int main(void) { int a = 3; int b = 5; printf("a = %d, b = %d\n", a, b); swap(&a, &b); printf("呼叫 swap() 之後, a = %d, b = %d\n", a, b); return 0; } void swap(int *n1Ptr, int *n2Ptr) { int temp = *n1Ptr; *n1Ptr = *n2Ptr; *n2Ptr = temp; } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:swaptest.c 功能:將兩個數字對調 作者:張凱慶 時間:西元2010年7月 */
第 3 行及第 17 行,宣告指標變數用星號
void swap(int *n1Ptr, int *n2Ptr);
第 11 行呼叫
swap(&a, &b);
利用取址運算子 & 可取得變數的記憶位址,也就是指標變數。
第 19 到 21 行
int temp = *n1Ptr; *n1Ptr = *n2Ptr; *n2Ptr = temp;
函數 swap() 裡的 n1Ptr 儲存的是變數 a 的記憶體位址,所以要利用取值運算子 * ,反參考該位址所儲存的數值, n2Ptr 的情況也一樣。這樣一來,便可由被呼叫函數操作呼叫函數中的變數值,兩個變數的數值才能對調。
編譯後執行,結果如下
問題與討論
- 暫存變數的作用是什麼?
- 為什麼到另一個函數之中,不能把函數 main() 裡的數字對調?
- 說明利用指標三倏地運作機制。
沒有留言:
張貼留言