从零开始理解 C 语言函数指针与回调机制

从零开始理解 C 语言函数指针与回调机制

在 C 语言中,函数指针是一个强大的武器,它能让程序变得灵活、可扩展、解耦更好。

很多经典的系统库、驱动开发、策略模式、回调机制,都离不开它。

下面来全面理解它的原理、用法和优势。


1. 函数名本质上就是一个指针

例如:

c 复制代码
int add(int a, int b) { return a + b; }

add 的值是函数所在的内存地址,所以我们可以:

c 复制代码
int(*p)(int,int) = add;
printf("%d\n", p(10,20));

2. 函数指针的定义方式

c 复制代码
int (*op)(int, int) = NULL;

拆解:

部分 含义
int 返回值类型
(*op) op 是一个指针
(int,int) 参数类型

3. 用函数指针实现"回调函数"

所谓回调,就是:

把函数当成参数,传给另一个函数,在运行时决定调用哪个。

示例:动态选择加法或减法

c 复制代码
int add(int a,int b) { return a+b; }
int sub(int a,int b) { return a-b; }

int main()
{
    int (*op)(int,int) = NULL;
    int a=10, b=20;

    int num;
    printf("1:+  2:-  输入选择:");
    scanf("%d", &num);

    if(num == 1) op = add;
    else op = sub;

    printf("结果=%d\n", op(a,b));
}

优势:

  • 运行时才决定功能
  • 可扩展,不需要 if/else 重写代码
  • 模块解耦

4. typedef 简化函数指针

c 复制代码
typedef int (*PFUN)(int,int);

PFUN fun = add;

比写 int (*op)(int,int); 清晰太多。


5. 函数指针 + 冒泡排序 = 策略模式

c 复制代码
int less(int a, int b)    { return a < b; }
int greater(int a, int b) { return a > b; }

void sort(int *a, int len, PFUN cmp)
{
    for(int j=len-1; j>0; j--)
        for(int i=0;i<j;i++)
            if(cmp(a[i], a[i+1]))
                swap(&a[i], &a[i+1]);
}

这样我们可以:

c 复制代码
sort(a, len, less);    // 升序
sort(a, len, greater); // 降序

这就和 C++ STL 的仿函数、Python 的 key、Java 的 Comparator 一样。


6. 函数指针是驱动程序/回调机制的基础

例如:

  • Linux 中断处理回调
  • GUI 事件(按钮点击)
  • 网络回调(收到数据时触发)
  • 多线程回调(线程执行函数)

函数指针是 C 语言实现"多态"的方式。


总结

特性 描述
函数名是指针 add 本身就是地址
函数指针定义 int (*p)(int,int)
回调作用 解耦、灵活、模块化
typedef 简化 typedef int (*PFUN)(int,int)
常用场景 排序、事件驱动、系统回调

掌握函数指针,你的 C 语言功力就提升一个等级。

相关推荐
AOI小白新手上路5 小时前
韦东山 01_ARM架构与编程_2-1_处理器的区分MCU_MPU_AP_内容总结
嵌入式硬件
泡海椒5 小时前
PDF 表格样式优化:jquick-pdf 边框、圆角、背景色
java·开发语言·pdf
ysu_03145 小时前
TinyML 模型部署:从 Edge Impulse 到 STM32F103
驱动开发·stm32·嵌入式硬件·mcu·硬件架构·硬件工程·dsp开发
吴声子夜歌6 小时前
Shell编程实例——编写安全的shell脚本(二)
linux·运维·shell
Beyond_System|系统之外6 小时前
【学编程】Python基础编程题100道(21-60)
开发语言·python·算法
景熙55237 小时前
15.Java 8 Stream 流入门到实战
java·开发语言·数据结构
xiaoye-duck7 小时前
《Linux 网络编程》深入理解 IP 协议(二):网段划分、私有 IP 与 NAT 地址转换
linux·网络·ip
zx_741484818 小时前
【Linux入门】Shell 函数、正则表达式与文本处理:cut 与 awk
linux·运维·正则表达式
Zenova EdgeOS8 小时前
Linux dmesg 工业边缘实战:内核日志过滤、持久化与故障定位
linux·运维·边缘计算·工业边缘·dmesg·内核日志
金士顿8 小时前
System.Text.Json Source Generator 深度解析:为什么 Native AOT 不喜欢反射
linux·asp.net core·arm64·net·native aot