函数指针的研究

/***************************************************
 *作     者:温子祺
 *联系方式: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.如果不用函数指针,按照平时的ifswitch的语句进行判断使用哪一个函数向外发送数据,会有如下的代码:

 

#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是强制类型转换操作,将数值“0”强制转换为函数指针地址“0”

  通过调用reset()函数,程序就会跳转到程序执行的“0”地址处重新执行。在一些其他高级单片机Bootloader中,如NBoot、UBoot、EBoot,经常通过这些Bootloader进行下载程序,然后通过函数指针跳转到要执行程序的地址处。

原文地址:https://www.cnblogs.com/wenziqi/p/1769371.html