求助。。int *(*(*aryCallback)(int *(*)[n]))[n];

stardust20 2009-10-27 10:59:55
在《C++程序设计陷阱》P89
中看到
int *(*(*aryCallback)(int *(*)[n]))[n];
还有解释(这里的解释就看不懂了,高手帮忙解释下,先谢谢了)
这当然是指向函数的指针,而这个函数用指向数组的指针作为参数,这个数组由指向int的n个指针构成,而且这个函数返回相同类型的指针。
用typedef,可以极大地简化这段代码
typedef int *(*PA)[n];
PA (*aryCallback)(PA);
高手帮忙解释下,先谢谢了。。。。
...全文
240 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
myhder 2009-10-28
  • 打赏
  • 举报
回复
nwpulei 2009-10-28
  • 打赏
  • 举报
回复
膜拜
  • 打赏
  • 举报
回复
"上一章费那么多唇舌讨论C语言的声明"

你写的是一本书,还是一个系列的专题文章。可以把书名或者所有文件的目录链接给出来么。
这文章不错,可以加深内功。
zgjxwl 2009-10-28
  • 打赏
  • 举报
回复
typedef int *(*PA)[n];      // 定义一个类型别名PA,而PA又是什么类型呢。它首先是指向一个数组,;
// 另外数组的每个元素都是int类型的指针。综上,这是定义一个指向元素类型
// 为int*,大小为n的数组的指针的别名,即PA,也就是说,一出现PA,
// 它就是定义了一个这样的数组指针
PA (*aryCallback)(PA); // 很明显,这是定义一个函数指针,具体的说,是定义一个指向返回类型为PA,并
// 仅带一个参数,参数类型为PA的函数指针。而PA一出现,上面也说了,就是定义了
// 一个指向一个大小为n,元素类型为int*类型的数组指针。综上,这句可这么说
// 定义一个返回类型为 一个指向一个大小为n,元素类型为int*类型数组的指针 类型
// 并仅带有 一个指向一个大小为n,元素类型为int*类型数组的指针 类型作为参数的函数指针
ljz888666555 2009-10-28
  • 打赏
  • 举报
回复
这么复杂的用途不大,用动态载入DLL时会用到一个简单的,
ulovexd 2009-10-28
  • 打赏
  • 举报
回复
考,谁能举出这个int *(*(*aryCallback)(int *(*)[n]))[n];
的具体应用?
ztenv 版主 2009-10-28
  • 打赏
  • 举报
回复
接分了。。。。。不再班门弄斧了
Johnny_Lx 2009-10-28
  • 打赏
  • 举报
回复
这个你一层层慢慢分析就行了,谁都不能说一眼就能看出来的,加油
yshuise 2009-10-28
  • 打赏
  • 举报
回复
up
zhusizhi007 2009-10-28
  • 打赏
  • 举报
回复
学习中,
GoForSky 2009-10-28
  • 打赏
  • 举报
回复
3楼的供大家学习,保留!!!

不过这样的问题,没意思,谁的代码这样写。
纯粹玩酷的
飞天御剑流 2009-10-28
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jiazhen 的回复:]
"上一章费那么多唇舌讨论C语言的声明"

你写的是一本书,还是一个系列的专题文章。可以把书名或者所有文件的目录链接给出来么。
这文章不错,可以加深内功。
[/Quote]

是一系列写数组与指针的文章,最近正在修改,改好会放到blog里。
wangyang327329 2009-10-28
  • 打赏
  • 举报
回复
int *(*(*aryCallback)(int *(*)[n]))[n];

对于(int *(*)[n])的部分是一个int*的列长度为n的二维指针;
然后(*aryCallback)(int *(*)[n])是一个函数调用,这时(int *(*)[n])是这个函数的参数,而
aryCallback是某个函数的指针,这个函数返回的是二维数组(这个二维数组的列长度为n)的指针,所以
这时一个二维数组指针的声明
butwang 2009-10-27
  • 打赏
  • 举报
回复
学习
perfecttt 2009-10-27
  • 打赏
  • 举报
回复
返回一个整型数组的参数为int *(*)[n]函数指针,参数为int *(*)[n]是一个指向指针的n维的指针数组。
从外朝里脱衣服。
mstlq 2009-10-27
  • 打赏
  • 举报
回复
既然3楼出现了……
那我就不掺和了……

围观膜拜^_^
飞天御剑流 2009-10-27
  • 打赏
  • 举报
回复
int *(*(*aryCallback)(int *(*)[n]))[n];
-------------------------------------------
aryCallback是一个函数指针,所指向函数的形参是指向指针数组的指针,该指针数组的元素类型为int*。aryCallback指向的函数的返回值也是指向指针数组的指针,元素类型同样为int*。


下面是我05年写的一篇文章,希望可以帮助你阅读这类复杂的指针:



上一章费那么多唇舌讨论C语言的声明,其实目的都是为了这一章,期望读者通过对C语言声明形式的详细了解,树立声明嵌套的观念,因为C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是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.


这段英文的翻译如下:

右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。

笔者要对这个法则进行一个小小的修正,应该是从未定义的标识符开始阅读,而不是从括号读起,之所以是未定义的标识符,是因为一个声明里面可能有多个标识符,但未定义的标识符只会有一个。

现在通过一些例子来讨论右左法则的应用,先从最简单的开始,逐步加深:

int (*func)(int *p);

首先找到那个未定义的标识符,就是func,它的外面有一对圆括号,而且左边是一个*号,这说明func是一个指针,然后跳出这个圆括号,先看右边,也是一个圆括号,这说明(*func)是一个函数,而func是一个指向这类函数的指针,就是一个函数指针,这类函数具有int*类型的形参,返回值类型是int。

int (*func)(int *p, int (*f)(int*));

func被一对括号包含,且左边有一个*号,说明func是一个指针,跳出括号,右边也有个括号,那么func是一个指向函数的指针,这类函数具有int *和int (*)(int*)这样的形参,返回值为int类型。再来看一看func的形参int (*f)(int*),类似前面的解释,f也是一个函数指针,指向的函数具有int*类型的形参,返回值为int。

int (*func[5])(int *p);

func右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。


int (*(*func)[5])(int *p);

func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。

int (*(*func)(int *p))[5];

func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。

要注意有些复杂指针声明是非法的,例如:

int func(void) [5];

func是一个返回值为具有5个int元素的数组的函数。但C语言的函数返回值不能为数组,这是因为如果允许函数返回值为数组,那么接收这个数组的内容的东西,也必须是一个数组,但C语言的数组名是一个右值,它不能作为左值来接收另一个数组,因此函数返回值不能为数组。

int func[5](void);

func是一个具有5个元素的数组,这个数组的元素都是函数。这也是非法的,因为数组的元素除了类型必须一样外,每个元素所占用的内存空间也必须相同,显然函数是无法达到这个要求的,即使函数的类型一样,但函数所占用的空间通常是不相同的。

作为练习,下面列几个复杂指针声明给读者自己来解析,答案放在第十章里。

int (*(*func)[5][6])[7][8];

int (*(*(*func)(int *))[5])(int *);

int (*(*func[7][8][9])(int*))[5];

实际当中,需要声明一个复杂指针时,如果把整个声明写成上面所示的形式,对程序可读性是一大损害。应该用typedef来对声明逐层分解,增强可读性,例如对于声明:

int (*(*func)(int *p))[5];

可以这样分解:

typedef int (*PARA)[5];
typedef PARA (*func)(int *);

这样就容易看得多了。


lingyin55 2009-10-27
  • 打赏
  • 举报
回复
其实慢慢分析就可以分析出来,用typedef只是把一些
类型组合起来,起一个别名,方面使用。
可以参考下
http://discuss.techinterview.org/default.asp?interview.11.638944.3
机智的呆呆 2009-10-27
  • 打赏
  • 举报
回复
百度
指针 右左法则

64,654

社区成员

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

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