• 函数指针学习笔记(转载)


    昨天和室友讨论了函数指针的使用方法,感觉收获挺大的,于是把它整理成笔记,发到博客里。

    就目前所接触过的情况,我觉得函数指针用法主要有以下两种:

    (一 )以相同的接口,方便地进行各个模块的替换。

    (二 )把函数指针作为形参,传给封装好的模块,实现用户不同的功能。

    这样说有点抽象了,下面对这两种应用分别给出例子。

    ( 一 ) 以相同的接口,方便地进行各个模块的替换。

    //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");    //用户把数据传给M 
        return 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

  • 相关阅读:
    07: mysql锁和事物隔离
    06: mysql索引查找原理及调优
    06: 字典、顺序表、列表、hash树 实现原理
    05:树结构
    02:MongoDB操作
    01:MongoDB基础
    02: CMDB设计思路
    二级制包安装Tomcat 与 RPM包安装Tomcat
    Docker的volume机制实现容器数据的持久性存储
    配置docker的私有仓库
  • 原文地址:https://www.cnblogs.com/kimiway/p/3991754.html
Copyright © 2020-2023  润新知