【非作业贴】请C++内功深厚的高手帮忙,C++使用《右左法则》理解函数声明,题目解答!

别逗我乐 2010-06-06 10:13:03
【非作业贴】请C++内功深厚的高手帮忙,C++使用《右左法则》理解函数声明,题目解答!
声明:
以下实例,系书籍以及互联网,本人只是收集学习用。本贴绝非作业贴,请大家放心食用!
我是c++爱好者,喜欢纠结细节。收集了一下,函数指针的例子,只可惜天下文章一大抄,出处并无确切答案,于是乎自己做了解答,不知道对不对,欢迎大家指正,谢谢。
The right-left rule
Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in

the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.
One small change to the right-left rule: When you start reading the declaration for the first time, you have to start from the identifier, and not the innermost parentheses.
右左法则
法则运用如下:从最内部的括号开始阅读声明,向右看,然后向左看。当你碰到一个括号时就调转阅读的方向。括号内的所有内容都分析完毕就跳出括号的范围。这样继续,直到整个声明都被分析完毕


对上述“右左法则”做一个小小的修正:当你第一次开始阅读声明的时候,你必须从变量名开始,而不是从最内部的括号。

1.
int (*ff(int)) (int *,int);
//等价于
typedef int (*pf)(int *,int);
pf (*ff)(int);

2.
int (*Register (int (*pf)(const char *, const char *))) (const char *, const char *)
//等价于
typedef int (*pf)(const char *, const char *);
pf Register(pf);

3.
int * (* (*fp1) (int) ) [10];
//等价于
typedef int* (*pf)[10];
typedef pf (*fp1)(int);

4.
int *( *( *arr[5])())();
//等价于
typedef int* (*fp)();
typedef fp (*fp1)();
fp1 (*arr)[5];

5.
float ( *( *b())[] )();
//等价于
typedef float (*pf)();
typedef pf (*parr)[];
parr b();

6.
void * ( *c) ( char, int (*)());
//等价于
typedef int (*pf)()
typedef void* (*c)(char,pf);

7.
void ** (*d) (int &, char **(*)(char *, char **));
//等价于
typedef char** (*pf)(char *, char **);
typedef void** (*d) (int &, pf);

8.
float ( * ( * e[10])(int &) ) [5];
//等价于
typedef float (*parr)[5];
typedef parr (*pf)(int &);
pf e[10];

9.
double (*)()(*e)[9];
//等价于
typedef double (*pf)();
pf (*e)[9];

10.
int*(*a[5])(int,char *);
//等价于
typedef int* (*pf)(int,char *);
pf a[5];


先谢谢 各位大侠!!!!
回帖就给分!!!!!!
...全文
1570 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
elnjjygsblm 2010-07-07
  • 打赏
  • 举报
回复
说不清,自己去看:ht-tp://lil.cx/hTU3Ju
jeam0402 2010-06-10
  • 打赏
  • 举报
回复
接分~接分~
figo1688 2010-06-09
  • 打赏
  • 举报
回复
留名,学习学习
cjl20090909 2010-06-09
  • 打赏
  • 举报
回复
留名,学习学习
wddrosa 2010-06-09
  • 打赏
  • 举报
回复
太纠结了 int (*ff(int)) (int *,int);
我的理解 ff是指向只有一个int参数的函数指针而这个指针指向有两个参数的函数
lhsxsh 2010-06-08
  • 打赏
  • 举报
回复
收藏了。不错
taodm 2010-06-08
  • 打赏
  • 举报
回复
不要浪费精力在这个话题上。
cyforever4842 2010-06-08
  • 打赏
  • 举报
回复
"int (*ff(int)) (int *,int);"

斗胆说一句,这样写的程序员,绝对不是好的程序员
别逗我乐 2010-06-06
  • 打赏
  • 举报
回复
发一下,改正的
1.
int (*ff(int)) (int *,int);
//等价于
typedef int (*pf)(int *,int);
pf ff(int);

2.
int (*Register (int (*pf)(const char *, const char *))) (const char *, const char *)
//等价于
typedef int (*pf)(const char *, const char *);
pf Register(pf);

3.
int * (* (*fp1) (int) ) [10];
//等价于
typedef int* (*pf)[10];
typedef pf (*fp)(int);
fp fp1;


4.
int *( *( *arr[5])())();
//等价于
typedef int* (*fp)();
typedef fp (*fp1)();
fp1 (*arr)[5];

5.
float ( *( *b())[] )();
//等价于
typedef float (*pf)();
typedef pf (*parr)[];
parr b();

6.
void * ( *c) ( char, int (*)());
//等价于
typedef int (*pf)()
typedef void* (*pf1)(char,pf);
pf1 c;

7.
void ** (*d) (int &, char **(*)(char *, char **));
//等价于
typedef char** (*pf)(char *, char **);
typedef void** (*pf1) (int &, pf);
pf1 d;

8.
float ( * ( * e[10])(int &) ) [5];
//等价于
typedef float (*parr)[5];
typedef parr (*pf)(int &);
pf e[10];

9.
double (*)()(*e)[9];
//等价于
typedef double (*pf)();
pf (*e)[9];

