函数指针详解

[size=large]函数指针:函数的入口地址
C程序变量驻留在程序内存空间的某个地址,它所在的地方取决于变量类型(自动变量、静态变量或全局变量等)。我们可以很容易打印变量的地址,如下所示:[/size]
#include <stdio.h>
int main(void)
{
int i = 3;
printf("i resides at %p\n", &i); //i resides at 0xbfef6c44
return 0;
}
[size=large]在程序中,操作符&作用于变量i,要求生成i的地址,而格式化标识符%p指定输出内存地址。上述程序的可能输出如下:
i resides at 0xbfef6c44
同变量一样,我们也可以打印函数的地址。下面这段代码说明了这一点:[/size]
#i nclude <stdio.h>
void func(void);
int main(void)
{
int i = 3;
printf("i resides at %p\n", &i); // i resides at 0xbfe2f6f4
printf("func() resides at %p\n", &func); // func() resides at 0x80483fa
// printf("func() resides at %p\n", func); // func() resides at 0x80483fa
printf("main() resides at %p\n", &main); // main() resides at 0x8048368
// printf("main() resides at %p\n", main); // main() resides at 0x8048368
return 0;
}
void func(void)
{
printf("Hello, world\n");
}
对应的输出如下:
i resides at 0xbfe2f6f4
func() resides at 0x80483fa
main() resides at 0x8048368
[size=large]实际上,函数也驻留在程序的内存空间中。地址操作符&也可以作用于函数,从而生成函数所在的地址。
如何声明函数指针
在C语言中,所有变量都需要声明和定义,函数指针也不例外。
变量和指针的声明及定义如下:
int i;
int *int_ptr = &i;
很自然会联想到:
int f(int arg);
int *func_ptr(int arg) = &f;
实际上,由于根据运算符优先级规则,括号的优先级要比指针高,因此这种形式定义了一个指针函数,也就是一个返回指向整型数的指针的函数。
函数指针的正确定义为:
int f(int arg);
int (*func_ptr)(int arg) = &f;
需要强调的是,函数指针和它所指向的函数应该是兼容的。下例给出了一些对函数及函数指针的错误赋值:[/size]
int func(int arg)
{
return 0;
}
int *func_ptr1(int arg);
int (*func_ptr2)(int arg);
int (*func_ptr3)(void);
double (*func_ptr4)(int arg);
int main(void)
{
// func_ptr1 = &func; //error: invalid lvalue in assignment
func_ptr2 = &func; //pass
// func_ptr3 = &func; //warning: assignment from incompatible pointer type
// func_ptr4 = &func; //warning: assignment from incompatible pointer type
}
[size=large]其中,只有第二个赋值是正确的。在示例一中,func_ptr1并不是函数指针,而是一个指向指针的函数。在示例三中,func_ptr3只能指向没有参数的函数,而函数func带有一个整型参数。而示例四中,func_ptr4只能指向返回double类型的函数,而函数func返回的是int类型。
如何获得函数的地址
有两种方式获取函数的地址。假设funcptr是一个函数指针。如果我们将它指向一个兼容函数func()。
第一种方法使用隐式指针转换(implicit conversion to pointer):
funcptr = func;
第二种方法使用显式指针转换(explicit conversion to pointer):
funcptr = &func;
这两种方法都是可行的。实际上,如果在程序中有第一种形式的语句,编译器会把它自动转换为第二种方式。
使用函数指针调用函数
象获取函数的地址一样,通过函数指针调用函数的方法也有两种:
第一种是使用显式指针(explicit dereference of the pointer),如下:[/size]
extern void func(int x, int y);
void (*func_ptr)(int x, int y) = func;
(*funcptr)(3, 2);
第二种称为隐式指针(implicit dereference of the pointer)。

extern void func(int x, int y):
void (* func_ptr)(int x, int y) = func;
funcptr(3, 2);

函数指针的应用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值