理解函数指针

  在学习函数指针, 我遇到了问题,  我定义一个指针指向负责打印参数的函数,  

 1 void (*p)( int ) = Fun; 

好奇该指针存放的是什么( 原以为是函数的入口地址),便调试观察一下他们的内存,   Fun的值是 函数入口地址 0x00401030 Fun(int),   而p的值是函数指针存放的内容 0x00401005 _Fun。   竟然不一样。 

     难道说0x00401005是函数名Fun所存放的内存地址? 

   看来我们在弄懂函数指针前, 需要知道函数名是个什么鬼? )

     首先它是个标识符, 其次它是一个常量指针, 因为当我试图把 3 赋值给Fun, 编译器告诉我warning C4047: '=' : 'void (__cdecl *)(int )' differs in levels of indirection from 'const int '。  这是一个函数指针。    我查看下资料, 函数名被使用时总是由编译器把它转换为函数指针。 在这里, 函数名标识了一个函数指针常量。

     接下来,我们探讨函数指针是什么鬼? 

     按理论讲,函数指针指向函数的入口地址。 查看汇编代码, 我在调用Fun处设置个断点, 然后进入这个函数,我发现没有直接进入,如图

 @ILT+0(_Fun): 00401005 E9 26 00 00 00 jmp Fun (00401030) 

它是跳转到我的Fun函数。  所以,函数指针指向的是跳转命令所在地址。 这不就和书本上的矛盾了。  我又尝试了一下strcmp函数, 这是一个库函数,是否也是这样呢?  于是,我写了一个字符串比较, 

    

 1 #include <string.h>
 2 #include <stdio.h>
 3 
 4 void
 5 main ()
 6 {
 7     int (*p)( const char *, const char * ) = strcmp;
 8     char *str1 = "afdf";
 9     char *str2 = "afdf";
10     
11     if ( !p( str1, str2 ) ){
12         printf( "same\n" );
13     }
14 }

调试时进入汇编界面, 在If判断语句处设置断点,进入p。我 发现直接进入strcmp函数内,

--- intel\strcmp.asm  ----------------------------------------------------------
strcmp:
0040D830 8B 54 24 04          mov         edx,dword ptr [esp+4]
0040D834 8B 4C 24 08          mov         ecx,dword ptr [esp+8]

奇怪,这跟刚才执行跳转命令不一样。为什么?  这是我自己的想法。  因为库函数已经指定了函数所在的路径, 而用户函数没有,所以需要临时跳转到用户函数的入口地址。

最后,归纳一下,  如果是库函数, 函数指针指向函数入口处; 如果是用户函数, 函数指针指向跳转到用户函数的指令所在地址。     把跳转指令看作用户函数的一部分,其实就和书本上的不矛盾。   所以,  结论是  函数指针指定了函数所在内存的位置。

 

          

  

 

转载于:https://www.cnblogs.com/the-one/p/4671274.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值