函数指针的数组

“函数指针数组”首先它是个数组,不过数组的元素是函数指针。

“函数指针”是指向函数的指针变量。

Example:

 #include <stdio.h>

  int add1(int a1,int b1); /*函数声明*/

  int add2(int a2,int b2); /*函数声明*/

  void main()

  {

  int numa1=1,numb1=2;

  int numa2=2,numb2=3;

  int (*op[2])(int a,int b);

  op[0]=add1;

  op[1]=add2;

  printf("%d %d\n",op[0](numa1,numb1),op[1](numa2,numb2));

  }


  int add1(int a1,int b1)

  {

  return a1+b1;

  }


  int add2(int a2,int b2)

  {

  return a2+b2;

  }

======================================================

为函数指针数组赋值:

为函数指针数组赋值有两种方式:静态定义和动态赋值。

  1.静态定义

  在定义函数指针数组的时候,已经确定了每个成员所对应的函数。例如:

  void (*INTARRAY[])(void) = {Stop,Run,Jump};

  从根本上讲函数指针数组依然是数组,所以和数组的定义类似,由于是静态赋值,[ ]里面的数字可以

  省略。这个函数指针数组的成员有三个。

  INTARRAY[1](); //执行Run函数

  2.动态赋值

  也可以先定义一个函数指针数组,在需要的时候为其赋值。为了还原它本来的面目,我们先对这个执行特定类型的函数指针进行类型重定义,然后再用这个新数据类型来定义数组。如下:

  typedef void (*INTFUN)(void); //此类型的函数指针指向的是无参、无返回值的函数。

  INTFUN INTARRAY[32]; //定义一个函数指针数组,其每个成员为INTFUN类型的函数指针

  INTARRAY[10] = INT_TIMER0; //为其赋值

        INTARRAY[10](); //调用函数指针数组的第10个成员指向的函数

***********************************************************************************
typedef  int (init_fnc_t) (void)int (*init_fnc_t) (void) 区别

1、typedef  int (init_fnc_t) (void);表示定义init_fnc_t为函数类型,该函数返回int型,无参数。
而“init_fnc_t  *init_sequence[]={ cpu_init,  board_init }”表示用init_fnc_t(函数类型)去定义一个一维指针数组,数组中的元素都是指针变量,而且都是指向函数的指针,这些函数返回值都是int型,无参数的。更明朗的说就是数组中的每个元素是用来存放函数入口首地址的。

  2、int (*init_fnc_t) (void);表示定义一个函数指针(返回值为int型,无参数的函数指针,存放的是函数的首地址),typedef  int (*init_fnc_t) (void);表示定义一个函数指针类型,即可以直接用init_fnc_t这个符号去定义函数指针,“init_fnc_t   init_sequence[]={cpu_init,  board_init }”表示用init_fnc_t(函数指针类型)去定义一个数组,数组里面的元素都是一个函数指针,cpu_init,  board_init 都是函数指针,存放的都是函数的首地址。

综上的分析,我个人觉得这两个定义的意思是一样的只是写法不一样而已,1中的数组元素是指向函数的指针变量,2中的数组的元素是函数指针。因此得到的结果是一样的。

******************************************************************

我们通常情况下会如下使用 typedef ,这个时候MyInt 就和int是一样的意思。
typedef int MyInt;
MyInt a;

对于函数的申明我们通常会这样申明:

int InitFunction(void);  //此时表示申明了一个函数名为InitFunction的函数, 函数没有任何的形参,返回值类型为int型。

typedef int(init_fnc_t) (void); // 就是对一个 int (void)类型的函数类型进行取别名init_fnc_t。 我们可以利用这个别名进行创建这个类型的函数对象。

init_fnc_t *MyFunction; //这里就是一个函数的指针。如果某个函数的类型和这个函数一样的,那么可以将这个函数的指针指向该函数。然后你就可以直接调用MyFunction();

以下是例子,如下:

#include <stdio.h>
int GetData(void)
{
    return 101;
}
int main()
{
    typedef int (init_fnc_t)(void);
    init_fnc_t *MyFunction;
    MyFunction = GetData;
    printf("%d",MyFunction());
    return 0;
}

这个时候打印出来的结果就是 101

再看下面的例子:

如果调用函数: EnterPWDN(0x7fff4); 会被替换成:((void (*)(int))0x00000020)(0x7fff4);

这个涉及到函数指针,函数指针的用法如下:
void fun(int x);         /* 声明一个函数 */
void (*pfun) (int x);    /* 声明一个函数指针 */
pfun = fun;              /* 将func函数的首地址赋给指针f */
那么调用函数fun可以这样写:a. fun(5);  b. (*pfun)(5);
那么对函数:((void (*)(int))0x00000020)(0x7fff4); 中0x7fff4是传递的参数,(void (*)(int))0x00000020是函数名。
其实函数名本身就是一个地址。像上式中,如果你知道函数fun存储在地址0x012345,理论上你可以这么写:0x012345(5),当然实际上不能这么写,因为你虽然fun在0x012345地址,但是你编译器不知到这个函数的参数、返回值等信息,所以要强制转换一下。
接下来看一下怎么把一个地址转换成函数名:
如果把 char a ; 中的a转换成 int  形变量,要这样:b=(int)a;
同样要把0x00000020地址转换为函数名,也要强制转换,只要在0x00000020的前面加上要转换的类型。
(void (*)(int))就是函数类型,和void (*pfun) (int x); / / 声明一个函数指针是相对应的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值