<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
為什麼要使用函數指標?
試想一下,我們在設計初期並不知道我們的函數的具體實現細節。例如,我們我們想要一個排序函數qsort,但是具體排序法則我們並不確定,是降序還是升序,採用什麼演演算法都不清楚。這些問題是要在使用者呼叫這個函數的時候才能夠決定。於是呼叫者應該自己設計comparator函數,傳給qsort函數。
例如我們設計一個結構體apple。我們除了設計出蘋果的屬性比如,數量、重量、顏色外,我們還要定義關於蘋果的操作,比如,吃掉,種植,這時候我們可以使用函數指標。然後我們以後呼叫這個結構體的時候,可以採用a.eat(&b)的方式呼叫函數。
typedef struct apple{ int number; double weight; colorType color; //some operations bool (*eat)(struct apple*); bool (*plant)(struct apple*); }apple;
函數的地址實際上就是函數名。這一點可以類比於陣列。
要宣告指向特定型別的函數的指標,可以先編寫這種函數的原型,然後用(*pf)代替函數名。或者採用C++11 的auto也能宣告並初始化函數指標。
double pam (int); //這是函數原型 double (*pf)(int); //這是函數指標 auto pn=pam; //定義並初始化函數指標
double pam (int); //這是函數原型 double (*pf)(int); //這是函數指標 auto pn=pam; //定義並初始化函數指標 pf=pam; pam(4); (*pf)(4); (*pn)(4);
直接把函數地址(即函數名)賦值給函數指標就行了,注意特徵標和返回型別必須相同。然後採用(*pf)(4)這樣的方式呼叫函數。實際上,C++也允許這樣子使用函數指標:
pf(4);//這種形式好看且實用,但是沒有顯示出 使用函數指標呼叫函數 pn(4);
閱讀這一篇幅,需要您熟練掌握,C語言中的指標。
//一些函數原型 const double* f1(const double ar[],int n); const double* f2(const double *,int); const double* f3(const double *,int); //函數指標 const double* (*p1)(const double ar[],int n)=f1; auto p2=f2;//感謝auto //呼叫函數 cout<<(*p1)(av,3)<<*(*p1)(av,3); cout<<p2(av,3)<<*p2(av,3); //實際上 *p2(av,3)和*(*p2)(av,3)是一樣的。不理解的看上面內容。 //包含3個函數指標的陣列 const double* (*pa[3])(const double *,int)={f1,f2,f3}; //注意: //1、[]優先順序高於* 所以這是個陣列不是指標。 //2、不能使用auto定義並初始化列表 auto pb=pa; //既然已經宣告了陣列,陣列名就是指標,採用auto可以定義初始化指標,這是合法的。 //呼叫函數 double x=*pa[0](av,3); double y=*(*pb[1])(av,3);//由於[]優先順序高於* 所以pb[1]是個函數指標。然後(*pb[1])就是呼叫函數了。 //更加深入 const double *(*(*pd)[3])(const double *,int) = &pa; //首先把函數指標的殼子去掉即 const double *(* ···)(const double *,int),然後得到(*pd)[3]這裡 pd先和* 結合 再和[]結合,所以pd是個指標,這個指標指向一個陣列,這個陣列的元素又是函數指標。 //是不是特別繞? //感謝auto auto pc=&pa; //呼叫 (*pd)[0](av,3); //pd是指向陣列的指標,則(*pd)[0]就是陣列的元素,陣列的元素是函數指標,所以可以採用這種方式呼叫函數。 //或者採用 (*(*pd)[0])(av,3)呼叫函數也是等價的。 double z=*(*pd)[0](av,3); //或者 採用 double z=*(*(*pd)[0])(av,3) 也是等價的
我們對於語法的瞭解不能僅僅潛於認識,對於這種const double *(*(*pd)[3])(const double *,int) = &pa;
我們不光要認識,更要會使用,再次重溫一遍,我們想要一個指向陣列的指標,這個陣列裡的元素是函數指標。
第一步,陣列元素的型別是函數指標,所以殼子要有 const double *(* ···)(const double *,int)
第二步,指向陣列的指標 (*pd)[3]
,由於[]比*優先順序高,所以我們必須採用(),否則 *pd[3]
就是一個陣列,陣列的元素是指標。 第三步,結合得 const double *(*(*pd)[3])(const double *,int) = &pa
typedef const double *(* p_fun)(const double *,int); p_fun p1=f1; p_fun pa[3]={f1,f2,f3}; p_fun (*pd)[3]=&pa;
typedef
使得程式碼量減少很多,而且更容易理解
到此這篇關於C/C++函數指標深入探究的文章就介紹到這了,更多相關C++函數指標內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45