关于c++ 函数指针的问题

写了一个测试函数测试了一下: 
#include <stdio.h>

void abc(){
    printf("abc/n");
}

void kkk(){
    printf("ddd/n");
}

void (*fun)();

int main(){
    abc();
    (&abc)();
    (*abc)();
    (*(*(*(*abc)))) ();
   
    printf("++++++ /n");
   
    (*(*(*(*(*abc)))))();
   
    (*(*(*(*(*(*abc))))))();
   
    printf("++++++ /n");
    kkk();
   
    fun = kkk;
   
    printf("before kkk /n");
    (*fun)();
   
    fun = abc;
   
    printf("before abc /n");
    (*fun)();
   
   
    printf("%x, %x, %x, %x, %x/n", kkk, &kkk, *kkk, **kkk, ***kkk);
    printf("%x, %x, %x/n", &fun, *fun, fun);
   
   
    return 1;
}

结果如下:
abc
abc
abc
abc
++++++
abc
abc
++++++
ddd
before kkk
ddd
before abc
abc
401018, 401018, 401018, 401018, 401018
404000, 401000, 401000


printf("%x, %x, %x, %x, %x/n", kkk, &kkk, *kkk, **kkk, ***kkk); 进行反汇编,结果如下:

printf("%x, %x, %x, %x, %x/n", kkk, &kkk, *kkk, **kkk, ***kkk);
  4010df:        83 ec 08                     sub    $0x8,%esp
  4010e2:        68 18 10 40 00               push   $0x401018
  4010e7:        68 18 10 40 00               push   $0x401018
  4010ec:        68 18 10 40 00               push   $0x401018
  4010f1:        68 18 10 40 00               push   $0x401018
  4010f6:        68 18 10 40 00               push   $0x401018
  4010fb:        68 2d 30 40 00               push   $0x40302d
  401100:        e8 2b 04 00 00               call   401530 <_printf>
  401105:        83 c4 20                     add    $0x20,%esp

 

以上的问题可以归结如下的问题:

int foo();
int (*pFoo)();

pFoo = foo;
pFoo = &foo;

请注意对pFoo赋值的两种形式,它们是等价的。因为对C编译器而言,函数名本身就代表函数的入口地址,所以第一种形式对C编译器是正确的。但问题是在C的语法层讲,对指针赋值而不取地址是讲不过去的,因些第二种形式也应该被允许。

这时问题出就来了:foo这个函数名倒底是什么?foo == &foo

其结果就是,编译器在处理函数名时,从逻辑上将其做为“指向自己的指针”。由此foo, &foo, *foo, **foo的值就都是一样的了。

至于为什么不允许&&foo,不光是对函数名不允许,在C里你就不可能见到这种语法形式,道理很简单:对变量取址得到变量的地址,对地址取址得到什么?这在概念上是讲不过去的。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值