指针本身是就一种数据类型,而要完全描述出指针的类型还需要指明指针所指向的数据类型,比如指向整型变量(int)的指针,又叫整型指针;指向字符类型(int)的指针,又叫字符指针,还有指向浮点类型(float)的指针,指向指针的指针。
以上的这些指向整型的指针,指向指针的指针都是平常C语言程序里面常用到的。但还有一种类型的指针,通常情况下几乎不会涉及到,但某些情况下用它会带来方便,这就是指向函数的指针,也叫函数指针。示例程序如下:
/*******************************************/
/* point2fun.c */
/* 指向函数的指针测试程序 */
/*******************************************/
#include <stdio.h>
void (*pfun)(int);
void fun(int a)
{
printf("%d",a);
}
void main()
{
pfun=fun; //写成pfun=&fun;也对
pfun(3); //采用(*pfun)(3);的写法也对
}
/***********************************************/
执行结果:输出3
指向函数的指针通常用在比较复杂的程序中来实现回调函数的功能,比如协议栈的程序,内部封装了大量的模块,给使用协议栈的用户留出较为统一的接口,中断函数入口采用指向函数名的指针来实现,用户就可以写自己的回调函数,函数名可以自己任意命名,而只需要把函数名的地址传递给中断函数里调用的入口就行了。
指向函数的指针的实现还可以有另外的写法,示例程序如下:
/************************************************/
#include <stdio.h>
typedef void(*FUN)(int);
void fun(int a)
{
printf("%d",a);
}
void main()
{
FUN pfun;
pfun=fun; //也可使用FUN类型进行强制类型转换,写成pfun=(FUN)fun;
pfun(3);
}
/***************************************************/
执行结果:输出3
不过这条typedef void(*FUN)(int);语句让我想了好半天才想大概明白编译器是怎么来识别和解读这条语句的~~
头一次见到typedef还可以这样来用,以前只知道typedef char BYTE;这样的用法,现在才知道typedef后面原来可以直接跟类似表达式的类型定义方式~~下面试着解读一下用FUN来定义类型的执行过程(个人见解,不一定正确):
当编译器解释FUN fun时,实际上是把fun的类型用FUN类型来替换,而FUN在前面的定义是一个表达式,所以直接把定义FUN的类型表达式里面的FUN又替换成fun,成了void(*fun)(int),这样其中的*fun就相当于函数名,而fun就相当于是一个指向该函数的指针了。
按通常理解,执行pfun=fun或pfun=&fun以后pfun指向的地址应该等于fun的地址,不过在调试时发现情况却并不是这样,两者地址不一致!在汇编下面查看,发现pfun指向的地址是另一个地址,该地址只有一条语句,就是jmp到fun指向的地址~~所以执行结果是对的。为什么不直接让pfun指向fun呢?而要绕一圈再指向fun呢?这个问题~~~一直没想清楚~~~