关于函数指针的调用具体过程

lj860603 2006-05-18 04:13:12
请教大家一个函数指针的问题:
首先请大家看看下面一段简单的代码:
----------------------------------------------

#include<stdio.h>

int Function(int Num);

int
main(void)
{
int (*P_Fun)(int) = &Function;

int a;

a = Function(25);
printf("%d\n", a);

a = (*P_Fun)(25);
printf("%d\n", a);

a = P_Fun(25);
printf("%d\n", a);

return 0;
}

//...

int Function(int Num)
{
int result;

result = Num * 2;

return result;
}

-----------------------------------------

打印了3个的值是一样的。
我的问题是:1.为什么a = (*P_Fun)(25);和a = P_Fun(25);结果一样?前面的间接操作符号‘*’可
以省略,那么编译器的操作过程到底对(*P_Fun)(25);和P_Fun(25);怎么样了?
2.函数指针的执行调用具体过程和一般的函数的调用过程有什么区别,有什么相同?
...全文
1767 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
rickxsx1121 2006-05-19
  • 打赏
  • 举报
回复
翻了一下<<C++ Primer Plus>>(5th), 在P218有解释:

两种写法在逻辑上是互相冲突的,只是C++允许这两种写法而已,表达同一种意思。
“在认为这种折中粗糙之前,应该想到,容忍逻辑上无法自圆其说的观点正是人类思维活动的特点”
lj860603 2006-05-18
  • 打赏
  • 举报
回复
我想这问题我已经基本明白了。根据了咕嘟大哥的回复我刚边吃饭边想,回来再看看新的回复,我发现我的想法和code_tin(代码罐头)差不多,其实咕嘟表达的意思也一样,只不过说得简单点。晕!我发现两个问题都可以用同一个答案来回答!
当然,也很感谢其他人的意见。谢谢大家啊:P
此帖子立刻结帐,加到50分!
LoveCreatesBeauty 2006-05-18
  • 打赏
  • 举报
回复
>1.为什么a = (*P_Fun)(25);和a = P_Fun(25);结果一样?前面的间接操作符号‘*’可以省略,
>那么编译器的操作过程到底对(*P_Fun)(25);和P_Fun(25);怎么样了?

P_Fun是函数指针,指向一个函数。*P_Fun代表被指向的函数本身。使用函数指针调用函数的格式可以为:(*P_Fun)(25);

也可以身略解引用操作符:P_Fun(25);这样更接近普通函数调用语法。这是由C语言的一些主要使用者建议的,完全是人为规定的惯用法。

>2.函数指针的执行调用具体过程和一般的函数的调用过程有什么区别,有什么相同?

没有不同

>(*P_Fun)(int)是一个函数指针,它的执行过程是不是不用象Function函数那样先转换成一个函
>数指针,而是就这样直接执行函数地址中的代码??这样不就等于函数指针和一般函数是等同的
>嘛。

(*P_Fun)(int)是一个函数调用表达式,P_Fun是函数指针,*P_Fun是P_Fun中保存的值——其正确值应该是一个函数地址,比如如此让函数指针保存一个函数地址P_Fun = &Function (或者 P_Fun = Function)。这样P_Fun就不是函数的地址,*P_Fun才是。(*P_Fun)(25)与Function(25)等效。通过C语言及标准参与者的努力,为了方便起见,P_Fun(25)也等同Function(25)。
yuanchuang 2006-05-18
  • 打赏
  • 举报
回复
2.函数指针的执行调用具体过程和一般的函数的调用过程有什么区别,有什么相同?
-------------------
这个我也只能表达自己的一家之言:
函数都是通过地址调用的(inline除外,所以他效率高)。至于在调用前他是变量还是常量,都一样。
我上面举的数组的例子就是想形象的表达这个意思。
yuanchuang 2006-05-18
  • 打赏
  • 举报
回复
1.为什么a = (*P_Fun)(25);和a = P_Fun(25);结果一样?
----------------
这个可以这么说:标准这两个一样,那所有的实现厂商就这么做了

就像char * = "abc";一样,你说他合法吗?我们的理解肯定不合法,但是标准说它合法,所以就合法了。
code_tin 2006-05-18
  • 打赏
  • 举报
