Q我该如何构造像“返回指向函数的指针,该函数又返回指向函数的指针,该函数最终返回指向字符的指针”这样复杂类型的声明?char的指针的 N 个指针的数组”,或者如何理解类似复杂的声明?
A这个问题的第一个部分至少有三种方法可以回答:
typedef char *pc; /* pointer to char */ typedef pc fpc(); /* function returning pointer to char */ typedef fpc *pfpc; /* pointer to above */ typedef pfpc fpfpc(); /* function returning... */ typedef fpfpc *pfpfpc; /* pointer to... */ pfpfpc a[N]; /* array of... */
cdecl> declare a as array of pointer to function returning pointer to function returning pointer to char char *(*(*a[])())()cdecl它还可以解释复杂的声明(您提供一个复杂的声明,它会返回英文描述)、帮助进行类型转换,并指示参数属于哪一对括号(对于复杂的函数定义,如上面那个)。参见问题 18.1。
C 语言的声明可能令人困惑,因为它们分为两部分:一个基本类型,和一个 declarator,后者包含被声明的标识符或名称,可能还包含*'s 和[]'s 和()声明该名称是指向、数组或返回基本类型的函数,或者这些的某种组合。[脚注] 例如,在
char *pc;中,基本类型是char,标识符是pc,而 declarator 是*pc;这表明*pc是一个char(这就是“声明模仿使用”的意思)。
理解复杂 C 声明的一种方法是“由内而外”地阅读它们,记住[]和()比*的结合性更强。例如,给定
char *(*pfpc)();,我们可以看到pfpc是指向(内部的)*的指针,指向一个函数(标志是()),该函数返回一个指针(外部的)*,该指针指向char。当后来使用pfpc时,表达式*(*pfpc)()(由指向pfpc的函数返回的值所指向的值)将是char.
另一种分析这些声明的方法是,在组合描述的同时分解 declarator,保持“声明模仿使用”的关系。
*(*pfpc)() is a char (*pfpc)() is a pointer to char (*pfpc) is a function returning pointer to char pfpc is a pointer to function returning pointer to char
如果您想在声明这些复杂类型时使其更清晰,可以通过一系列 typedef 来明确分析,如上面选项 2 所示。
上面示例中的指针到函数声明没有包含参数类型信息。当参数类型复杂时,声明真的会变得混乱。(现代版本的cdecl也很有帮助。)
额外链接
我的一条消息解释了
指针数组与数组指针声明之间的区别
David Anderson 的“顺时针/螺旋法则”
参考:K&R2 第 5.12 节,第 122 页
ISO 第 6.5 及后续章节(特别是第 6.5.4 节)
H&S 第 4.5 节,第 85-92 页,第 5.10.1 节,第 149-50 页