首頁(yè) 現(xiàn)實(shí)

程序媛養(yǎng)成計(jì)劃

第五十二章 指針(七)

程序媛養(yǎng)成計(jì)劃 任煦之秋 2017 2020-05-25 22:21:22

  「行了行了,老爹你也不用做鋪墊了,咱們開(kāi)門(mén)見(jiàn)山直接說(shuō)吧!大家都這么熟的人了,你這背后的套路早就我們看穿了。」

  還不等老爹說(shuō)完,我便揮手打斷了他。

  「……」

  老爹是一陣語(yǔ)塞,滿(mǎn)臉的無(wú)奈。

  「這個(gè)時(shí)候,我們就可以使用typedef這個(gè)喜歡取名字的家伙來(lái)定義函數(shù)指針類(lèi)型。注意到,這里是定義的一種數(shù)據(jù)類(lèi)型,這意味著我們可以使用這種類(lèi)型來(lái)聲明很多的變量,所以剛剛提到的問(wèn)題也就迎刃而解了。具體的使用方法如下:

  typedef int(*Func)(int,int);

  int max(int a,int b)

  {

  return a > b ? a : b;

  }

  int min(int a, int b)

  {

  return a < b ? a : b;

  }

  int main(int argc, char const* argv[])

  {

  Func f_max = max;

  Func f_min = min;

  int maxValue = f_max(3, 4);

  int minValue = f_min(3, 4);

  }

  看到?jīng)],因?yàn)槭褂昧藅ypedef,這個(gè)時(shí)候Func已經(jīng)不是某個(gè)具體的指針變量了,而是搖身一變,升級(jí)成為了開(kāi)山鼻祖。

  這樣一來(lái),F(xiàn)unc就成了一種函數(shù)指針類(lèi)型,可以用來(lái)聲明變量,所有返回值為int,有兩個(gè)int參數(shù)的函數(shù)都可以賦值給它的變量。

  到這里,指針和函數(shù)之間那些不可告人的關(guān)系就被我們?nèi)棵噶?。?p>  「可是老爹,你說(shuō)了這么多,我也沒(méi)有明白函數(shù)指針有什么用啊,如果我們要調(diào)用一個(gè)函數(shù),直接用方法名調(diào)用不好么,何必這么麻煩?」

  我不解道。

  「嗯~,之前我跟你們說(shuō)了,其實(shí)函數(shù)指針最大的用處是作為參數(shù)傳遞給另外一個(gè)函數(shù),這種就做回調(diào)機(jī)制,而作為參數(shù)傳遞的函數(shù)指針就被稱(chēng)之為回調(diào)函數(shù)。

  現(xiàn)在我們就用一個(gè)貼近生活的小案例來(lái)說(shuō)明回調(diào)函數(shù)。

  假設(shè)我們住這個(gè)小區(qū)是非常高檔的小區(qū),甚至都和國(guó)際接軌了,里面除了中國(guó)人以外還居住了很多外國(guó)友人。

  物業(yè)為了提高服務(wù)水品,于是要求保安叔叔們?cè)谛^(qū)門(mén)口和每一個(gè)進(jìn)來(lái)小區(qū)的業(yè)主敬禮問(wèn)好。

  那現(xiàn)在問(wèn)題就來(lái)了,敬禮還好,不管是中國(guó)人還是外國(guó)人都能夠看懂。但是問(wèn)好因?yàn)檎Z(yǔ)言的差異性,會(huì)存在問(wèn)題。如果說(shuō)中文的話(huà),大部分外國(guó)人聽(tīng)不懂,但是如果說(shuō)英語(yǔ)的話(huà),大部分中國(guó)人也聽(tīng)不懂。

  于是啊,有個(gè)聰明的保安想出了一種讓人拍案叫絕的辦法,讓進(jìn)出的人自己選擇問(wèn)好的方式,這樣一來(lái),中國(guó)人問(wèn)好用漢語(yǔ),外國(guó)人問(wèn)好用英語(yǔ)。

  吶,上面的場(chǎng)景就可以用回調(diào)函數(shù)來(lái)實(shí)現(xiàn):

  typedef void (*Func)(void);

  void chineseSayHello(void)

  {

  printf(“歡迎回家“);

  }

  void othersSayHello(void)

  {

  printf(“welecome go back home“);

  }

  void sayHello(Func f_sayHello)

  {

  /*敬禮*/

  f_sayHello();

  }

  這樣,當(dāng)中國(guó)人進(jìn)入小區(qū)的時(shí)候,咱們就把chineseSayHello這個(gè)函數(shù)作為參數(shù)傳遞給sayHello,到時(shí)候保安叔叔們就會(huì)說(shuō)『歡迎回家』,而如果是外國(guó)人,就把othersSayHello作為參數(shù)傳遞給sayHello,這樣保安叔叔們就會(huì)說(shuō)『welecome go back home』。

  其實(shí)我們之前在寫(xiě)推箱子這個(gè)游戲時(shí),講到的響應(yīng)事件,追根究底其實(shí)就是使用的回調(diào)函數(shù)機(jī)制。

  通過(guò)上面的案例,我們可以總結(jié)出一點(diǎn),當(dāng)我們需要在一個(gè)函數(shù)中執(zhí)行某些操作,但是這些操作的具體內(nèi)容在實(shí)現(xiàn)函數(shù)的時(shí)候不能確定,那么這個(gè)時(shí)候我們就可以考慮使用回調(diào)函數(shù)了。

  當(dāng)然了,就這么三言?xún)烧Z(yǔ)就想讓你們理解回調(diào)機(jī)制無(wú)疑是太想當(dāng)然了,等到你們?cè)趯?shí)際開(kāi)發(fā)過(guò)程中會(huì)接觸到的?!?p>  看著我和小弦子臉上毫不掩飾的茫然,老爹不置可否地聳了聳肩。

  「現(xiàn)在指針的內(nèi)容就剩下最后一點(diǎn)點(diǎn)了——多重指針和指針數(shù)組。這兩個(gè)知識(shí)點(diǎn)用到的時(shí)候比較少,咱們點(diǎn)到為止即可。

  我們先說(shuō)指針數(shù)組,既然指針是一種數(shù)據(jù)類(lèi)型,那么它有數(shù)組也不是什么怪事,那你們說(shuō)說(shuō),指針數(shù)組是個(gè)嘛玩意?」

  「一個(gè)口袋,里面裝的全部都是指針!」

  我和小弦子異口同聲道。

  「冰狗,回答正確!那么再請(qǐng)你們大膽的猜想一下,如何定義一個(gè)指針數(shù)組?!?p>  聞言后,我先總結(jié)了一下普通數(shù)據(jù)類(lèi)型聲明數(shù)組的方式,然后依葫蘆畫(huà)瓢寫(xiě)出了自己的答案,沒(méi)想到居然還被我蒙對(duì)了。

  「其實(shí)指針數(shù)組從你們寫(xiě)下第一行代碼的時(shí)候就見(jiàn)到了哦!而且在這之后,你們每次寫(xiě)代碼的時(shí)候指針數(shù)組都默默地陪伴在你們身邊。它認(rèn)識(shí)你們,你們卻不認(rèn)識(shí)它?!?p>  這個(gè)時(shí)候,老爹突然神秘地笑了笑。

  「寫(xiě)下第一行代碼的時(shí)候就見(jiàn)到了指針數(shù)組這么高深的知識(shí)?不可能啊,寫(xiě)的第一段代碼分明是一個(gè)輸出『hello world』的程序嘛。

  等等,老爹后面這句話(huà)分明是別有所指嘛。」

  我在心里暗自揣摩了一下老爹的話(huà),最終推斷出只有main函數(shù)才滿(mǎn)足老爹的這個(gè)說(shuō)法。

  因?yàn)閙ain函數(shù)從我們開(kāi)始寫(xiě)第一段代碼到之后的每次寫(xiě)代碼都會(huì)用到它,那么指針數(shù)組出現(xiàn)的位置就呼之欲出了,只能是main函數(shù)的參數(shù)!

  關(guān)于main函數(shù),一開(kāi)始老爹也沒(méi)有給我解釋太多,只是說(shuō)這是程序的入口地址,所有程序都是從main函數(shù)開(kāi)始執(zhí)行的,讓我給硬背下來(lái)。

  main函數(shù)的第一個(gè)參數(shù)是argc,int類(lèi)型的變量,第二個(gè)參數(shù)是argv,指數(shù)組參數(shù)就只能是它了。

  「看來(lái)你們已經(jīng)猜到了,那我們今天就順帶來(lái)揭開(kāi)main函數(shù)什么的面紗,現(xiàn)在我們寫(xiě)一段代碼來(lái)運(yùn)行一下:

  int main(int argc, char const *argv[])

  {

  for (int i = 0; i < argc; i++)

  {

  printf(“argv[%d]=%s\n“, i, argv[i]);

  }

  getchar();

  return 0;

  }

  在小黑屏里面運(yùn)行可執(zhí)行文件的時(shí)候,咱們?cè)诤竺婕狱c(diǎn)東西,程序編譯出來(lái)的可執(zhí)行文件名字叫point.exe,那小黑屏就執(zhí)行這個(gè):

  pointer.exe hello world Java」

  按照老爹說(shuō)法,在小黑屏里面輸出了:

  argv[0]= pointer.exe

  argv[1]= hello

  argv[2]= world

  argv[3]= Java

  原來(lái)argv是一個(gè)字符指針數(shù)組,而字符指針就是一個(gè)字符串,所以argv是一個(gè)字符串?dāng)?shù)組,而argc是這個(gè)數(shù)組的長(zhǎng)度!并且字符串?dāng)?shù)組的元素來(lái)自于我們運(yùn)行程序時(shí)攜帶的參數(shù)!

  哈哈,沒(méi)想到學(xué)到這里,居然才把main函數(shù)給弄清楚。難怪當(dāng)初老爹不給我多講main函數(shù),因?yàn)橹v我的確也難以理解,說(shuō)不定還會(huì)因此畏難而放棄學(xué)習(xí)。

  

按 “鍵盤(pán)左鍵←” 返回上一章  按 “鍵盤(pán)右鍵→” 進(jìn)入下一章  按 “空格鍵” 向下滾動(dòng)
目錄
目錄
設(shè)置
設(shè)置
書(shū)架
加入書(shū)架
書(shū)頁(yè)
返回書(shū)頁(yè)
指南