【 C 】初识函数指针
函数指针,顾名思义,也就是指针,不过这个指针是指向函数的指针。
在【 C 】高级指针话题之高级声明的演进 这篇博文中提到了函数指针的声明等,摘出来:
接下来的一个声明更有趣,但也更容易让人疑惑:
int (*f)();
确定括号的含义是分析这个声明的一个重要步骤。这个声明有两个括号,每对的含义各不相同。第2个括号是函数调用操作符,第1个括号只起到聚组的作用。它迫使间接访问在函数调用之前进行,使 f 成为一个函数指针,它所指向的函数返回一个整型值。
何为函数指针?
程序中的每个函数都位于内存中的某个位置,所以存在指向那个位置的指针是完全可能的。
如果上面的引用不清楚的话,我在试着解释一遍:
int (*f)();
先执行括号里面的内容,也就是间接访问操作,可见 f 是一个指针,可是之后就进行函数调用的操作,可见该指针是还不是一般的指针,该指针指向一个函数,称该指针为函数指针。
函数指针有什么用呢?最常见的两个用途是转换表(jump table)和作为参数传递给另一个函数。但是本博文不涉及其应用,只是简单地了解一下函数指针以及函数指针的初始化!
必须提出,和其他类型的指针一样,简单声明一个函数指针并不意味着可以马上使用,对函数指针执行间接访问之前必须初始化为指向某个具体的函数。而这个过程十分的有意思,下面的代码说明了一种初始化函数指针的方法:
int f( int );
int (*pf)( int ) = &f;
第2个声明创建了一个函数指针并把它初始化为指向函数 f 。这里关键的问题是:在函数初始化之前具有 f 的原型是很重要的,否则编译器就无法检测 f 的类型是否与 pf 所指向的类型一致。
下面更有意思的内容来了:
初始化表达式中的 &(取地址操作符)是可选的,因为函数名被使用时总是由编译器把它转换为函数指针。&操作符只是显式地说明了编译器隐式执行的任务。
在函数指针被声明以及初始化之后,我们就可以使用三种方式来调用函数:
int ans;
ans = f( 25 );
ans = (*pf)(25);
ans = pf(25);
这三种方式调用函数完成的功能是完全相同的,这看起来有些荒谬,特别是第三条,而实际上并非如你所想,下面一一道来:
第1条语句简单地使用名字来调用函数,这是我们最常用的调用函数的方法,但它的执行过程可能和你想象的不太一样。函数名f首先被转化为一个函数指针,该指针指定函数在内存中的位置。然后,函数调用操作符()调用该函数,执行开始于这个地址的代码。
第2条语句对pf执行间接访问操作,它把函数指针转化为一个函数名。这个转换并不是真正需要的,因为编译器在执行函数调用操作符之前又会把它转换回去。
第3条语句和前两天语句效果一样,只不过省去了在第1种情况下,编译器把函数名 f 转换为函数指针的过程,这里是直接执行函数在该处的代码。
仔细品味这些说明,真是大开眼界!
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/82694875
- 点赞
- 收藏
- 关注作者
评论(0)