新闻  |   论坛  |   博客  |   在线研讨会
关于函数指针的使用小结
mayer | 2009-06-01 18:36:02    阅读:1750   发布文章

关于函数指针的使用小结

 

以前学C语言的时候也看过。不过由于用的不多,所以概念也比较模糊,直到这一阵一下子碰到了好几次有关于函数指针的程序。所以花了一些时间仔细研究了一下。

1,定义函数指针:
return_type (*func_pointer)(parameter_list)
例如:int (*p)();
定义一个函数指针p,参数列表为空。
void add()
{
...
}
void main()
{
   void (*p)()=add;
  (*p)(); //执行函数,等效于add();
}

 
2,定义返回函数指针的函数:
return_type(*function(func_parameter_list))(parameter_list)
定义了一个函数function,该函数的参数列表是(function_patameter_list),返回类型是一个函数指针,这个函数指针的原型是return_type(*)(parameter_list)。

例:
int (*add1(int a,int b))(int,int)
此处:此函数的函数主体为add1,add2函数作为add1的形参,返回值为一个函数指针。
注:返回的函数的形式必须为int funcname(int,int)

可以用typedef来简化定义:
//此函数等效于上面函数
typedef int (*funcp)(int)(int); //定义整型函数指针
funcp add1(int a,int b);

 
碰到的一些实例:

1、上电后把存放在Nand flash中的程序复制到内存中以0x30900000开始的地方,之后跳转到相应地址执行程序。
这是阿南的2410开发板的简易bootloader程序。由于Nand flash不能直接运行程序,所以要把程序复制到内存中运行。如下:
#define DOWNLOAD_ADDRESS 0x30900000
void main()
{
      //把程序复制到内存中
      ...
      //跳转到想应地址运行程序
      *((void(*)())(DOWNLOAD_ADDRESS))();
}

分解:DOWNLOAD_ADDRESS为复制的目标地址。
      void(*)() 为函数指针,参数为空。
      (void(*)())DOWNLOAD_ADDRESS 把DOWNLOAD_ADDRESS转为函数指针。
      *((void(*)())(DOWNLOAD_ADDRESS))();    执行相应函数

 

2、实现类似于windows中的回调函数,实现两个数的加法。
int add1(int x,int y)
{
       return x+y;
}
int add(int a,int b, int (* func)(int x,int y))
{
     return (* func)(a,b);
}

调用:
add(3,4,add1);

 

3、一个综合的例子:

#include <stdio.h>
typedef int (*funcp)(int,int);

//普通三个变量的加法函数
int func(int x,int y,int z)
{
// return x+y;
 printf("func:x+y+z=%d\n",x+y+z);
 return x+y+z;
}

/*实现两个数的减法,并返回函数func的地址。此函数的主体为dec(int x,int y),返回值为一个函数指针。注意返回值为函数指针的函数的定义。一开头已经给出。return_type(*function(func_parameter_list))(parameter_list)*/
void (*dec(int x,int y))(int a,int b,int c)
{
 printf("dec:x-y=%d\n",x-y);
 return (void *)func;
}

int add(int x,int y)
{
 return x+y;
}

/*此函数通过回调实现a+b+a+b,并且返回函数add的地址。此函数的主体为add1,add2函数作为add1的形参。返回类型为函数指针。*/
int (*add1(int a,int b,int (*add2)(int x,int y)))(int,int)
{
 printf("add1:a+b+a+b=%d\n",a+b+(*add2)(a,b));
 return add2;
}

/*此函数等效于add2,只不过用typedef进行分开来定义,看的更加清晰。typedef int (*funcp)(int,int); 定义一个函数指针为funcp. funcp add4等同于(*add4)(int,int), funcp add3(int a,int b, (*add4)(int,int)) 等同于 int (*add3(int a,int b,int (*add4)(int x,int y)))(int,int)*/
funcp add3(int a,int b, funcp add4)
{
 printf("add3:a+b+a+b=%d\n",a+b+add4(a,b));
 return add4;
}

 
//函数a1-a5用来验证函数指针数组的功能。
void a1()
{
 printf("this is a1!\n");
}
void a2()
{
 printf("this is a2!\n");
}                                                                        
void a3()
{
        printf("this is a3!\n");
}
void a4()
{
        printf("this is a4!\n");
}
void a5()
{
        printf("this is a5!\n");
}

int main()
{
 int addr;
 //定义函数指针
 int (*p)(int,int,int);
 char i;
 
 //定义函数指针数据,初始化存放a1-a5的函数地址。
 void (*funcarry[5])()={a1,a2,a3,a4,a5};
 int a[5]={(int)a1,(int)a2,(int)a3,(int)a4,(int)a5};

//直接把函数地址转化为整型
 addr=(int)func;

//把函数地址赋给一个函数指针p
 p=func;

//把印出func的地址。
 printf("func address is %d\n",addr);

//利用一个整型的地址来实现3+4+5
 printf("This is addr %d\n",(*((int(*)(int,int,int))addr))(3,4,5));

//利用函数指针来实现3+4+5
 printf("This is func pointer %d\n",(*p)(3,4,5));

//利用dec函数实现5-4,并且打印出返回的函数指针的地址。
 printf("func address is %d %d\n",dec(5,4),addr);

//以下两个功能一致,实现3+4+3+4
 printf("add for add1 address is %d %d\n",add1(3,4,add),(int *)add);
 printf("add for add3 address is %d %d\n",add3(3,4,add),(int *)add);

//利用函数指针数组实现函数a1-a5的执行。以下两种方法等效。
 for(i=0;i<5;i++)
 (*funcarry[i])();


 for(i=0;i<5;i++)
 (*((void(*)())a[i]))();
}

 

运行环境:Red hat 9.0

运行结果:

func address is 134513448
func:x+y+z=12
This is addr 12
func:x+y+z=12
This is func pointer 12
dec:x-y=1
func address is 134513448 134513448
add1:a+b+a+b=14
add for add1 address is 134513529 134513529
add3:a+b+a+b=14
add for add3 address is 134513529 134513529
this is a1!
this is a2!
this is a3!
this is a4!
this is a5!
this is a1!
this is a2!
this is a3!
this is a4!
this is a5!

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客