[函数] 一个函数指针的问题

[函数] 一个函数指针的问题 [复制链接]
0 0

帖子
100
主题
34
精华
0
可用积分
27
信誉积分
100
专家积分
0
在线时间
0 小时
注册时间
2003-09-19
最后登录
2007-03-09
论坛徽章:
0
跳转到指定楼层
1[收藏(0)][报告]
  发表于 2006-02-18 14:59:48  | 只看该作者  | 倒序浏览
书上说 int (*comp)(int) 是定义一个指向函数的指针,comp是指针,*comp是一个函数,调用时,用(*comp)(a)
但是我试了下面两个程序,都一样

  1. void test(int);

  2. main(){
  3.         void (*fp)(int);
  4.         fp=test;
  5.         (*fp)(9);
  6.          return 0;
  7. }

  8. void test(int a)
  9. {
  10.     printf( "%d\n", a );
  11. }
复制代码


  1. void test(int);

  2. main(){
  3.         void (*fp)(int);
  4.         fp=test;
  5.         fp(9);
  6.          return 0;
  7. }

  8. void test(int a)
  9. {
  10.     printf( "%d\n", a );
  11. }
复制代码


第二个直接用fp(9)就可以调用函数。两个程序的结果相同,就连gcc -S fun.c的输出结果也完全相同。为什么?哪种才是正确的?
 
   

Rank: 1

帖子
425
主题
31
精华
3
可用积分
416
信誉积分
104
专家积分
0
在线时间
8 小时
注册时间
2005-03-24
最后登录
2012-12-05
论坛徽章:
0
2[报告]
  发表于 2006-02-18 15:56:06  | 只看该作者
这两种形式是等价的,都是为ANSI C所接受的。

历史上,贝尔实验室的C和UNIX的开发者采用的是第一种观点
(*fp)(9);

而Berkeley的UNIX的扩展者采用第二种观点
fp(9);

K&R C不允许第二种形式。
但是为了保持与现有代码的兼容性,ANSI C把这两者作为等价形式全部接受。
A New GNU/Linux Distribution.

 
   

Rank: 7Rank: 7Rank: 7

帖子
1920
主题
13
精华
6
可用积分
2182
信誉积分
100
专家积分
28
在线时间
9 小时
注册时间
2004-02-01
最后登录
2010-10-02
论坛徽章:
0
3[报告]
  发表于 2006-02-18 22:24:29  | 只看该作者
正如 kernelxu 所言,按照标准 C 的规定两种函数调用方式都是正确的。

这是因为在 C/C++ 中总是使用函数指针的形式来调用函数。即使在函数调用中使用的是函数指示符(代表函数类型),也会被转换为函数指针使用,这就是默认的 function-to-pointer 转换。

例如,楼主程序中的 test 函数可以直接使用函数指示符形式来调用:test( 9 );。然而,在这里的函数指示符 test 其实被编译器自动转换为了函数指针来使用,既从函数类型转换为了函数指针类型,最终是使用函数指针的形式来完成对函数调用的。

程序中的 fp( 9 ); 是直接使用函数指针 fp 来调用。既然 fp 已经是函数指针了,所以在类型上就不需要任何转换了。

(*fp)( 9 ); 也是合法的函数调用。在这里,fp 是函数指针,所以 *fp 是对于函数的引用,是函数类型。根据标准规定的 function-to-pointer 转换又把 *fp 由函数类型转换为了函数指针类型,所以实际上 (*fp)( 9 ); 相当于 fp( 9 ); 这种直接的函数指针调用方式。

另外,test 函数也可这样调用:(*test)( 9 );。可以这样来理解:根据  function-to-pointer 转换规定首先 test 由函数类型转换为函数指针,那么 *test 表示的又是函数类型,最后又根据  function-to-pointer 转换为函数指针来调用函数。这其实和 (*fp)( 9 ); 是等价的。

甚至 test 函数还可以这样调用:(**test)( 9 );、(***test)( 9 );、(****test)( 9 ); 等等,或者函数指针形式:(**fp)( 9 );、(***fp)( 9 );、(****fp)( 9 ); 等等。对此的理解可参看上段中的分析。

从上面的分析可以看出,函数调用的时候可以使用函数指针的方式,也可以使用函数指示符的方式。不过,后者会由编译器自动转换为前者的形式,即函数指针的形式。和指向对象的指针相比,这是函数指针一个比较特殊的地方。
已有 1 人评分 可用积分 收起理由
 lenovo + 2 我很赞同

总评分: 可用积分 + 2   查看全部评分

 
   
扬子江  该用户已被删除
4[报告]
  发表于 2006-02-18 22:30:25  | 只看该作者
提示:  作者被禁止或删除 内容自动屏蔽
 
   

帖子
81
主题
7
精华
0
可用积分
92
信誉积分
102
专家积分
0
在线时间
14 小时
注册时间
2005-10-02
最后登录
2010-09-26
论坛徽章:
0
5[报告]
  发表于 2006-02-18 22:45:45  | 只看该作者
个人喜欢第一种
 
   
【光环使者】

Rank: 1

帖子
990
主题
30
精华
0
可用积分
379
信誉积分
127
专家积分
0
在线时间
7 小时
注册时间
2005-03-07
最后登录
2015-01-06
论坛徽章:
0
6[报告]
  发表于 2006-02-19 17:22:19  | 只看该作者
whyglinux 说的不错啊
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值