函数指针可以像一般函数一样,用于调用函数、传递参数。在如 C 这样的语言中,通过提供一个简单的选取、执行函数的方法,函数指针可以简化代码。
函数指针只能指向具有特定特征的函数。因而所有被同一指针运用的函数必须具有相同的参数和返回类型。
一个简单的例子:

#include <stdio.h>
// 函数原型
void sayHello();

//函数实现
void sayHello(){
    printf("hello world\n");
}

// main函数调用
int main() {
    sayHello();
    return 0;
}

在上面的例子中我们定义了一个函数sayHello(),sayHello()函数并没有接受任何参数,只是打印了hello,world,调用sayHello()直接使用sayHello();形式,有没有别的方法呢?

#include <stdio.h>
// 函数原型
void sayHello();

//函数实现
void sayHello(){
    printf("hello world\n");
}
// main函数调用
int main() {
    void(*sayHelloPtr)() = sayHello;
    sayHelloPtr();
    return 0;
}
~ 
void (*syaHelloPtr)(),是一个函数指针,它指向一个不接收参数且没有返回值的函数。
我们来看函数指针的一般形式:
返回值 * funcptr (函数参数) = 函数名

带参数的函数指针

#include <stdio.h>

//函数原型
void subtractAndPrint(int x, int y);
//函数实现
void subtractAndPrint(int x, int y) {
    int z = x - y;
    printf("Simon says, the answer is: %d\n", z);
}
//main函数调用
int main() {
    void (*sapPtr)(int, int) = subtractAndPrint;
    (*sapPtr)(10, 2);
    sapPtr(10, 2);
    return 0;
}

带参数和返回值的函数指针

#include <stdio.h>

// 函数原型
int subtract(int x, int y);

// 函数实现
int subtract(int x, int y) {
    return x - y;
}

// main函数调用
int main() {
  int (*subtractPtr)(int, int) = subtract;

  int y = (*subtractPtr)(10, 2);
  printf("Subtract gives: %d\n", y);

  int z = subtractPtr(10, 2);
  printf("Subtract gives: %d\n", z);
  return 0;
}

函数指针作为函数参数

#include <stdio.h>

// 函数原型
int add(int x, int y);
int subtract(int x, int y);
int domath(int (*mathop)(int, int), int x, int y);

// 加法 x+ y
int add(int x, int y) {
    return x + y;
}

// 减法 x - y
int subtract(int x, int y) {
    return x - y;
}

// 根据输入执行函数指针
int domath(int (*mathop)(int, int), int x, int y) {
    return (*mathop)(x, y);
}

// main函数调用
int main() {

// 用加法调用domath
int a = domath(add, 10, 2);
printf("Add gives: %d\n", a);

// 用减法调用domath
int b = domath(subtract, 10, 2);
printf("Subtract gives: %d\n", b);
return 0;
}

我们定义了函数int domath(int (*mathop)(int, int), int x, int y)。它第一个参数int (*mathop)(int, int)是一个函数指针,指向返回一个整数并接受两个整数作为参数的函数。我们在主函数中调用domath第一个参数参数add就会在domath函数中调用add,如果在domath中传入subtract就会调用subtract函数。

typedef的用处

函数指针类型通常相当的冗长,可以用typedef 大大的简化。
例如

typedef int (*cmpFcn)(const char *, const char *);  

该定义表示cmpFcn是一种指向函数的指针类型的名字。要使用这种指针类型时只需直接使用cmpFcn即可,不必每次把整个声明都写出来。
参考如下例子:

#include <stdio.h>

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

typedef int (*funptr)(int ,int);

int main()
{
    int a = 10;
    int b = 30;
    funptr ptr = sum;
    printf("sum = %d\n",ptr(a,b));
    return 0;
}

下面是一个在项目中的真实用例:

我们定义了函数指针mir_ioctl_fn,它返回一个int32_t的值,并且它的参数需要plugin和param,我们在函数mir_plugin_ioctl中定义了函数指针fn,在给fn经过一些操作赋值后可以直接调用fn(plugin,param).
关于函数指针的例子参考另一篇博客分析C语言声明