10.
int*(*a[5])(int,char *);
//等价于
typedef int* (*pf)(int,char *);
pf a[5];
别逗我乐 2010-06-06
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 crysleeper 的回复:]
1.wrong
2...没有多大问题,只是两个并不完全等价,原来是有变量名的
3.wrong 多typedef
4.wrong int* []和int (*)[]是不同的类型
5.wrong 同4
6.wrong 同3
7.wrong 同3
8.right!
9.wrong!编译都不通过,可能是要double (* (*e)[9])();不要光拍脑袋想问题,实践一样重要
10.r……
[/Quote]

9是对的,gcc可以通过。
我想说,不能只看编译器的结果,不能为准!
tananade 2010-06-06
  • 打赏
  • 举报
回复
up~~~
zhangzhongke007 2010-06-06
  • 打赏
  • 举报
回复
学习学习。
CrySleeper 2010-06-06
  • 打赏
  • 举报
回复
1.wrong
2...没有多大问题,只是两个并不完全等价,原来是有变量名的
3.wrong 多typedef
4.wrong int* []和int (*)[]是不同的类型
5.wrong 同4
6.wrong 同3
7.wrong 同3
8.right!
9.wrong!编译都不通过,可能是要double (* (*e)[9])();不要光拍脑袋想问题,实践一样重要
10.right
huang_liang 2010-06-06
  • 打赏
  • 举报
回复
左右法则适合程序分析,不适合人。你说的那个更正并不必须的,只是更方便人使用。
给你对人来说一个更简单的法则:模式匹配

1.找到变量名。程序不容易做,人比较容易。
2.除开变量名后,是它的类型声明,可能有四种复杂, 四种简单模式(为了形式上完整)
其中空格是变量的位置, ???可能是比较复杂东西。
???(* )??? 变量是指针
???( )???或??? ??? 变量是值或数组, 前一种形式括号是多余的.
???(* (???))??? 变量是函数声明,返回类型是指针,指向括号外面的部分
???(* [???])??? 变量是数组,数组类型是指针,指向括号外面的类型
type ; 简单变量type = char/short/long/int/float/struct/union/emnu等
type * 指针,指向type
type [XX]??? type的数组,
type (???) 函数
3.把已经识别的部分看成变量
4.如果余下的部分, 返回第2步.

例如:
int (*ff(int)) (int *,int); => 结果
step 1. 找到ff. 变量ff是...
step 2. 满足???(* (???))??? 函数声明, 参数是(int), 返回值是指针, 指向...
step 3. 除去已经识别部分int (int *, int)
step 2. 满足type (???) 函数, 参数是(int*, int)

int (*Register (int (*pf)(const char *, const char *))) (const char *, const char *)
step 1.找到pf, 这个是找错了,不过没关系.
step 2.满足???(*)???, pf是指针,指向...
step 3.剩下int (*Register (int ^(const char*, const char*)))( const char*, const*)
我用^标出的变量的位置,
step 2.满足??? (???), 是函数
step 3.剩下int (*Register (^))(const char*, const*),
step 2.满足???( )???, 说明是类型, 但注意pf是函数,函数不能再是一个值或数组.所以pf变量其实
不是真正的变量, 所以需要退回上一步,再找一下变量这次可以找出Register
step 1.找出Register
step 2.除出Register得到int (* (pf))(const char*, const*), Register是函数声明, 返回值指向...
step 3.剩下int (const char*, const*) 是函数
-----
题外话,如果先找到Register就比较简单,直接说明它是函数, 返回值是...


float ( * ( * e[10])(int &) ) [5];
变量e, 第一次找到???(* [???])???, e是数组, 成员是...
float ( * (int &) ) [5]; +++ ???(* (???))???, 函数指针, 返回类型是指针, 指向
float [5]; +++ float数组
别逗我乐 2010-06-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 arong1234 的回复:]
好吧,如果你认为这是基础的话。老实说,我一向把这个看作垃圾代码,从来不当作是基础

引用 9 楼 jsjrj01 的回复:
大哥,额在学习基础好吧,了解了后,才能读懂,才能自己避免!!
[/Quote]

拿什么是基础ne ?

你给指条路吧,大侠
cs_yagami 2010-06-06
  • 打赏
  • 举报
回复
函數指標喔...
你只要會第一個就夠了,其他的看看就好,會了也用不到..
zqfddqr 2010-06-06
  • 打赏
  • 举报
回复
...jF拉哈哈哈
arong1234 2010-06-06
  • 打赏
  • 举报
回复
好吧,如果你认为这是基础的话。老实说,我一向把这个看作垃圾代码,从来不当作是基础[Quote=引用 9 楼 jsjrj01 的回复:]
大哥,额在学习基础好吧,了解了后,才能读懂,才能自己避免!!
[/Quote]
别逗我乐 2010-06-06
  • 打赏
  • 举报
回复
大哥,额在学习基础好吧,了解了后,才能读懂,才能自己避免!!
别逗我乐 2010-06-06
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 arong1234 的回复:]
什么时候你懂得如何避免纠结,而不是在纠结状态下如何理解,你就进步了。好的程序员一定有办法避免进入让自己都搞不明白的境地

就如同5楼你举的两个例子,如果你一开始就用typedef,何必要判断前面哪个东西到底和哪个typedef的结果等价?
[/Quote]

加载更多回复(18)

64,643

社区成员

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

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