/***************************************************
*作 者:温子祺
*联系方式:wenziqi@hotmail.com
*说 明 :函数指针的研究
***************************************************/
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。
在C语言编程当中,指针就是精华,恰当地使用指针能够使代码更加简练,函数指针的使用尤为重要,具有动态选择的特性。
例如单片有3个通信接口,分别是串口、USB口、网口,它们发送数据的函数如下:
void UARTSendNBytes(UINT8 *szSendBytes,UINT8 ucSendLength);
void USBSendNBytes (UINT8 *szSendBytes,UINT8 ucSendLength);
void NETSendNBytes (UINT8 *szSendBytes,UINT8 ucSendLength);
1.如果不用函数指针,按照平时的if、switch的语句进行判断使用哪一个函数向外发送数据,会有如下的代码:
#define COM_PORT 0
#define USB_PORT 1
#define NET_PORT 2
void PortSendNBytes(UINT8 ucPort,UINT8 *szSendBytes,UINT8 ucSendLength)
{
if(ucPort ==COM_PORT) UARTSendNBytes(szSendBytes, ucSendLength);
if(ucPort ==USB_PORT) USBSendNBytes (szSendBytes, ucSendLength);
if(ucPort ==NET_PORT) NETSendNBytes (szSendBytes, ucSendLength);
}
串口发送数据调用方式:
PortSendNBytes(COM_PORT,buf,9);
USB发送数据调用方式:
PortSendNBytes(USB_PORT,buf,9);
网络发送数据调用方式:
PortSendNBytes(NET_PORT,buf,9);
2. 使用函数指针:
#define COM_PORT 0
#define USB_PORT 1
#define NET_PORT 2
void (*PortSendNBytes[3])( UINT8 *szSendBytes,UINT8 ucSendLength)=
{
UARTSendNBytes, USBSendNBytes, NETSendNBytes
};
串口发送数据调用方式:
PortSendNBytes[COM_PORT](buf,9);
USB发送数据调用方式:
PortSendNBytes[USB_PORT](buf,9);
网络发送数据调用方式:
PortSendNBytes[NET_PORT](buf,9);
虽然运用函数指针可以使代码更加简练,效率更高,但是空间资源占用方面就是它的弊端。一般情况下,单片机的资源是绰绰有余的,那么函数指针数组就是首选。
3.使用函数指针做程序跳转操作
函数指针跳转操作在软件复位章节有所介绍。
void(*reset)(void)= (void(*)(void))0。
void(*reset)(void)就是函数指针定义,(void(*)(void))0是强制类型转换操作,将数值“
通过调用reset()函数,程序就会跳转到程序执行的“0”地址处重新执行。在一些其他高级单片机Bootloader中,如NBoot、UBoot、EBoot,经常通过这些Bootloader进行下载程序,然后通过函数指针跳转到要执行程序的地址处。