尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

【2014-03-07】【转】函数指针

【2014-03-07】【转】函数指针 [历史归档]本文原发布于 cstriker1407.info 个人博客内容为历史存档仅供参考。发布时间2014-03-07 标题【转】函数指针分类编程 / C C 标签函数指针【转】函数指针2 函数指针简单介绍2.1 什么是函数指针3 C/C函数指针的语法3.1 定义一个函数指针3.3 给函数指针赋值和调用3.4 函数指针作为参数3.5 使用函数指针作为返回值3.6 使用函数指针数组3.7 使用typedef转自【 http://hipercomer.blog.51cto.com/4415661/792300 】有删改2 函数指针简单介绍2.1 什么是函数指针函数指针是一个指向函数的指针函数指针表示一个函数的入口地址。使用函数指针的好处就是在处理“在运行时根据数据的具体状态来选择相应的处理方式”这种需求时更加灵活。简单的例子floatminus(floata,floatb){returna-b;}typedeffloat(*pf)(float,float);。。。。。 。。。。。voidswitch_fp_impl(floata,floatb,pf p){floatresult0.0;resultp(a,b);}intmain(){inti0;for(i0;iN;i){switch_fp_impl(12.32,54.14,minus);}return0;}3 C/C函数指针的语法从语法上讲有两种不兼容的函数指针形式1 指向C语言函数和C静态成员函数的函数指针2 指向C非静态成员函数的函数指针不兼容的原因是因为在使用C非静态成员函数的函数指针时需要一个指向类的实例的this指针而前一类不需要。3.1 定义一个函数指针指针是变量所以函数指针也是变量因此可以使用变量定义的方式来定义函数指针对于普通的指针可以这么定义int a10;int *paa;这里pa是一个指向整型的指针定义这个指针的形式为int * pa;区别于定义非指针的普通变量的“形式”就是在类型中间和指针名称中间加了一个“*”所以能够表达不同的“内容”。这种形式对于表达的内容是完备的因为它说明了两点1这是一个指针2这是一个指向整型变量的指针以下给出三个函数指针定义的形式第一个是C语言的函数指针第二个和第三个是C的函数指针的定义形式都是指向非静态函数成员的函数指针int (*pFunction)(float,char,char)NULL;int (MyClass::*pMemberFunction)(float,char,char)NULL;int (MyClass::*pConstMemberFunction)(float,char,char) constNULL;3.3 给函数指针赋值和调用给函数指针赋值就是为函数指针指定一个函数名称。这个过程很简单下面是两个例子int func1(float f,int a,int b){return f*a/b;}int func2(float f,int a,int b){return f*a*b}然后我们给函数指针pFunction赋值pFunctionfunc1;pFunctionfunc2;上面这段代码说明了两个问题1一个函数指针可以多次赋值想想C中的引用2取地址符号是可选的却是推荐使用的。最后我们来使用这个函数pFunction(10.0,’a’,’b’);(*pFunction)(10.0,’a’,’b’);在C中对于赋值你必须要加“”而且你还必须再次之前已经定义好了一个类实例取地址符号要操作于这个类实例的对应的函数成员上。在使用成员函数的指针调用成员函数时你必须要加类实例的名称然后再使用.*或者-*来使用成员函数指针。举例如下MyClass{public:intfunc1(floatf,chara,charb){returnf*a*b;}intfunc2(floatf,chara,charb)const{returnf*a/b;}}首先来赋值MyClass mc;pMemberFunction mc.func1; //必须要加取地址符号pConstMemberFunction mc.func2;接下来调用函数(mc.*pMemberFunction)(10.0,’a’,’b’);(mc.*pConstMemberFunction)(10.0,’a’,’b’);例子#includestdio.hfloatfunc1(floatf,chara,charb){printf(func1 );returnf*a/b;}floatfunc2(floatf,chara,charb){printf(func2 );returnf*a*b;}classMyClass{public:MyClass(floatf){factorf;}floatfunc1(floatf,chara,charb){printf(MyClass::func1 );returnf*a/b*factor;}floatfunc2(floatf,chara,charb)const{printf(MyClass::func2 );returnf*a*b*factor;}private:floatfactor;};intmain(intargc,char*argv[]){float(*pFunction)(float,char,char)NULL;float(MyClass::*pMemberFunction)(float,char,char)NULL;float(MyClass::*pConstMemberFunction)(float,char,char)constNULL;floatf10.0;charaa,bb;floatresult;pFunctionfunc1;printf(pointer pFunctions address is:%x ,pFunction);result(*pFunction)(f,a,b);printf(result%f ,result);pFunctionfunc2;printf(pointer pFunctions address is:%x ,pFunction);resultpFunction(f,a,b);printf(result%f ,result);if(func1!pFunction)printf(notequal.);pMemberFunctionMyClass::func1;MyClassmc1(0.2);printf(pointer pMemberFunctions address is:%x ,pMemberFunction);result(mc1.*pMemberFunction)(f,a,b);printf(result%f ,result);pConstMemberFunctionMyClass::func2;MyClassmc2(2);printf(pointer pConstMemberFunctions address is:%x ,pConstMemberFunction);result(mc2.*pConstMemberFunction)(f,a,b);printf(result%f ,result);return0;}**使用类的静态函数成员的函数指针和使用C语言的函数很类似**这里仅仅给出一个例子和其执行结果程序代码为#includeiostreamclassMyClass{public:staticfloatplus(floata,floatb){returnab;}};intmain(){floatresult,a10.0,b10.0;float(*p)(float,float);pMyClass::plus;resultp(a,b);printf(result%f ,result);return0;}3.4 函数指针作为参数例子#includestdio.hfloatadd(floata,floatb){returnab;}floatminus(floata,floatb){returna-b;}intpass_func_pointer(float(*pFunction)(floata,floatb)){floatresultpFunction(10.0,12.0);printf(result%f ,result);}intmain(){pass_func_pointer(add);pass_func_pointer(minus);return0;}3.5 使用函数指针作为返回值所以对于以下形式float (* func(char op) ) (float ,float)其具体含义就是声明了这样一个函数l 其名称为func其参数的个数为1个l 其各个参数的类型为op—charl 其返回变量函数指针类型为float(*)(float,float)再次强调函数指针时变量哦。到了这里之后我们再来分析一下unix的系统调用函数signal的定义形式void (*signal)(int signo,void (*func)(int)))(int);其具体含义为就是声明了这样一个函数l 其函数名称为signall 其参数个数为2l 其各个参数的类型为signo–int, func— void (*)(int)l 其返回的变量函数指针的类型为void(*)(int)上面这个函数比较经典有一个参数类型为函数指针返回值还是函数指针。例子floatadd(floata,floatb){returnab;}floatminus(floata,floatb){returna-b;}float(*FunctionMap(charop))(float,float){switch(op){case:returnadd;break;case-:returnminus;break;default:exit(1);}}intmain(){floata10,b5;charops[]{,-};intlenstrlen(ops);inti0;float(*returned_function_pointer)(float,float);for(i0;ilen;i){returned_function_pointerFunctionMap(ops);printf(%c%f ,ops,returned_function_pointer(a,b));}return0;}3.6 使用函数指针数组现在我们来类比函数指针数组的定义定义一个指向函数指针类型为float (*)(float,float)的函数指针数组数组长度为10.正确的形式为float(* pFunctionArray[10])(float,float)下面是一个例子程序floatadd(floata,floatb){returnab;}floatminus(floata,floatb){returna-b;}floatmultiply(floata,floatb){returna*b;}floatdivide(floata,floatb){returna/b;}intmain(){float(*func_pointers[4])(float,float){add,minus,multiply,divide};inti0;floata10.0,b5.0;for(i0;i4;i){printf(result is%f ,func_pointers(a,b));}return0;}3.7 使用typedef现在我们要将float (*)(float,float)类型声明为一种新类型typedef float(*fpType)(float,float);这样我们就可以用fpType来表示float (*)(float,float)这种类型了。所以定义一个新的指向float (*)(float,float)类型的指针变量的时候我们就可以采用下面这种形式了fpType pFunction;在定义函数指针数组的时候可以这样定义fpType pFunctions[10];在定义函数指针类型参数时可以这样定义void func(fpType pFunction);在定义函数指针类型的返回值时可以这样定义fpType func(int a);现在我们再来看一下unix中的那个signal函数其形式为void (*signal)(int signo,void (*func)(int)))(int);现在我们定义一个类型为typedef void (*pSgnType)(int);这样上面的函数就能表达为pSgnType signal(int signo,pSgnType func);这样是不是看起来清爽多了。其实上面的signal函数也能这样定义首先引入新类型typedef void SgnType(int)然后signal函数的声明改为SgnType *signal(int signo,SgnType *func);
返回列表