【 C 】初识函数指针

举报
李锐博恩 发表于 2021/07/15 07:32:36 2021/07/15
【摘要】 函数指针,顾名思义,也就是指针,不过这个指针是指向函数的指针。 在【 C 】高级指针话题之高级声明的演进 这篇博文中提到了函数指针的声明等,摘出来: 接下来的一个声明更有趣,但也更容易让人疑惑: int (*f)(); 确定括号的含义是分析这个声明的一个重要步骤。这个声明有两个括号,每对的含义各不相同。第2个括号是函数调用操作符,第1个括号只起到聚...

函数指针,顾名思义,也就是指针,不过这个指针是指向函数的指针。

【 C 】高级指针话题之高级声明的演进 这篇博文中提到了函数指针的声明等,摘出来:

接下来的一个声明更有趣,但也更容易让人疑惑:

int (*f)();
  

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

何为函数指针?

程序中的每个函数都位于内存中的某个位置,所以存在指向那个位置的指针是完全可能的。

如果上面的引用不清楚的话,我在试着解释一遍:

int (*f)();

 

先执行括号里面的内容,也就是间接访问操作,可见 f 是一个指针,可是之后就进行函数调用的操作,可见该指针是还不是一般的指针,该指针指向一个函数,称该指针为函数指针。

函数指针有什么用呢?最常见的两个用途是转换表(jump table)和作为参数传递给另一个函数。但是本博文不涉及其应用,只是简单地了解一下函数指针以及函数指针的初始化!


必须提出,和其他类型的指针一样,简单声明一个函数指针并不意味着可以马上使用,对函数指针执行间接访问之前必须初始化为指向某个具体的函数。而这个过程十分的有意思,下面的代码说明了一种初始化函数指针的方法:


  
  1. int f( int );
  2. int (*pf)( int ) = &f;

第2个声明创建了一个函数指针并把它初始化为指向函数 f 。这里关键的问题是:在函数初始化之前具有 f 的原型是很重要的,否则编译器就无法检测 f 的类型是否与 pf 所指向的类型一致。

下面更有意思的内容来了:

初始化表达式中的 &(取地址操作符)是可选的,因为函数名被使用时总是由编译器把它转换为函数指针。&操作符只是显式地说明了编译器隐式执行的任务。

在函数指针被声明以及初始化之后,我们就可以使用三种方式来调用函数:


  
  1. int ans;
  2. ans = f( 25 );
  3. ans = (*pf)(25);
  4. ans = pf(25);

这三种方式调用函数完成的功能是完全相同的,这看起来有些荒谬,特别是第三条,而实际上并非如你所想,下面一一道来:

第1条语句简单地使用名字来调用函数,这是我们最常用的调用函数的方法,但它的执行过程可能和你想象的不太一样。函数名f首先被转化为一个函数指针,该指针指定函数在内存中的位置。然后,函数调用操作符()调用该函数,执行开始于这个地址的代码。

第2条语句对pf执行间接访问操作,它把函数指针转化为一个函数名。这个转换并不是真正需要的,因为编译器在执行函数调用操作符之前又会把它转换回去。

第3条语句和前两天语句效果一样,只不过省去了在第1种情况下,编译器把函数名 f 转换为函数指针的过程,这里是直接执行函数在该处的代码。

仔细品味这些说明,真是大开眼界!

 

 

 

 

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/82694875

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。