目录

一、函数指针是什么?

二、结构体中的函数指针


一、函数指针是什么?

函数指针是指向函数指针变量。 通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数函数指针可以像一般函数一样,用于调用函数、传递参数。

正确形式:int (*f) ( );

这个声明有两对括号,每对的含义各不相同。第2对括号是函数调用操作符,但第1对括号只起到聚组的作用。它迫使间接访问在函数调用之前进行,使f成为一个函数指针,它所指向的函数返回一个整型值。

容易混淆的地方:int (*f)(); 与 int * f ();

两者看似只相差了一个(),但是在编译器看来却是两种截然不同的情况。

首先我们知道

1、函数名代表这个函数的入口,也就是首地址。

2、符号’ * ‘在不同的情况下有不同的含义。声明时:加上 * 表示这个变量是一个指针。调用时:加上 * 表示访问指针;

#include int a = 1;int * p = &a; /* 这里我们分成4个部分来看。左边是3个部分:'int','*','p',右边是'&a。 * 习惯上我们以 从右往左 的顺序来解读 左边 部分。 * p :变量p * *p :表示p是一个指针,它的值是会被当做地址处理,而不是一个数值 * int * p : 表示变量p所保存的地址指向的是int类型的数,帮助编译器确定类型 * &a : 取a的地址 */   int main(){printf("*p = %d",*p);}

输出结果:

结合上面的例子我们来分析一下int (*f) () 与int *f ();

二者与int * p一个明显的不同之处就在于f的后面跟了()。这代表它可以输入参数,也就是说 f 表示某个函数的入口。

int * f () 与 int * p类似,代表函数f()的返回值是 指针。这个指针指向int类型。

int (*f) () :表示 f 是一个指向函数的指针,该函数没有参数并返回 int 值。

int *f () :表示 f 是一个函数,它不接受任何参数,并返回指向 int 值的指针。

  • 函数指针的调用方式
void test(int);int main(void){    void (*fp)(int);    fp=test;        (*fp)(9);   //调用方式一:函数指针      fp(9);      //调用方式二:函数指示符    return 0;}void test(int a){  printf( "%d\n", a );}输出结果:99

这两种形式是等价的。

这是因为在 C/C++ 中总是使用函数指针的形式来调用函数。即使在函数调用中使用的是函数指示符(代表函数类型), 也会被转换为函数指针使用,这就是默认的 function-to-pointer 转换。

尽管二者等价,但个人还是比较推荐用函数指针的形式来调用函数。

二、结构体中的函数指针

函数指针可以作为结构体的成员使用。

以下是使用示例

void Dance_func(){  printf("Xiao Ming is dancing!\n");}void Sing_func(int i) {  printf("Xiao Ming Sang %d Songs.\n", i);}typedef struct {  void (*dance)();   //函数指针的正确形式  void (*sing)(int i);  //void * sing (int i);  错误形式,无法通过编译} student;int main(void){  student Xiao_Ming;  Xiao_Ming.dance = Dance_func; //对结构体变量的赋值。函数名Dance_func是指针  Xiao_Ming.dance();            //调用Dance_func()  Xiao_Ming.sing = Sing_func;   //同上  Xiao_Ming.sing(3);  return 0;}输出结果:Xiao Ming is dancing!Xiao Ming Sang 3 Songs.

注意:

  Xiao_Ming.dance = Dance_func; //对结构体变量的赋值。函数名Dance_func是指针  Xiao_Ming.dance();            //调用Dance_func()

二者只相差一个括号,但是意义不同。