视窗
loading...
您现在的位置:首页 > IT认证 > 软件水平 >

软考程序员辅导:浅析函数指针


2012年软考程序员辅导:浅析函数指针

函数指针的概念是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。在大多数情况下我们使用不到,也忽略了它的存在。函数名实际上也是一种指针,指向函数的入口地址,但它又不同于普通的如int*、double*指针,看下面的例子来理解函数指针的概念:
  view plain int function( int x, int y );int main ( void )

  { int (*fun) ( int x, int y );int a = 10, b = 20;function( a, b );fun = function;(*fun)( a, b );……

  }第一行代码首先定义了一个函数function,其输入为两个整型数,返回也为一个整型数(输入参数和返回值可为其它任何数据类型);后面又定义了一个函数指针fun,与int*或double*定义指针不同的是,函数指针的定义必须同时指出输入参数,表明这是一个函数指针,并且*fun也必须用一对括号括起来;并将函数指针赋值为函数function,前提条件是*fun和function的输入参数和返回值必须保持一致,否则无法通过编译。可以直接调用函数function(),也可以直接调用函数指针,二者是等效的。

  声明函数指针

  回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。要实现回调,必须首先定义函数指针。尽管定义的语法有点不可思议,但如果你熟悉函数声明的一般方法,便会发现函数指针的声明与函数声明非常类似。请看下面的例子:

  void f(); // 函数原型

  上面的语句声明了一个函数,没有输入参数并返回void.那么函数指针的声明方法如下:

  void (*) ();

  函数存放在内存的代码区域内,它们同样有地址,我们如何能获得函数的地址呢?

  如果我们有一个int test(int a)的函数,那么,它的地址就是函数的名字,这一点如同数组一样,数组的名字就是数组的起始地址。

  定义一个指向函数的指针用如下的形式,以上面的test()为例:

  int (*fp)(int a); //这里就定义了一个指向函数的指针

  函数指针绝对不能指向不同类型,或者是带不同形参的函数,在定义函数指针的时候我们很容易犯如下的错误。

  int *fp(int a); //这里是错误的,因为按照结合性和优先级来看就是先和()结合,然后变成了一个返回整形指针的函数了,而不是函数指针,这一点尤其需要注意!

  例如函数原型为:

  int fun(int *, int);

  则函数指针可以声明为: int (*pf)(int *, int);

  当然从上述例子看不出函数指针的优点,目的主要是想引出函数指针数组的概念。我们从上面例子可以得知,既然函数名可以通过函数指针加以保存,那们也一定能定义一个数组保存若干个函数名,这就是函数指针数组。正确使用函数指针数组的前提条件是,这若干个需要通过函数指针数组保存的函数必须有相同的输入、输出值。

  view plain //首先定义256个处理函数(及其实现)。

  int function0( int *, int );……

  int function255( int *, int );

  //其次定义函数指针数组,并给数组赋值。

  void (*fun[256])( int *, int );

  fun[0] = function0;……

  fun[255] = function255;

  如果赋了不同的值给函数指针,那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。

  下面我们来看一个具体的例子:

  view plain int test(int a)

  { return a;}

  int main(void)

  { int (*fp)(int a);fp = test; //将函数test的地址赋给函数指针fp cout《fp(5)《“|”《(*fp)(10)《endl; //输出fp(5),这是标准c++的写法,(*fp)(10)这是兼容c语言的标准写法,两种同意,但注意区分,避免写的程序产生移植性问题!

  return 0;} typedef定义可以简化函数指针的定义,在定义一个的时候感觉不出来,但定义多了就知道方便了,上面的代码改写成如下的形式:

  view plain int test(int a)

  { return a;}

  int main(void)

  { typedef int (*fp)(int a); //注意,这里不是生命函数指针,而是定义一个函数指针的类型,这个类型是自己定义的,类型名为fp fp fpi; //这里利用自己定义的类型名fp定义了一个fpi的函数指针!

  fpi = test;cout《fpi(5)《“|”《(*fpi)(10)《endl; //输出fp(5),这是标准c++的写法,(*fp)(10)这是兼容c语言的标准写法,两种同意,但注意区分,避免写的程序产生移植性问题!

  return 0;}

闂備線娼уΛ宀勫磻閿燂拷

闂備線娼уΛ宀勫磻閿燂拷

