函数指针与函数名

迷惑很久的问题了,今天正好又遇到这个问题,就抽了个时间研究总结了一下把它记录下来。

和同学讨论一个typedef的问题,实验过程中偶然发现VS2005的行为:

int fun(){
    cout << "fun()" <<endl;
    return 43;
}

int (*callback())(){//对    
     return fun; //returns function pointer
}

int (callback())(){//不对,报错:function returns function
           return fun; //returns function
}

C99中的一个例子:

typedef int F(void);            // type F is "function with no parameters
                                            // returning int"
F f, g;                                  // fand g both have type compatible with F
F f { /* ... */ }                     // WRONG: syntax/constraint error
F g() { /* ... */ }                  // WRONG: declares that g returns a function
int f(void) { /* ... */ }         // RIGHT: f has type compatible with F
int g() { /* ... */ }               // RIGHT: g has type compatible with F

F *e(void) { /* ... */ }        // e returns a pointer to a function
F *((e))(void) { /* ... */ }  // same: parentheses irrelevant
int (*fp)(void);                  // fp points to a function that has type F
F*Fp;                                //Fp points to a function that has type F

typedef int F(void);和typedef int (*F)(void);含义是不同的。

还可以这样int (*G)(void);这是声明了一个函数变量G,它不是个类型只是个对象。

因此可以对它赋值但不能用它定义变量。

int  f(int);

int  (*pf)(int) = &f;

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

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

int  ans;

ans = f(25);

ans = (*pf)(25);

ans = pf(25);

第一条语句简单地使用名字调用函数f,但他的执行过程可能和你想像的不太一样。函数名f首先被转换为一个函数指针,该指针制定函数在内存中的位置。然后,函数调用操作符调用该函数,执行开始与这个地址的代码。

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

第三条语句和前两条的效果一样。间接访问操作并非必须,因为编译器需要的是一个函数指针。这个例子显示了函数指针通常是如何使用的。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值