“函数指针数组”首先它是个数组,不过数组的元素是函数指针。
“函数指针”是指向函数的指针变量。
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); / / 声明一个函数指针是相对应的。