在 C 語言進階學習中,指標函數與函數指標是兩個極易混淆卻又至關重要的概念。它們僅在宣告語法上相差一組括號,卻代表著完全不同的語意。本文將透過語法剖析、記憶技巧與實戰範例,助你徹底掌握兩者的區別與應用。
指標函數的定義形式為:
類型名 *函數名(參數表列);
根據運算子優先序,() 優先於 * 結合,因此 函數名 首先與 () 結合,表明它是一個函數;再與前綴 * 結合,說明該函數的返回值是一個指標。例如:
int *pfun(int, int);
等價於 int *(pfun(int, int));,表示 pfun 是一個接受兩個 int 參數、返回 int*(整數指標)的函數。
函數指標的定義形式為:
類型名 (*指標變數名)(參數表列);
此處括號強制 *指標變數名 先結合,說明它是一個指標;再與後方 () 結合,表明該指標指向一個函數;最後與前方類型名結合,規定被指向函數的返回類型。例如:
int (*pfun)(int, int);
表示 pfun 是一個指標,指向「接受兩個 int 參數、返回 int」的函數。
* 在 () 之外(左側) → 指標函數(函數返回指標)* 在 () 之內(與變數名同侧) → 函數指標(指標指向函數)當函數需要返回另一個函數的指標時,直接撰寫宣告會極其晦澀,例如:
int (*ff(int))(int *, int);
此時善用 typedef 可大幅提升可讀性:
typedef int (*PF)(int *, int); // 定義函數指標類型 PF
PF ff(int); // 宣告返回 PF 類型的函數 ff
下列程式示範如何透過函數指標實現「根據輸入字元動態選擇演算法」:
#include <stdio.h>
#include <assert.h>
double GetMin(double *data, int n) { /* 求最小值 */ }
double GetMax(double *data, int n) { /* 求最大值 */ }
double GetAvg(double *data, int n) { /* 求平均值 */ }
double Unknown(double *data, int n) { return 0; }
typedef double (*PF)(double *, int); // 函數指標類型
PF GetOperation(char c) {
switch (c) {
case 'd': return GetMax;
case 'x': return GetMin;
case 'p': return GetAvg;
default: return Unknown;
}
}
int main(void) {
double dbData[] = {3.14, 1.41, -0.5, 999, -313, 365};
int n = sizeof(dbData)/sizeof(dbData[0]);
char op;
printf("輸入操作 (d=最大 x=最小 p=平均):");
op = getchar();
printf("結果 = %lf\n", GetOperation(op)(dbData, n));
return 0;
}
程式中 GetOperation 根據字元返回對應的函數指標,main 直接以 GetOperation(op)(dbData, n) 調用,展現了函數指標作為回呼與策略切換的經典用法。
類型 *函數名(…)類型 (*指標名)(…)typedef 分層,提升可讀性與維護性掌握兩者區別,不僅能避開語法陷阱,更能寫出靈活、可擴充的 C 程式架構。