先看以下的代码:
#include <stdio.h>
#include <stdlib.h>
void a(int k)
{
printf("k=%d\n", k);
}
int main(
const int argc,
const char *argv[]
)
{
void(*p_a)(int);
printf("a=%p\n", a);
printf("&a=%p\n", &a);
p_a = a;
printf("1 p_a=%p\n", p_a);
p_a(1);
p_a = &a;
printf("2 p_a=%p\n", p_a);
p_a(2);
(*p_a)(3);
(*****************p_a)(4);
getchar();
return 0;
}输出结果是:a=0018107D
&a=0018107D
1 p_a=0018107D
k=1
2 p_a=0018107D
k=2
k=3
k=4
可见,通过函数名a和对函数名a取地址结果是一样的。
不论是a(int), 还是(*a)(int),调用的结果是一样的。
这些要参考ANSI C的规范,看起来是有点混乱的,因为C语言就是这样规定的。
以下是规范:
1 表达式中的函数自动转换成指向函数的指针。
但是,当函数是地址运算符或者sizeof运算符的操作数时,表达式中的函数不能变换成指向函数的指针
2 函数调用运算符()的操作数不是函数,而是函数的指针。
按照第1条,当表达式中出现a时,会被自动转换成a的指针。但是当表达式中出现&a时,不会转换,所以&a的结果才是a的指针。
通过a(int)和(*a)(int)的方式都可以调用函数,是因为虽然(*a)得到了a函数,但是在()操作符的作用下,瞬间又变成了a的指针。
所以(******a)(int)是可以正常调用的,多少个*也不起作用。
这些东西也许多少有点孔乙己的味道,不过,知其然也要知其所以然,了解C语言的不完美可以更好的运用它,也可以更容易的理解编译过程中错误。
参考书目:征服C指针 (日本 前桥和弥)

被折叠的 条评论
为什么被折叠?



