C语言中的函数和函数指针

先看以下的代码:

#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指针 (日本 前桥和弥)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值