函数指针学习笔记(转载)
昨天和室友讨论了函数指针的使用方法,感觉收获挺大的,于是把它整理成笔记,发到博客里。
就目前所接触过的情况,我觉得函数指针用法主要有以下两种:
(一 )以相同的接口,方便地进行各个模块的替换。
(二 )把函数指针作为形参,传给封装好的模块,实现用户不同的功能。
这样说有点抽象了,下面对这两种应用分别给出例子。
( 一 ) 以相同的接口,方便地进行各个模块的替换。
//test_pf.cpp//函数指针实现接口相同的模块方便切换。//假设有9种方式对数据进行预测,选一种返回值最小的作为结果。#include "stdio.h"#include "stdlib.h"typedef int predict_fun(int x,int y); //声明函数指针类型//声明9个函数的原型int predict0(int x,int y);int predict1(int x,int y);int predict2(int x,int y);int predict3(int x,int y);int predict4(int x,int y);int predict5(int x,int y);int predict6(int x,int y);int predict7(int x,int y);int predict8(int x,int y);typedef struct block{int a;int b;predict_fun *pf[9]; //该结构体有9个函数指针,后面切换很方便。void init(); //初始化}block;void block::init(){ //对函数指针赋值pf[0]=predict0;pf[1]=predict1;pf[2]=predict2;pf[3]=predict3;pf[4]=predict4;pf[5]=predict5;pf[6]=predict6;pf[7]=predict7;pf[8]=predict8;};int main(){int i,j,min,temp;block *my_block;my_block = (block*)malloc(sizeof(block));my_block->init();my_block->a = 5;my_block->b = 6;min=100000;j=0;for (i=0;i<9;i++){temp = my_block->pf[i](my_block->a,my_block->b);printf("Method %d return value %d./n",i,temp);if ( temp < min){j=i;min=temp;}}printf("/nThe minimum return value is %d, which is got by predict mothod %d/n",min,j);free(my_block);printf("/nEnd of test./n");system("pause");return 0;}//9种函数的实现int predict0(int x,int y){return x+y;}int predict1(int x,int y){return 3*x;}int predict2(int x,int y){return x*y;}int predict3(int x,int y){return 2*x;}int predict4(int x,int y){return 2*y;}int predict5(int x,int y){return y-x;}int predict6(int x,int y){return (x+y)/2;}int predict7(int x,int y){return x-y;}int predict8(int x,int y){return x*x;}//end of file.
参考资料:
http://www.google.com/codesearch/p?hl=en#wxNDR0bxBmM/pub/videolan/x264/snapshots/x264-snapshot-20070428-2245.tar.bz2%7CVkYc4UgfDIA/x264-snapshot-20070428-2245/common/predict.c&q=x264_predict_4x4_init
Google 代码搜索 x264_predict_4x4_init 这是它的帧内预测代码,对函数指针 pf[]赋值,本文是其简化版。
转到这个网页之后,把代码框滚动条拉到最后面,看到 x264_predict_4x4_init()函数。
( 二 ) 把函数指针作为形参,传给封装好的模块,实现用户不同的功能。
//test_callback.cpp//函数指针作为函数的参数,实现用户功能的多样化,以及知识产权的封装(简单例子)//假设软件开发者为M,用户为A、B、C。//M为A、B、C提供可进行二次开发的软件,A、B、C可以定义不同的功能。#include "stdio.h"#include "stdlib.h"#include "string.h"typedef int User_callback(int x,int y,char *str); //M要把各项参数的含义告诉用户。int m(User_callback *pf) //这个函数对二次开发用户来说是封装好的。{int s,t,threshold=20,data;char user_info[100];//开发者M经过艰苦卓绝的努力,得到一系列数据,他只将这些数据提供给用户,(计算数据的过程被M封装了)。//艰苦卓绝的过程省略......,这里用直接的赋值给s,t代替。s=5;t=6;data=pf(s,t,user_info);printf("%s Data exchanged!/n",user_info); //打印回调函数传入的数据。if (data > threshold){printf("Alarm On!/n");}printf("/n");//开发者M续继艰苦卓绝的努力,实现其它功能,并实现用户其它需求.......//......return 0;}int a(int x,int y,char *str);int b(int x,int y,char *str);int c(int x,int y,char *str);int main(){m(a);m(b);m(c);printf("CallBack Test End !/n");system("pause");return 0;}//用户的回调函数实现。int a(int x,int y,char *str)//用户A{//用户可以根据需要,对x,y进行存盘、发送到网络等操作。事实上就是M内部的s,t两个值.printf("Enter User A's callback function!/n");strcpy(str,"User A"); //用户把数据传给Mreturn x+y;}int b(int x,int y,char *str)//用户B{printf("Enter User B's callback function!/n");strcpy(str,"User B");return x*y;}int c(int x,int y,char *str)//用户C{printf("Enter User C's callback function!/n");strcpy(str,"User C");return 2*y;}//end of file
总结:函数指针有两种妙用--
(1)模块的方便替换;
(2)功能的多样性和封装。
转载自:http://blog.csdn.net/qiuzhenguang/article/details/5489981

浙公网安备 33010602011771号