char (*(*x())[])()

slowgrace 2009-09-26 05:45:25
char (*(*x())[])()


请问这个声明是表示函数,还是表示函数指针?

俺比较笨,请楼下的朋友说详细点,谢谢!
...全文
365 34 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiger_Zhao 2009-09-29
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hpsmouse 的回复:]下次看到有人写这种代码,直接抡起砖头……[/Quote]
slowgrace 2009-09-27
  • 打赏
  • 举报
回复
那你们看看这个帖子吧,如果不弄懂这些、不熟练本帖这些,你很多常见的语句都会蒙的。
xiaobozz 2009-09-27
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 slowgrace 的回复:]
引用 25 楼 xiaobozz 的回复:
引用 8 楼 pengzhixi 的回复:
typedef  char(*FUNPTR)();
typedef FUNPTR[] FUNPTR_ARRAY;
char (*(*x())[])()就可以写成 FUNPTR_ARRAY * x();


除了用来考试和炫耀自己的基本功外,写这样的表达式有什么好处?
可以简化的问题写成这样多清楚




这只是一种练习,通过这种练习让你对指针运算达到滚瓜烂熟、条件反射的地步。个人认为这种练习还是很必要的,毕竟在C中指针的使用比比皆是,如果不能达到超级熟练的地步,在使用C的过程中可以说步步皆是雷区。
[/Quote]

我觉得这纯粹是表达式的解释,不涉及到指针的原理,最多是一个指针类型
用typedef多么符合人的逻辑思维啊,而扩展开是编译器的工作,没必要去重复编译器的劳动。
如果大家全部都用typedef,难道大家指针就都不会用了????

2009-09-27
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 slowgrace 的回复:]
我觉得你理解的不对。这是声明不是使用!

*在这里不是当做解引用运算符,而是当做指针修饰符。()在这里是函数声明,而不是函数调用。
[/Quote]
我第一句话说的就是“按使用方式声明”……这句话我是从 Bjarne Stroustrup 那里抄来的……
这当然是声明不是使用,我的意思是说 C 的声明是以描述使用方式实现的……
forster 2009-09-27
  • 打赏
  • 举报
回复
写这个 是靠编译器玩的
考别人就是找抽。。
zxl0511 2009-09-27
  • 打赏
  • 举报
回复
哎,误人子弟啊。。。
slowgrace 2009-09-27
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 xiaobozz 的回复:]
引用 8 楼 pengzhixi 的回复:
typedef  char(*FUNPTR)();
typedef FUNPTR[] FUNPTR_ARRAY;
char (*(*x())[])()就可以写成 FUNPTR_ARRAY * x();


除了用来考试和炫耀自己的基本功外,写这样的表达式有什么好处?
可以简化的问题写成这样多清楚


[/Quote]

这只是一种练习,通过这种练习让你对指针运算达到滚瓜烂熟、条件反射的地步。个人认为这种练习还是很必要的,毕竟在C中指针的使用比比皆是,如果不能达到超级熟练的地步,在使用C的过程中可以说步步皆是雷区。
slowgrace 2009-09-27
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 hpsmouse 的回复:]
引用 21 楼 slowgrace 的回复:
引用 8 楼 pengzhixi 的回复:
typedef  char(*FUNPTR)();
typedef FUNPTR[] FUNPTR_ARRAY;
char (*(*x())[])()就可以写成 FUNPTR_ARRAY * x();


谢谢。我发现如果是自己去阅读复杂的声明,那应该“从内到外”,就是从最里面的圆括号往外读;而如果是拆分复杂的声明typedef,那就要“从外向里剥”。是不是这样?

一般来说,typedef 和一般声明的方法是一样的。去掉 typedef 关键字,你通常会发现这依旧是一个合法的声明。
另外,typedef FUNPTR[] FUNPTR_ARRAY; 这种声明办法不对。要写成 typedef FUNPTR FUNPTR_ARRAY[];
C 中的声明方法的一大特点就是“按使用方式声明”,通过描述使用方法声明标识符的类型,懂得这点以后看声明就简单多了。
例如:char (*(*x())[])()
可以从最里面看起。
首先 *x 是一个指针解引用,然后 *x() 对 *x 解引用的结果进行函数调用,这就是说,x 是一个函数指针;
然后 (*x())[] 对函数调用的返回值进行下标运算,表明返回的是一个数组(或指针);
*(*x())[] 对下标运算的结果(即数组中的元素)继续指针解引用,表示数组中的元素是指针;
(*(*x())[])() 表示对解引用的结果又可以做一次函数调用,就是说数组中的元素是函数指针;
最后 char(*(*x())[])() 说明了数组中的函数指针调用结果是一个 char。
这也算提供一种方法吧~~具体用什么办法要看个人喜好了~~
[/Quote]

