指標與函數參數
——《C程式設計語言(第2版-新版)》5.2
由於 C 語言是以傳值的方式將參數值傳遞給被調用函數。因此,被調用函數不能直接修改主調函數中的變數的值。例如,排序函數可能會使用一個名為 swap 的函數來交換兩個次序顛倒的元素。但是,如果將 swap 函數定義為下列形式:
void swap(int x, int y) /* WRONG */
{
int temp;
temp = x;
x = y;
y = temp;
}
則下列語句無法達到該目的。
swap(a, b);
這是因為,由於參數傳遞採用傳值的方式,因此上述的 swap 函數不會影響到調用它的常式中的參數 a 和 b 的值。該函數僅僅交換了 a 和 b 的副本的值。
那麼,如何?我們的目標呢,可以使主調程式將指向所要交換的變數的指標傳遞給被調用函數,即:
swap(&a, &b);
由於一元運算子&用來取變數的地址,這樣&a就是一個指向變數 a 的指標。swap 函數的所有參數都聲明為指標,並且通過這些指標來間接訪問它們指向的運算元。
void swap(int *px, int *py) /* interchange *px and *py */
{
int temp;
temp = *px;
*px = *py;
*py = temp;
}
指標參數使得被調用函數能夠訪問和修改主調函數中的對象的值。我們來看這樣一個例子:函數 getint 接受自由格式的輸入,並執行轉換,將輸入的字元流分解成整數,且每次調用得到一個整數。getint 需要返迴轉換後得到的整數,並且,在到達輸入結尾時要返迴文件結束標記。這些值必須通過不同的方式返回。EOF(檔案結束標記符)可以用任何值表示,當然也可用一個輸入的整數表示。
可以這樣設計該函數:將表示是否到達檔案結尾的狀態作為 getint 函數的傳回值,同時,使用一個指標參數儲存轉換後得到的整數並傳回給主調函數。函數 scanf 的實現就採用了這種方法。
下面的迴圈語句調用 getint 函數給一個整形數組賦值:
int n, array[SIZE], getint(int *);
for (n = 0; n< SIZE && getint(&array[n]) != EOF; n++)
每次調用 getint 時,輸入資料流中的下一個整數將被賦值給數組元素 array[0],同時,n 的值將增加1。請注意,這裡必須將 array[n] 的地址傳遞給函數 getint,否則函數 getint 將無法把轉換得到的整數傳回給調用者。
該版本的 getint 函數在到達檔案結尾時返回 EOF,當下一個輸入不是數字時返回0,當輸入中包含一個有意義的數字時返回一個正值。
#include <ctype.h>
int getch(void);
void ungetch(int);
/* getint: get next integer from input into *pn */
int getint(int *pn)
{
int c, sign;
while (isspace(c = getchar())) /* skip white space */
;
if(!isdigit(c) && c != EOF && c != '+' && c != '-'){
ungetch(c); /* it is not a number */
return 0;
}
sign = (c == '-')? -1 : 1;
if(c == '+' || c == '-')
c = getch();
for(*pn = 0; isdigit(c), c = getch())
*pn = 10 * *pn + (c - '0');
*pn *= sign;
if(c != EOF)
ungetch(c);
return c
}
在 getint 函數中,*pn始終作為一個普通的整形變數使用。其中還使用了 getch 和 ungetch 兩個函數,藉助這兩個函數,函數 getint 必須讀入的一個多餘字元就可以重新寫回到輸入中。
/*********************************
* Last Edit By Old At 2009.12.26
********************************/
C程式設計語言_第2版新版.pdf