C语言函数指针 #

一、函数指针基础 #

1.1 什么是函数指针 #

函数指针是指向函数的指针变量。

c
int add(int a, int b) {
    return a + b;
}

int (*p)(int, int) = add;

1.2 函数名与函数指针 #

函数名是函数的入口地址:

c
#include <stdio.h>

void hello() {
    printf("Hello, World!\n");
}

int main() {
    printf("函数地址: %p\n", (void*)hello);
    printf("函数地址: %p\n", (void*)&hello);
    
    void (*p)() = hello;
    p();
    return 0;
}

1.3 声明语法 #

c
返回类型 (*指针名)(参数类型列表);

示例:

c
int (*p1)(int);
int (*p2)(int, int);
void (*p3)(void);
char* (*p4)(const char*);

二、函数指针使用 #

2.1 基本使用 #

c
#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int main() {
    int (*p)(int, int) = add;
    
    printf("直接调用: %d\n", add(10, 5));
    printf("指针调用: %d\n", p(10, 5));
    printf("指针调用: %d\n", (*p)(10, 5));
    return 0;
}

2.2 函数指针赋值 #

c
#include <stdio.h>

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }

int main() {
    int (*p)(int, int);
    
    p = add;
    printf("加法: %d\n", p(10, 5));
    
    p = subtract;
    printf("减法: %d\n", p(10, 5));
    return 0;
}

2.3 typedef简化 #

c
#include <stdio.h>

typedef int (*Operation)(int, int);

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }

int main() {
    Operation op = add;
    printf("结果: %d\n", op(10, 5));
    return 0;
}

三、函数指针数组 #

3.1 定义函数指针数组 #

c
#include <stdio.h>

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return a / b; }

int main() {
    int (*operations[4])(int, int) = {add, subtract, multiply, divide};
    char* names[] = {"+", "-", "*", "/"};
    
    int a = 20, b = 4;
    for (int i = 0; i < 4; i++) {
        printf("%d %s %d = %d\n", a, names[i], b, operations[i](a, b));
    }
    return 0;
}

输出:

text
20 + 4 = 24
20 - 4 = 16
20 * 4 = 80
20 / 4 = 5

3.2 使用typedef #

c
#include <stdio.h>

typedef int (*Operation)(int, int);

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }

int main() {
    Operation ops[] = {add, subtract};
    
    for (int i = 0; i < 2; i++) {
        printf("结果: %d\n", ops[i](10, 5));
    }
    return 0;
}

3.3 菜单系统 #

c
#include <stdio.h>

void menu_new() { printf("新建文件\n"); }
void menu_open() { printf("打开文件\n"); }
void menu_save() { printf("保存文件\n"); }
void menu_exit() { printf("退出程序\n"); }

int main() {
    void (*menu[])(void) = {menu_new, menu_open, menu_save, menu_exit};
    char* names[] = {"新建", "打开", "保存", "退出"};
    int choice;
    
    while (1) {
        printf("\n===== 菜单 =====\n");
        for (int i = 0; i < 4; i++) {
            printf("%d. %s\n", i + 1, names[i]);
        }
        printf("请选择: ");
        scanf("%d", &choice);
        
        if (choice >= 1 && choice <= 4) {
            menu[choice - 1]();
            if (choice == 4) break;
        } else {
            printf("无效选择\n");
        }
    }
    return 0;
}

四、回调函数 #

4.1 什么是回调函数 #

回调函数是作为参数传递给其他函数的函数指针。

4.2 基本回调 #

c
#include <stdio.h>

void process(int arr[], int size, void (*callback)(int)) {
    for (int i = 0; i < size; i++) {
        callback(arr[i]);
    }
}

void print_value(int value) {
    printf("%d ", value);
}

void print_square(int value) {
    printf("%d ", value * value);
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    
    printf("原值: ");
    process(arr, 5, print_value);
    printf("\n");
    
    printf("平方: ");
    process(arr, 5, print_square);
    printf("\n");
    return 0;
}

4.3 qsort回调 #

c
#include <stdio.h>
#include <stdlib.h>

int compare_asc(const void* a, const void* b) {
    return (*(int*)a - *(int*)b);
}

int compare_desc(const void* a, const void* b) {
    return (*(int*)b - *(int*)a);
}

void print_array(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {5, 2, 8, 1, 9, 3};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    qsort(arr, size, sizeof(int), compare_asc);
    printf("升序: ");
    print_array(arr, size);
    
    qsort(arr, size, sizeof(int), compare_desc);
    printf("降序: ");
    print_array(arr, size);
    return 0;
}

4.4 查找函数 #

c
#include <stdio.h>
#include <stdbool.h>