闂備線娼уΛ娆撳礉閺囥垹鍌ㄩ柕鍫濇处鐎氬鏌ㄥ┑鍡樺珔缂佹唻缍侀弻锟犲礋椤愶富鈧鏌熼摎鍌氬祮闁诡啫鍥ч唶闁绘柨鎽滅粔顒勬煟閻樺弶鎼愰柣掳鍔屽嵄闁硅揪绠戣繚闂佽法鍣﹂幏锟�
闂備礁鎼悧婊堝礈濞戙垺鍋熸い鏍仦閻掗箖鏌曟繛鍨姎闁诲氦顕ц彁闁搞儻绲芥晶鎻捗归悡搴㈠殗鐎殿喖鐖兼俊鐑芥晜閸撗冪厓濠电偛鐡ㄧ划宀€鑺遍懖鈺勫С濞寸厧鐡ㄩ崵鍌炴煛閸愩劌鈧崵绮旇ぐ鎺撶叆婵炴垼娅曠€氾拷闂佽娴烽弫鎼併€佹繝鍋綊宕卞Ο璇差潯闂佷紮绲介張顒勬偩閸楃們搴ㄥ炊閿濆懎鈷夋繛瀵稿帶閹虫﹢鐛€n喖绠f繝濠傚閹枫劑姊洪崨濠冣拹缂佸甯¢幆鍥ㄥ閺夋垵鍞ㄩ梺鎼炲劘閸斿秹锝為弽顬ュ酣宕堕敐鍛拤婵炲鍘ч幊姗€骞嗛崘顔肩妞ゆ劑鍨洪惁鏃€绻濋姀锝嗙【閻庢艾鎽滃Σ鎰版晸閿燂拷闂備胶鎳撻悺銊╁垂閸愭祴鍫柟瀵稿С閻掑﹤鈹戦悩鍙夋悙婵炲懌鍨归湁闁挎繂妫涢惌搴ㄦ煃瑜滈崜娆撳箠閹邦兘鏋旈柟杈鹃檮閸嬪鏌涢銈呮瀾缂傚秮鍋撻梻浣瑰灊閻掞箓濡甸悙鐢电闁哄啫鐗嗙痪褔鏌涢幇顖涚《缂佲偓閿燂拷闂佽绨肩徊濠氾綖婢舵劕鍨傛繝濠傚椤╅攱銇勯幒鎴濇殲缂佷緡鍣e鍫曟倷閸偅鐝┑鐐茬墛閸ㄥ墎绮氶柆宥呯労闁告剬鍛槬濠电姷顣介埀顒€鍟块埀顒傛嚀閿曘垺鎷呴崜鎻掓闂佺ǹ鏈换宥夊船閹绢喗鐓欓悗娑欋缚婢ь剚绻濋埀顒佹媴閸︻厾鎳濋梺鍓茬厛閸嬪懐绱為埀顒勬⒑閻熸壆鎽犻柣妤冨仧閹广垹顫濋鑺ョ亙闂佸搫娲﹂惌顔炬崲閸℃稒鐓欐い鎾楀啰浠村銈嗘处閸撶喎鐣烽敐鍡欑瘈闁告劏鏅╁Σ顖炴⒑閼逛即鍝烘慨濠傤煼閺屽牓骞橀鑲╊吅闂佺懓鐡ㄧ划宥囧垝閿曞倹鐓ユ繛鎴炆戝﹢鐗堢節閳ь剟骞嶉鎯у触濠电偛妫楀ù椋庣玻濡ゅ啰纾奸柡鍌涱儥閸庡繒鈧鎸稿Λ婵嗙暦濮樿埖鍋愮紓浣贯缚瑜版垿姊洪幐搴″枙闁瑰嚖鎷�闂佽娴烽弫鎼佸箠閹捐埖鏆滄い鎰剁畱缁€鍡樼箾閹寸伝顏堝极閸洘鍊电痪顓炴媼濞兼劙鏌涢妸锔剧煁缂佸倹甯¢、妤佹媴缁嬪晝顐︽⒑鐟欏嫭绶茬紒缁樺灴瀵偊顢欓悾宀婃祫濠殿喗銇涢崑鎾绘煃瑜滈崜娆撳磹閸濄儳绀婇悗锝庡枟閸庡秹鏌涢弴銊ュ笌鐟滅増甯楅悡鈧銈嗗笒閿曪妇绮堥敓锟�闂備浇澹堟ご绋款潖婵犳碍鐒鹃柟缁㈠枛濡﹢鏌i悢绋款棆缁绢厸鍋撻梻浣瑰缁嬫帒鐣濋幖浣哥;闁哄秲鍔庨々鐑芥煥閻曞倹瀚�:webmaster@jscj.com闂備線娼уΛ宀勫磻閹剧粯鐓熸い顐幘缁佺兘鏌i敂璺ㄧ煓闁轰礁绉归弫鎾绘晸閿燂拷4008816886

相关文章

无相关信息
更新时间2022-03-13 11:10:58【至顶部↑】
联系我们 | 邮件: webmaster@jscj.com | 客服热线电话:4008816886(QQ同号) |  濠电姷鏁告慨鐑藉极閹间礁纾块柟瀵稿Х缁€濠囨煃瑜滈崜姘跺Φ閸曨垰鍗抽柛鈩冾殔椤忣亪鏌涘▎蹇曠闁哄矉缍侀獮鍥敋閸涱喗鐦滈梻浣呵归鍡涘箲閸ヮ剚鍋樻い鏇楀亾鐎规洖缍婇、娆撳矗閵壯勶紡婵犵數濮烽弫鍛婃叏椤撱垹纾婚柟鍓х帛閻撴洟鏌曟径瀣仴闁兼椿鍨伴埢鎾活敃閵忊晜瀵岄梺闈涚墕濡瑩藟閸℃ǜ浜滈柡鍌氬皡閸旂喖鏌熼獮鍨伈闁轰焦鎹囬弫鎾绘晸閿燂拷

付款方式留言簿投诉中心网站纠错二维码手机版

客服电话: