】函數(shù)指針)
[歷史歸檔]本文原發(fā)布于 cstriker1407.info 個(gè)人博客內(nèi)容為歷史存檔僅供參考。發(fā)布時(shí)間2014-03-07 標(biāo)題【轉(zhuǎn)】函數(shù)指針分類編程 / C C 標(biāo)簽函數(shù)指針【轉(zhuǎn)】函數(shù)指針2 函數(shù)指針簡(jiǎn)單介紹2.1 什么是函數(shù)指針3 C/C函數(shù)指針的語法3.1 定義一個(gè)函數(shù)指針3.3 給函數(shù)指針賦值和調(diào)用3.4 函數(shù)指針作為參數(shù)3.5 使用函數(shù)指針作為返回值3.6 使用函數(shù)指針數(shù)組3.7 使用typedef轉(zhuǎn)自【 http://hipercomer.blog.51cto.com/4415661/792300 】有刪改2 函數(shù)指針簡(jiǎn)單介紹2.1 什么是函數(shù)指針函數(shù)指針是一個(gè)指向函數(shù)的指針函數(shù)指針表示一個(gè)函數(shù)的入口地址。使用函數(shù)指針的好處就是在處理“在運(yùn)行時(shí)根據(jù)數(shù)據(jù)的具體狀態(tài)來選擇相應(yīng)的處理方式”這種需求時(shí)更加靈活。簡(jiǎn)單的例子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函數(shù)指針的語法從語法上講有兩種不兼容的函數(shù)指針形式1 指向C語言函數(shù)和C靜態(tài)成員函數(shù)的函數(shù)指針2 指向C非靜態(tài)成員函數(shù)的函數(shù)指針不兼容的原因是因?yàn)樵谑褂肅非靜態(tài)成員函數(shù)的函數(shù)指針時(shí)需要一個(gè)指向類的實(shí)例的this指針而前一類不需要。3.1 定義一個(gè)函數(shù)指針指針是變量所以函數(shù)指針也是變量因此可以使用變量定義的方式來定義函數(shù)指針對(duì)于普通的指針可以這么定義int a10;int *paa;這里pa是一個(gè)指向整型的指針定義這個(gè)指針的形式為int * pa;區(qū)別于定義非指針的普通變量的“形式”就是在類型中間和指針名稱中間加了一個(gè)“*”所以能夠表達(dá)不同的“內(nèi)容”。這種形式對(duì)于表達(dá)的內(nèi)容是完備的因?yàn)樗f明了兩點(diǎn)1這是一個(gè)指針2這是一個(gè)指向整型變量的指針以下給出三個(gè)函數(shù)指針定義的形式第一個(gè)是C語言的函數(shù)指針第二個(gè)和第三個(gè)是C的函數(shù)指針的定義形式都是指向非靜態(tài)函數(shù)成員的函數(shù)指針int (*pFunction)(float,char,char)NULL;int (MyClass::*pMemberFunction)(float,char,char)NULL;int (MyClass::*pConstMemberFunction)(float,char,char) constNULL;3.3 給函數(shù)指針賦值和調(diào)用給函數(shù)指針賦值就是為函數(shù)指針指定一個(gè)函數(shù)名稱。這個(gè)過程很簡(jiǎn)單下面是兩個(gè)例子int func1(float f,int a,int b){return f*a/b;}int func2(float f,int a,int b){return f*a*b}然后我們給函數(shù)指針pFunction賦值pFunctionfunc1;pFunctionfunc2;上面這段代碼說明了兩個(gè)問題1一個(gè)函數(shù)指針可以多次賦值想想C中的引用2取地址符號(hào)是可選的卻是推薦使用的。最后我們來使用這個(gè)函數(shù)pFunction(10.0,’a’,’b’);(*pFunction)(10.0,’a’,’b’);在C中對(duì)于賦值你必須要加“”而且你還必須再次之前已經(jīng)定義好了一個(gè)類實(shí)例取地址符號(hào)要操作于這個(gè)類實(shí)例的對(duì)應(yīng)的函數(shù)成員上。在使用成員函數(shù)的指針調(diào)用成員函數(shù)時(shí)你必須要加類實(shí)例的名稱然后再使用.*或者-*來使用成員函數(shù)指針。舉例如下MyClass{public:intfunc1(floatf,chara,charb){returnf*a*b;}intfunc2(floatf,chara,charb)const{returnf*a/b;}}首先來賦值MyClass mc;pMemberFunction mc.func1; //必須要加取地址符號(hào)pConstMemberFunction mc.func2;接下來調(diào)用函數(shù)(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;}**使用類的靜態(tài)函數(shù)成員的函數(shù)指針和使用C語言的函數(shù)很類似**這里僅僅給出一個(gè)例子和其執(zhí)行結(jié)果程序代碼為#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 函數(shù)指針作為參數(shù)例子#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 使用函數(shù)指針作為返回值所以對(duì)于以下形式float (* func(char op) ) (float ,float)其具體含義就是聲明了這樣一個(gè)函數(shù)l 其名稱為func其參數(shù)的個(gè)數(shù)為1個(gè)l 其各個(gè)參數(shù)的類型為op—charl 其返回變量函數(shù)指針類型為float(*)(float,float)再次強(qiáng)調(diào)函數(shù)指針時(shí)變量哦。到了這里之后我們?cè)賮矸治鲆幌聈nix的系統(tǒng)調(diào)用函數(shù)signal的定義形式void (*signal)(int signo,void (*func)(int)))(int);其具體含義為就是聲明了這樣一個(gè)函數(shù)l 其函數(shù)名稱為signall 其參數(shù)個(gè)數(shù)為2l 其各個(gè)參數(shù)的類型為signo–int, func— void (*)(int)l 其返回的變量函數(shù)指針的類型為void(*)(int)上面這個(gè)函數(shù)比較經(jīng)典有一個(gè)參數(shù)類型為函數(shù)指針返回值還是函數(shù)指針。例子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 使用函數(shù)指針數(shù)組現(xiàn)在我們來類比函數(shù)指針數(shù)組的定義定義一個(gè)指向函數(shù)指針類型為float (*)(float,float)的函數(shù)指針數(shù)組數(shù)組長(zhǎng)度為10.正確的形式為float(* pFunctionArray[10])(float,float)下面是一個(gè)例子程序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現(xiàn)在我們要將float (*)(float,float)類型聲明為一種新類型typedef float(*fpType)(float,float);這樣我們就可以用fpType來表示float (*)(float,float)這種類型了。所以定義一個(gè)新的指向float (*)(float,float)類型的指針變量的時(shí)候我們就可以采用下面這種形式了fpType pFunction;在定義函數(shù)指針數(shù)組的時(shí)候可以這樣定義fpType pFunctions[10];在定義函數(shù)指針類型參數(shù)時(shí)可以這樣定義void func(fpType pFunction);在定義函數(shù)指針類型的返回值時(shí)可以這樣定義fpType func(int a);現(xiàn)在我們?cè)賮砜匆幌聈nix中的那個(gè)signal函數(shù)其形式為void (*signal)(int signo,void (*func)(int)))(int);現(xiàn)在我們定義一個(gè)類型為typedef void (*pSgnType)(int);這樣上面的函數(shù)就能表達(dá)為pSgnType signal(int signo,pSgnType func);這樣是不是看起來清爽多了。其實(shí)上面的signal函數(shù)也能這樣定義首先引入新類型typedef void SgnType(int)然后signal函數(shù)的聲明改為SgnType *signal(int signo,SgnType *func);