int* find_if(int* start, int* end, bool (*predicate)(int)) {
    while (start < end) {
        if (predicate(*start)) {
            return start;
        }
        start++;
    }
    return NULL;
}

bool is_even(int n) { return n % 2 == 0; }
bool is_positive(int n) { return n > 0; }
bool is_greater_than_10(int n) { return n > 10; }

int main() {
    int arr[] = {-5, 3, 8, 2, 15, 7};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    int* p = find_if(arr, arr + size, is_even);
    if (p) printf("第一个偶数: %d\n", *p);
    
    p = find_if(arr, arr + size, is_positive);
    if (p) printf("第一个正数: %d\n", *p);
    
    p = find_if(arr, arr + size, is_greater_than_10);
    if (p) printf("第一个大于10的数: %d\n", *p);
    return 0;
}

五、高级应用 #

5.1 策略模式 #

c
#include <stdio.h>

typedef int (*Strategy)(int, int);

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }

typedef struct {
    Strategy strategy;
    char* name;
} Calculator;

int calculate(Calculator* calc, int a, int b) {
    printf("%s: ", calc->name);
    return calc->strategy(a, b);
}

int main() {
    Calculator calculators[] = {
        {add, "加法"},
        {subtract, "减法"},
        {multiply, "乘法"}
    };
    
    for (int i = 0; i < 3; i++) {
        printf("%s\n", calculate(&calculators[i], 10, 5));
    }
    return 0;
}

5.2 事件处理 #

c
#include <stdio.h>

typedef void (*EventHandler)(int);

typedef struct {
    EventHandler onClick;
    EventHandler onHover;
    EventHandler onKeyPress;
} Button;

void handle_click(int id) {
    printf("按钮 %d 被点击\n", id);
}

void handle_hover(int id) {
    printf("鼠标悬停在按钮 %d 上\n", id);
}

void handle_key(int id) {
    printf("按钮 %d 接收到按键\n", id);
}

int main() {
    Button btn = {handle_click, handle_hover, handle_key};
    
    btn.onClick(1);
    btn.onHover(1);
    btn.onKeyPress(1);
    return 0;
}

5.3 插件系统 #

c
#include <stdio.h>

typedef void (*PluginInit)(void);
typedef void (*PluginProcess)(int);
typedef void (*PluginCleanup)(void);

typedef struct {
    PluginInit init;
    PluginProcess process;
    PluginCleanup cleanup;
    char* name;
} Plugin;

void plugin_a_init() { printf("插件A初始化\n"); }
void plugin_a_process(int data) { printf("插件A处理: %d\n", data); }
void plugin_a_cleanup() { printf("插件A清理\n"); }

void plugin_b_init() { printf("插件B初始化\n"); }
void plugin_b_process(int data) { printf("插件B处理: %d\n", data * 2); }
void plugin_b_cleanup() { printf("插件B清理\n"); }

int main() {
    Plugin plugins[] = {
        {plugin_a_init, plugin_a_process, plugin_a_cleanup, "PluginA"},
        {plugin_b_init, plugin_b_process, plugin_b_cleanup, "PluginB"}
    };
    int count = 2;
    
    for (int i = 0; i < count; i++) {
        plugins[i].init();
    }
    
    for (int i = 0; i < count; i++) {
        plugins[i].process(10);
    }
    
    for (int i = 0; i < count; i++) {
        plugins[i].cleanup();
    }
    return 0;
}

六、函数指针与结构体 #

6.1 方法模拟 #

c
#include <stdio.h>

typedef struct {
    int value;
    void (*set)(struct Number*, int);
    int (*get)(struct Number*);
    void (*print)(struct Number*);
} Number;

void number_set(Number* self, int value) {
    self->value = value;
}

int number_get(Number* self) {
    return self->value;
}

void number_print(Number* self) {
    printf("值: %d\n", self->value);
}

Number create_number(int value) {
    Number n = {value, number_set, number_get, number_print};
    return n;
}

int main() {
    Number n = create_number(10);
    n.print(&n);
    n.set(&n, 20);
    printf("获取值: %d\n", n.get(&n));
    return 0;
}

七、总结 #

函数指针语法 #

c
返回类型 (*指针名)(参数列表);

typedef简化 #

c
typedef int (*FuncType)(int, int);
FuncType p = add;

函数指针数组 #

c
int (*arr[])(int, int) = {add, subtract};

回调函数 #

c
void process(int arr[], int size, void (*callback)(int));

应用场景 #

场景 说明
回调函数 事件处理、异步操作
策略模式 运行时选择算法
插件系统 动态加载功能
菜单系统 函数映射
排序比较 qsort比较函数

下一步,让我们学习数组!

最后更新:2026-03-26