本文展示一組指針相關的綜合示例,涵蓋:值傳遞 vs 指針傳遞、字符查找(單級/雙級指針)、函數指針變量、函數指針類型定義、回調函數、命令行參數解析等核心概念。
void Exchg1(int x, int y) { // 形參是副本
int t = x; x = y; y = t;
printf("x=%d,y=%d ", x, y); // 只影響局部副本
}
int a=4,b=6;
Exchg1(a,b); printf("a=%d,b=%d ", a,b); // 輸出 4 6,未改變
void Exchg2(int *px, int *py) {
int t = *px; *px = *py; *py = t;
printf("*px=%d,*py=%d ", *px, *py);
}
Exchg2(&a, &b); printf("a=%d,b=%d ", a,b); // 輸出 6 4,實參交換成功
void find1(char arr[], char target, char *pa) {
for (int i=0; arr[i]; i++)
if (arr[i]==target) { pa = arr+i; break; }
}
char *p = 0; find1(str, 'd', p); // 錯誤:p 是值傳遞,函數內修改不影響外部
void find2(char arr[], char target, char **ppa) {
for (int i=0; arr[i]; i++)
if (arr[i]==target) { *ppa = arr+i; break; }
}
char *p = 0; find2(str, 'd', &p); // 正確:傳遞 p 的地址,函數通過 *ppa 修改 p
void MyFunc(int x) { printf("x=%d ", x); }
// 聲明函數指針變量
void (*Funcp)(int);
// 直接賦值調用
Funcp = MyFunc;
(*Funcp)(20); // 等價於 Funcp(20)
(MyFunc)(30); // 函數名本身可作指針用
(*MyFunc)(40);
(&MyFunc)(50); // 取地址同理
// 類型別名簡化聲明
typedef void (*FuncType)(int);
void CallMyFunc(FuncType fp, int x) { fp(x); } // 回調模式
CallMyFunc(MyFunc1, 100);
int add(int a,int b){ return a+b; }
int sub(int a,int b){ return a-b; }
int (*ops[])(int,int) = { add, sub }; // 函數指針數組
int main(int argc, char **argv) {
int op = atoi(*++argv); // 第一個參數為運算符索引 0/1
int result = 0;
while (*++argv) {
int val = atoi(*argv);
result = ops[op](result, val);
}
printf("%d\n", result);
return 0;
}
// 運行:./calc 0 1 2 3 → 0=add, 1+2+3=6
// 運行:./calc 1 10 5 2 → 1=sub, 10-5-2=3
| 概念 | 關鍵點 |
|---|---|
| 值傳遞 | 形參是副本,函數內修改不影響實參 |
| 指針傳遞 | 傳遞地址,函數可通過解引用修改實參 |
| 輸出參數 | 需傳遞指針的指針(二級指針) |
| 函數指針 | 聲明:返回類型 (*名)(參數列表) |
| 函數名 | 隱式轉換為函數指針,&func 等價 |
| 回調函數 | 將函數指針作參數傳遞,實現策略模式 |
| 命令行參數 | argc 含程序名,argv[0] 為程序名 |
NULL,使用前檢查。typedef 簡化,如 typedef void(*Handler)(int);。argv 移動邏輯,*++argv 先移動再取值。