首先看以下程序:
例 23.1. 指針參數和返回值
#include <stdio.h> int *swap(int *px, int *py) { int temp; temp = *px; *px = *py; *py = temp; return px; } int main(void) { int i = 10, j = 20; int *p = swap(&i, &j); printf("now i=%d j=%d *p=%d\n", i, j, *p); return 0; }
我們知道,調用函數的傳參過程相當於用實參定義並初始化形參,swap(&i, &j)
這個調用相當於:
int *px = &i; int *py = &j;
所以px
和py
分別指向main
函數的局部變數i
和j
,在swap
函數中讀寫*px
和*py
其實是讀寫main
函數的i
和j
。儘管在swap
函數的作用域中訪問不到i
和j
這兩個變數名,卻可以通過地址訪問它們,最終swap
函數將i
和j
的值做了交換。
上面的例子還演示了函數返回值是指針的情況,return px;
語句相當於定義了一個臨時變數並用px
初始化:
int *tmp = px;
然後臨時變數tmp
的值成為表達式swap(&i, &j)
的值,然後在main
函數中又把這個值賦給了p,相當於:
int *p = tmp;
最後的結果是swap
函數的px
指向哪就讓main
函數的p
指向哪。我們知道px
指向i
,所以p
也指向i
。
1、對照本節的描述,像圖 23.1 “指針的基本概念”那樣畫圖理解函數的調用和返回過程。在下一章我們會看到更複雜的參數和返回值形式,在初學階段對每個程序都要畫圖理解它的運行過程,只要基本概念清晰,無論多複雜的形式都應該能正確分析。
2、現在回頭看第 3 節 “形參和實參”的習題1,那個程序應該怎麼改?