我觉得你理解的不对。这是声明不是使用!

*在这里不是当做解引用运算符,而是当做指针修饰符。()在这里是函数声明,而不是函数调用。
xiaobozz 2009-09-27
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 pengzhixi 的回复:]
typedef  char(*FUNPTR)();
typedef FUNPTR[] FUNPTR_ARRAY;
char (*(*x())[])()就可以写成 FUNPTR_ARRAY * x();
[/Quote]

除了用来考试和炫耀自己的基本功外,写这样的表达式有什么好处?
可以简化的问题写成这样多清楚

slowgrace 2009-09-27
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 qingye2008 的回复:]
西西看的是啥书啊?
[/Quote]

"The C Programming Language (2nd Edition)"
2009-09-27
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 slowgrace 的回复:]
引用 8 楼 pengzhixi 的回复:
typedef char(*FUNPTR)();
typedef FUNPTR[] FUNPTR_ARRAY;
char (*(*x())[])()就可以写成 FUNPTR_ARRAY * x();


谢谢。我发现如果是自己去阅读复杂的声明,那应该“从内到外”,就是从最里面的圆括号往外读;而如果是拆分复杂的声明typedef,那就要“从外向里剥”。是不是这样?
[/Quote]
一般来说,typedef 和一般声明的方法是一样的。去掉 typedef 关键字,你通常会发现这依旧是一个合法的声明。
另外,typedef FUNPTR[] FUNPTR_ARRAY; 这种声明办法不对。要写成 typedef FUNPTR FUNPTR_ARRAY[];
C 中的声明方法的一大特点就是“按使用方式声明”,通过描述使用方法声明标识符的类型,懂得这点以后看声明就简单多了。
例如:char (*(*x())[])()
可以从最里面看起。
首先 *x 是一个指针解引用,然后 *x() 对 *x 解引用的结果进行函数调用,这就是说,x 是一个函数指针;
然后 (*x())[] 对函数调用的返回值进行下标运算,表明返回的是一个数组(或指针);
*(*x())[] 对下标运算的结果(即数组中的元素)继续指针解引用,表示数组中的元素是指针;
(*(*x())[])() 表示对解引用的结果又可以做一次函数调用,就是说数组中的元素是函数指针;
最后 char(*(*x())[])() 说明了数组中的函数指针调用结果是一个 char。
这也算提供一种方法吧~~具体用什么办法要看个人喜好了~~
qingye2008 2009-09-27
  • 打赏
  • 举报
回复
西西看的是啥书啊?
slowgrace 2009-09-27
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 pengzhixi 的回复:]
typedef  char(*FUNPTR)();
typedef FUNPTR[] FUNPTR_ARRAY;
char (*(*x())[])()就可以写成 FUNPTR_ARRAY * x();
[/Quote]

谢谢。我发现如果是自己去阅读复杂的声明,那应该“从内到外”,就是从最里面的圆括号往外读;而如果是拆分复杂的声明typedef,那就要“从外向里剥”。是不是这样?
geochway 2009-09-27
  • 打赏
  • 举报
回复
作为语法分析的例子可以,在实际编程中写出这样的代码就是变态.
slowgrace 2009-09-27
  • 打赏
  • 举报
回复
谢谢supermegaboy 。
slowgrace 2009-09-27
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 sytstarac 的回复:]
这句话声明了一个函数指针数组对吧,X是函数名吗?借助一个函数名来声明一个指针可以吗?我觉得函数名代表一个对象,而非一个类型。用一个对象来表示一个类型我觉得不妥啊。
[/Quote]

不对。声明的是一个函数。详见1楼和7楼。
开心乐源 2009-09-27
  • 打赏
  • 举报
回复
*x()看完这个,就可以知道x是函数。
Targui1989 2009-09-26
  • 打赏
  • 举报
回复
四楼正解!顶!
lzx258 2009-09-26
  • 打赏
  • 举报
回复
学习学习~~~~~~~~
飞天御剑流 2009-09-26
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 slowgrace 的回复:]
引用 7 楼 supermegaboy 的回复:
int (*(*func)(int *p))[5];
func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。


这里是不是有笔误:

你的原话是:返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。

是不是应该:返回值是指向数组的指针,所指向的数组是具有5个int元素的数组。
[/Quote]

对,是多了“的元素”三个字。

还有“但C语言的数组名是一个右值,它不能作为左值来接收另一个数组,”这句话也是错的,正确的应该是“但C语言的数组名是一个不可修改的左值,它不能作为赋值运算符的左操作数来接受另一个数组”。
加载更多回复(14)

70,019

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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