找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

922

积分

0

好友

122

主题
发表于 昨天 05:44 | 查看: 0| 回复: 0

在 C 语言编程中,函数指针是一个强大且核心的概念。它指的是一个指向函数的指针变量。通过这个指针,你可以间接地调用它所指向的函数。这项技术是 C 语言实现类似 C++ 中多态(Polymorphism)功能的基础,尤其在驱动开发和操作系统内核(如 Linux 内核)中应用广泛。

当我们谈论函数时,它经过编译后会变成 CPU 可以执行的机器指令,这些指令存储在内存的特定区域(通常是只读的代码段)。函数名在编译后,本质上就代表了这个函数代码块在内存中的起始地址,一个固定的常量。

理解了这一点,函数指针的概念就清晰了:我们定义一个指针变量,让它存储某个函数的入口地址。之后,通过操作这个指针,就能达到调用对应函数的目的。这为程序设计带来了极大的灵活性,例如实现回调函数和插件架构。

每个函数都有其特定的类型。例如,对于函数 int fx(char c, double d) {return 0;},它的类型是 int(char, double)。相应地,指向这类函数的指针类型就是 int(*)(char, double)

函数指针的定义语法

那么,如何声明一个函数指针呢?其标准语法如下:

返回类型 (*指针名)(形参类型1, 形参类型2, ...) = 初始值;

关键说明:

  1. 指针名:必须是一个合法的标识符。
  2. 返回类型:若函数无返回值,此处应写 void
  3. 形参列表(形参类型1, 形参类型2, ...) 指明了指向函数的参数类型。如果函数没有参数,可以写作 ()(void)
  4. 初始值:定义时可以省略 = 初始值 部分。如果赋值,初始值必须是同类型的函数地址或 NULL

如何获取函数地址并为指针赋值?

在 C 语言中,函数名本身作为一个表达式使用时,其值就是该函数的起始地址。有趣的是,对函数名使用取地址运算符 &,得到的结果也是同一个地址。两者完全等价。

例如,对于函数 void fy(double a, double b){}

  • 表达式 fy 的值是函数起始地址,类型为 void(*)(double, double)
  • 表达式 &fy 的值同样是函数起始地址,类型也是 void(*)(double, double)

因此,为函数指针赋值时,直接用函数名或对其取地址都是正确的。

通过函数指针调用函数

得到函数指针后,调用其指向的函数有两种等价语法:

函数指针(实际调用参数1, 实际调用参数2, ...)
// 或
(*函数指针)(实际调用参数1, 实际调用参数2, ...)

第一种方式是直接通过指针调用,第二种是先解引用指针再调用。从编译器的角度来看,这两种形式产生的效果完全相同。函数调用本身也是一个表达式,拥有返回值和类型。

完整代码示例

下面我们通过一个具体例子来演示:定义一个函数指针,让它先后指向两个不同的函数,并进行调用。

// filename: function_pointer.c
#include <stdio.h>

int myadd(int x, int y) {
    printf("%d + %d = %d\n", x, y, x+y);
    return x + y;
}

int mymul(int x,int y) {
    printf("%d * %d = %d\n", x, y, x*y);
    return x * y;
}

int main(int argc, char *argv[]) {
    int value;
    // 声明一个指向 int(int, int) 类型函数的函数指针 pfun,并初始化为 NULL
    int(*pfun)(int,int) = NULL;

    pfun = myadd;  // 让 pfun 指向 myadd  函数
    pfun(1, 2);  // 使用指针直接调用 myadd 函数
    (*pfun)(3, 4);  // 使用指针解引用后调用 myadd 函数

    pfun = mymul;
    pfun(5, 6);
    (*pfun)(7, 8);

    pfun = &myadd;  // 函数取地址也同样是函数的地址。
    value = pfun(9,10);  // 将函数调用的返回值赋值给 value
    printf("pfun(9, 10) 的返回值是 %d\n", value);

    return 0;
}

将上述代码保存并编译运行,可以看到预期的结果:

weimingze@mzstudio:~$ gcc -o function_pointer function_pointer.c
weimingze@mzstudio:~$ ./function_pointer
1 + 2 = 3
3 + 4 = 7
5 * 6 = 30
7 * 8 = 56
9 + 10 = 19
pfun(9, 10) 的返回值是 19

进阶思考:函数指针数组

掌握了单个函数指针后,可以挑战一个更实用的结构:函数指针数组。它允许你将多个相同签名的函数组织在一起,通过索引来动态选择并调用,这在实现状态机或命令表时非常有用。

定义函数指针数组的语法如下:

返回类型 (*数组名[元素个数])(形参类型1, 形参类型2, ...) = {初始值1, 初始值2, ...};

动手实验:
尝试定义一个包含三个元素的函数指针数组,让每个元素指向一个参数和返回值类型相同的不同函数。然后编写一个循环,遍历这个数组,并依次调用每个函数指针所指向的函数。这个练习能帮助你深刻理解如何批量管理并动态调用函数,是迈向高级 C 语言编程的重要一步。

希望这篇关于 C 语言函数指针的解析能帮助你打下坚实的基础。如果你想深入探讨更多关于 C/C++ 的底层细节或系统设计模式,欢迎在云栈社区与我们交流。




上一篇:Coze平台Skill制作指南:手把手教你将智能体转技能
下一篇:Kimi K2.5智能体Agent深度测试:从视觉编程到一体化模型路线解析
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-1 00:15 , Processed in 1.286456 second(s), 47 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表