首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言指針進階示例 - 函數指針、指針數組、參數傳遞

     編輯:關於C

代碼功能概覽

本文展示一組指針相關的綜合示例,涵蓋:值傳遞 vs 指針傳遞、字符查找(單級/雙級指針)、函數指針變量、函數指針類型定義、回調函數、命令行參數解析等核心概念。

關鍵代碼片段解析

1. 值傳遞無法修改實參

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,未改變

2. 指針傳遞可修改實參

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,實參交換成功

3. 字符查找:單級指針作為輸出參數

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 是值傳遞,函數內修改不影響外部

4. 字符查找:雙級指針正確輸出

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

5. 函數指針聲明與調用

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);

6. 函數指針數組實現簡易計算器

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 先移動再取值。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved