typedef用于函数指针的难点

雪人2015 2011-02-10 09:21:09
帮忙解答一下:
为什么
这句代码

int (*Register (int (*pf) (const char*,const char*)))(const char*,const char*);

和下面两句代码等价

typedef int (*pF)(const char*,const char*);
pF (*Register)(pF p);




特别那后者应该如何理解?
...全文
544 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
songxueyu 2013-03-08
  • 打赏
  • 举报
回复
引用 15 楼 xujiezhige 的回复:
引用 12 楼 hhddzz 的回复因为Register是函数,所以左边的*就表示它返回指针咯 你那个pf是标识符,左边的*表示pf自己设计个指针 如果你的pf是个数组,那左边的*就表示数组的元素是指针 当然有括号和没括号是不一样的,看的顺序不同 用C++的语法来说就是 改变了操作符的优先级 double *pf(double,double); // pf是……
我觉得这是因为编译器的编译顺序。这样的话编译器就不会首先去看Register了,不会按我们想的那个顺序去编译。 它会去看第一个括号里,这里面只有一个*,没有标示符或者类型,这样就会报错了。 但是如果你能自己写一个编译器来理解这种类型的话……
mujiok2003 2011-02-11
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 hhddzz 的回复:]

解析过程就用那个“右左法则”
int (*Register (int (*pf) (const char*,const char*)))(const char*,const char*);
从Register向右看,看到一对括号(),说明Register是一个函数,括号里面的内容自然就是参数列表了
参数的类型int(*)(const char*,const char*)这是个最基本的函数指针形式,就不多说了

然后该向左看了,*,说明Register(已经确定它是一个函数了)返回一个指针,指针指向什么呢?跳出括号向右看,看到调用符号,说明指针指向函数
调用符号里面是参数列表(const char*,const char*)
这个函数的返回值是什么呢?向左看,int,说明这个函数返回值类型是int
整理一下,Register是一个函数声明,它的形参pf和返回值类型都是int(*)(const char*,const char*)
[/Quote]
完全正确. 因为是Register是一个函数(声明),所以是右值(也叫常量).
但是
typedef int (*pF)(const char*,const char*);
pF (*Register)(pF p);
,这里Register一个函数指针变量,所以本质上不等价(因为不是一个东西)。
这里有一测试程序:
#include <typeinfo>
#include <iostream>
int main()
{
int (*Register (int (*) (const char*,const char*)))(const char*,const char*);
//Register = NULL;
std::cout << typeid(Register).name() << std::endl;
typedef int (*pFun)(const char*,const char*);
typedef pFun (*RegisterFun)(pFun);
cout << typeid(RegisterFun).name() << std::endl;
return 0;
}

g++编译后运行为
FPFiPKcS0_ES2_E
PFPFiPKcS0_ES2_E

FPFiPKcS0_ES2_E说明是一个函数,PFPFiPKcS0_ES2_E说明它是一个指针

雪人2015 2011-02-11
  • 打赏
  • 举报
回复

我刚才才vs2008里面试了一下,
int(*)(const char*,const char*)Register(int(*pF)(const char*,const char*));
编译不通过。

那就这样吧。Thanks hhddzz。
hhddzz 2011-02-11
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 xujiezhige 的回复:]

引用 12 楼 hhddzz 的回复
因为Register是函数,所以左边的*就表示它返回指针咯
你那个pf是标识符,左边的*表示pf自己设计个指针
如果你的pf是个数组,那左边的*就表示数组的元素是指针

当然有括号和没括号是不一样的,看的顺序不同
用C++的语法来说就是 改变了操作符的优先级
double *pf(double,double); // pf是函数
double……
[/Quote]
这个我也不知道
雪人2015 2011-02-11
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 hhddzz 的回复]
因为Register是函数,所以左边的*就表示它返回指针咯
你那个pf是标识符,左边的*表示pf自己设计个指针
如果你的pf是个数组,那左边的*就表示数组的元素是指针

当然有括号和没括号是不一样的,看的顺序不同
用C++的语法来说就是 改变了操作符的优先级
double *pf(double,double); // pf是函数
double (*pf)(double,double); // pf是函数指针

int (*a)[10] // a是指向int[10]是指针
int *a[10] // a是有10个元素的数组,它的元素都是int*
[/Quote]

对哈,这里的Register是函数啊。有点明白了。
但是为什么返回者要那么个写法把函数名括到里面啊。为什么不这么写呢?
int(*)(const char*,const char*)Register(int(*pF)(const char*,const char*));
请帮忙解释一下?
hhddzz 2011-02-11
  • 打赏
  • 举报
回复
笔误
左边的*表示pf自己设计个指针--->左边的*表示pf自己是个指针
改变了操作符的优先级--->这个表达不准确,不知道怎么说才好。或许叫 改变了运算顺序以及操作符的结合方式?
hhddzz 2011-02-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 xujiezhige 的回复:]

引用 9# hhddzz 的回复:
然后该向左看了,*,说明Register(已经确定它是一个函数了)返回一个指针

为什么看左到*就说Register返回一个指针呢?

你看double (*pf)(double,double);
pf往左看也是*,但是返回值是int啊。
请帮忙解答一下
[/Quote]
因为Register是函数,所以左边的*就表示它返回指针咯
你那个pf是标识符,左边的*表示pf自己设计个指针
如果你的pf是个数组,那左边的*就表示数组的元素是指针

当然有括号和没括号是不一样的,看的顺序不同
用C++的语法来说就是 改变了操作符的优先级
double *pf(double,double); // pf是函数
double (*pf)(double,double); // pf是函数指针

int (*a)[10] // a是指向int[10]是指针
int *a[10] // a是有10个元素的数组,它的元素都是int*
雪人2015 2011-02-10
  • 打赏
  • 举报
回复
说错了,返回的是double
雪人2015 2011-02-10
  • 打赏
  • 举报
回复
[Quote=引用 9# hhddzz 的回复:]
然后该向左看了,*,说明Register(已经确定它是一个函数了)返回一个指针
[/Quote]
为什么看左到*就说Register返回一个指针呢?

你看double (*pf)(double,double);
pf往左看也是*,但是返回值是int啊。
请帮忙解答一下
hhddzz 2011-02-10
  • 打赏
  • 举报
回复
我最近也在学这个。我来说一下吧
首先
typedef int (*pF)(const char*,const char*);
pF (*Register)(pF p);
LZ你这个不对吧
我觉得应该是 pF Register(pF p);才对,
我做了测试,对Register赋值直接报“表达式需要是可修改的左值”,说明Register不是指针,而是函数名


解析过程就用那个“右左法则”
int (*Register (int (*pf) (const char*,const char*)))(const char*,const char*);
从Register向右看,看到一对括号(),说明Register是一个函数,括号里面的内容自然就是参数列表了
参数的类型int(*)(const char*,const char*)这是个最基本的函数指针形式,就不多说了

然后该向左看了,*,说明Register(已经确定它是一个函数了)返回一个指针,指针指向什么呢?跳出括号向右看,看到调用符号,说明指针指向函数
调用符号里面是参数列表(const char*,const char*)
这个函数的返回值是什么呢?向左看,int,说明这个函数返回值类型是int
整理一下,Register是一个函数声明,它的形参pf和返回值类型都是int(*)(const char*,const char*)

int(*)(const char*,const char*)太长了,就用typedef把它定义一下
雪人2015 2011-02-10
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 arong1234 的回复:]
你为什么要去理解前者呢?前者无非就是把类型一层一层手工解开。这种方法本来就不应该用。你既然没有能力揭开,何必故意制造障碍然后麻烦别人给你解释
[/Quote]
说明一下:
我比较喜欢搞懂一些我感兴趣的东西。可能以后会用到也说不定。

顺便回复4楼:
我是在网上搜了很多文章关于typedef,然后对其中的讲解有些不理解。然后又到网上找答案,没找到就到csdn找大哥们。

请6楼分析一下,我自己分析很久没分析出来。嘿嘿

arong1234 2011-02-10
  • 打赏
  • 举报
回复
你为什么要去理解前者呢?前者无非就是把类型一层一层手工解开。这种方法本来就不应该用。你既然没有能力揭开,何必故意制造障碍然后麻烦别人给你解释[Quote=引用 2 楼 xujiezhige 的回复:]
关键是为什么前者和后者相等。
发帖的时候发错了,特别是前者应该怎么理解?

对不起
[/Quote]
bdmh 2011-02-10
  • 打赏
  • 举报
回复
没什么不好理解的,第一个就是把第二个合成一体而已,自己想一下就明白了
上善若水邻 2011-02-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 bdmh 的回复:]
typedef int (*pF)(const char*,const char*);
这是定义了一个返回值为int的函数指针pF,其参数为(const char*,const char*);
[/Quote]

学习了.
其实这只是个函数指针的复杂应用。

int (*Register (int (*pf) (const char*,const char*)))(const char*,const char*);

//分解为
typedef int (*PF)(const char*,const char*);
PF FUN(PF fp)
{
return fp;
}
qq120848369 2011-02-10
  • 打赏
  • 举报
回复
前者不太好理解,还是用后者吧。
qq120848369 2011-02-10
  • 打赏
  • 举报
回复
你百度typedef去学习一下比较好。
雪人2015 2011-02-10
  • 打赏
  • 举报
回复
关键是为什么前者和后者相等。
发帖的时候发错了,特别是前者应该怎么理解?

对不起
bdmh 2011-02-10
  • 打赏
  • 举报
回复
typedef int (*pF)(const char*,const char*);
这是定义了一个返回值为int的函数指针pF,其参数为(const char*,const char*);


64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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