在C语言中,函数指针是一种指针,它存储的是函数的地址。这允许我们将函数像数据一样作为参数传递,并在需要时动态调用。这项技术在回调函数、事件驱动程序以及多态(即函数或操作符根据上下文表现出不同行为的概念)等领域非常有用。
让我们来看一个示例:
C
CODEBLOCK_ef600eea
输出结果
15
解释: 在这个程序中,我们定义了一个函数 add(),将它的地址赋给了一个函数指针 fptr,然后通过该指针调用了这个函数,从而打印出两个整数的和。
函数指针的声明
函数指针是根据它们将要指向的函数的签名来声明的。下面是函数指针声明的通用语法:
C
CODEBLOCK_0967a902
- return_type: 函数返回值的类型。
- parameter_types: 函数接收的参数类型。
- pointer_name: 函数指针的名称。
指针名称周围的括号是必须的,否则,它将被视为一个返回类型为 returntype* 且名为 pointername 的函数声明。
函数的类型由其返回类型、参数的数量和类型决定。因此,指针的声明方式必须与它后续指向的函数的签名相匹配。例如,在上面的代码中,函数指针被声明为:
C
CODEBLOCK_abf21d77
这与它后续指向的 add() 函数的签名是相匹配的。
初始化
函数指针通过赋值函数的地址来进行初始化。
C
CODEBLOCK_8b329392
我们也可以省略取地址操作符,因为函数名本身的表现就像一个常量函数指针。
C
CODEBLOCK_6894a8ba
必须赋值一个与指针声明中指定的签名相匹配的函数。否则,编译器可能会显示类型不匹配的错误。
函数指针的属性
函数指针指向的是代码而不是数据,因此与其他指针相比,函数指针有一些限制。以下是函数指针的一些重要属性:
- 指向代码段中函数的内存地址。
- 要求精确的函数签名(返回类型和参数列表)。
- 可以指向具有相同签名的不同函数。
- 不能执行算术运算,如自增或自减。
- 支持类似数组的功能,用于构建函数指针表。
应用示例
下面的程序列出了一些函数指针的常见应用及代码示例:
函数指针作为参数(回调函数)
函数指针最有用的应用之一是将函数作为参数传递给其他函数。这允许我们在运行时指定要调用哪个函数。
C
CODEBLOCK_38a6b57a
输出结果
15
5
解释: calc 函数接受一个函数指针 operation,用于对两个整数 a 和 b 执行特定操作(如加法或减法)。通过将 add 或 subtract 函数传递给 calc,可以在运行时动态执行正确的函数。
在结构体中模拟成员函数
我们可以在结构体中创建数据成员,但不能在其中定义函数。但是,我们可以定义函数指针,进而用来调用被赋值的函数。
C
CODEBLOCK_462c510a