|
发表于 2008-3-11 12:19:30
|
显示全部楼层
这涉及到 C 的语义。由于现在的计算机教育往往从 C 开始,就忽视了对 C 的语义的理解而通过观察已有程序的例子从“表向”上去理解 C 如何工作。在大多数情况下这是可行的,但涉及到像这里所遇到的细节时就不得不回到语义上去。我下面的讨论以 C99 标准为背景,这份标准可以在 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf 下载到。
Post by realtang;1824791
- #include <stdio.h>
- typedef char (*PTRFUN)(int);//指向函数的指针
- char glFun(int a)
- {
- putchar( a);
- putchar('\n');
- return a;
- }
- int main()
- {
- PTRFUN pFun;
- pFun = glFun;
- pFun('A');
- (*pFun)('A');
- return 0;
- }
复制代码
从gdb看去,pFun和*pFun的值确实相同,但*pFun的类型更加安全。
(gdb) p pFun
$4 = 0x804836c <glFun>
(gdb) p *pFun
$5 = {char (int)} 0x804836c <glFun>
标准的 6.3.2.1 定义了 function designator 的概念:
A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.
上面的例子中 g1Fun 就是一个 function designator。
6.5.2 节定义了函数调用的限制和语义。6.5.2.1 节中说:
The expression that denotes the called function shall have type pointer to function returning void or returning an object type other than an array type.
并且在脚注 77 中,标准明确地指出“大多数情况下这是转换一个是 function designator 的标识符得到的结果”。回到 realtang 的例子,
是不需转义的写法,因为 pFun 本身就是一个指向函数的指针的类型。后一种写法,以及下面 dajun 的写法:
Post by dajun;1825152
这样都行的:
#include <stdio.h>
void aa(void) {
puts("test");
}
int main(void) {
aa();
(*aa)();
return(0);
}
[root@td17 tmp]# ./p
test
test
其语义可以在 6.5.3.2 节找到:
The unary * operator denotes indirection. If the operand points to a function, the result is a function designator;
即,(*pointer_to_func) 先被转换为 function designator,再转换成 pointer to function。当然,这些都是在编译时完成的。我也给出一个写法:
- #include <stdio.h>
- typedef char FUN (int);
- char
- g1Fun (int a)
- {
- putchar (a);
- putchar ('\n');
- return a;
- }
- int
- main (int argc, char *argv[])
- {
- FUN *pFun = g1Fun;
- pFun ('A');
- return 0;
- }
复制代码 |
|