回复
如果有说的不对的地方还请大家拍砖
作为函数
编译以后就是作为在.TEXT段内的代码存在
而函数调用的地方
会被转换成call 这个函数所在位置的编码
比如Function函数生成可执行文件后位置在0x1111
那么最后调用Function的就变成
call 0x1111
当然前后还要做些出栈入栈的操作

而使用函数指针
就是把这个0x1111存放在另外一个指针处
对于函数指针的执行
可能会比直接调用多一个取数的操作
把指针内所含地址取出
然后再call
当然经过优化的代码可能并不多任何代码

所以最终两者并没有什么差别
只是函数指针可以移动,指向不同的函数去执行
提供了一个概念上比较灵活的东西
屋顶上的老猫 2006-05-18
  • 打赏
  • 举报
回复
简单问题不要复杂化,函数指针只是单纯的函数入口地址。编译系统的词法分析决定了各种各样的茴香豆写法!

函数指针真正的用意是要在多级,跳跃式系统中使用!那也是以前的事了,现在很少用!
lj860603 2006-05-18
  • 打赏
  • 举报
回复
对于函数 是特殊情况 ...

-------------------------

斑竹的回答是啥意思啊?
lj860603 2006-05-18
  • 打赏
  • 举报
回复
谢谢大家的回答 :P
-----------------------------
2.函数指针的执行调用具体过程和一般的函数的调用过程有什么区别,有什么相同?

其实差不多,都一样了啊。
比如说int a[5]; int *p = a;
你说a[2] and p[2]有什么区别?

----------------------------------------
元传大哥说的这个我知道。可能我的问题表达有点错误,其实我是想问:Function是一般函数,它的执行过程是首先把转换为一个函数指针指向它在内存中的地址,然后再调用这函数执行地址中的代码。
那么,(*P_Fun)(int)是一个函数指针,它的执行过程是不是不用象Function函数那样先转换成一个函数指针,而是就这样直接执行函数地址中的代码??这样不就等于函数指针和一般函数是等同的嘛。
而且如果按照元创兄第一个问题说的那样,那么,函数和函数指针没有区别了,是这样吗?
fallinleave 2006-05-18
  • 打赏
  • 举报
回复
我的理解:首先,一段函数总是占用一段内存,而函数名则是该函数所占内存区的首地址。也即函数名其实也是一个指针,一个隐式的指向该函数的函数指针。
所以,P_Fun==Function,=>P_Fun(25)=Function(25)
而(*P_Fun)是取得首地址以后进行操作,对于函数名,我觉得编译器肯定也是把它翻译成地址以后进行操作的(猜得,呵呵,具体可以去查询一下编译原理),所以我觉得他们也是相同的。所以三者相同。
2.没有区别。

我记得《c++ primer》中提到过最好采用(*P_Fun)这种操作方法
jixingzhong 2006-05-18
  • 打赏
  • 举报
回复
对于函数 是特殊情况 ...
yuanchuang 2006-05-18
  • 打赏
  • 举报
回复
1.为什么a = (*P_Fun)(25);和a = P_Fun(25);结果一样?
----------------
函数名就是指针,这样知识为了使使时用两种格式的人都适应而已。你习惯其中一种,就不用去管另一种了,他们是一样的。

2.函数指针的执行调用具体过程和一般的函数的调用过程有什么区别,有什么相同?
-------------------
其实差不多,都一样了啊。
比如说int a[5]; int *p = a;
你说a[2] and p[2]有什么区别?
sharpdew 2006-05-18
  • 打赏
  • 举报
回复
可能是为了解决C++中成员函数指针初始化问题,才引入了&取函数地址,而在c中直接赋函数名就可以了,所以现在对于普通函数而言两种方式都可用。
屋顶上的老猫 2006-05-18
  • 打赏
  • 举报
回复
p_Fun加不加*号,对于编译器的词法分析已经根据 (*P_Fun)(int) = &Function确定了P_Fun为函数指针关键字。这是编译系统设计的问题!

没什么区别都是通过函数首地址进入!

你也可以直接写成(*P_Fun)() = Function
铖邑 2006-05-18
  • 打赏
  • 举报
回复
函数指针指向的内容才是函数地址
我想这个可能就是第一个问题的原因吧
铖邑 2006-05-18
  • 打赏
  • 举报
回复
1 (*P_Fun)(25);和P_Fun(25);确实是一样的,一直不知道原因
2 一般的函数地址是固定的,函数指针指向的内容才是函数地址

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