官术网_书友最值得收藏!

第53章 指針(七)

  • 程序媛養成計劃
  • 任煦之秋
  • 2017字
  • 2020-05-25 22:21:22

「行了行了,老爹你也不用做鋪墊了,咱們開門見山直接說吧!大家都這么熟的人了,你這背后的套路早就我們看穿了。」

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

「……」

老爹是一陣語塞,滿臉的無奈。

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

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);

}

看到沒,因為使用了typedef,這個時候Func已經不是某個具體的指針變量了,而是搖身一變,升級成為了開山鼻祖。

這樣一來,Func就成了一種函數指針類型,可以用來聲明變量,所有返回值為int,有兩個int參數的函數都可以賦值給它的變量。

到這里,指針和函數之間那些不可告人的關系就被我們全部摸透了。」

「可是老爹,你說了這么多,我也沒有明白函數指針有什么用啊,如果我們要調用一個函數,直接用方法名調用不好么,何必這么麻煩?」

我不解道。

「嗯~,之前我跟你們說了,其實函數指針最大的用處是作為參數傳遞給另外一個函數,這種就做回調機制,而作為參數傳遞的函數指針就被稱之為回調函數。

現在我們就用一個貼近生活的小案例來說明回調函數。

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

物業為了提高服務水品,于是要求保安叔叔們在小區門口和每一個進來小區的業主敬禮問好。

那現在問題就來了,敬禮還好,不管是中國人還是外國人都能夠看懂。但是問好因為語言的差異性,會存在問題。如果說中文的話,大部分外國人聽不懂,但是如果說英語的話,大部分中國人也聽不懂。

于是啊,有個聰明的保安想出了一種讓人拍案叫絕的辦法,讓進出的人自己選擇問好的方式,這樣一來,中國人問好用漢語,外國人問好用英語。

吶,上面的場景就可以用回調函數來實現:

typedef void (*Func)(void);

void chineseSayHello(void)

{

printf(“歡迎回家“);

}

void othersSayHello(void)

{

printf(“welecome go back home“);

}

void sayHello(Func f_sayHello)

{

/*敬禮*/

f_sayHello();

}

這樣,當中國人進入小區的時候,咱們就把chineseSayHello這個函數作為參數傳遞給sayHello,到時候保安叔叔們就會說『歡迎回家』,而如果是外國人,就把othersSayHello作為參數傳遞給sayHello,這樣保安叔叔們就會說『welecome go back home』。

其實我們之前在寫推箱子這個游戲時,講到的響應事件,追根究底其實就是使用的回調函數機制。

通過上面的案例,我們可以總結出一點,當我們需要在一個函數中執行某些操作,但是這些操作的具體內容在實現函數的時候不能確定,那么這個時候我們就可以考慮使用回調函數了。

當然了,就這么三言兩語就想讓你們理解回調機制無疑是太想當然了,等到你們在實際開發過程中會接觸到的。」

看著我和小弦子臉上毫不掩飾的茫然,老爹不置可否地聳了聳肩。

「現在指針的內容就剩下最后一點點了——多重指針和指針數組。這兩個知識點用到的時候比較少,咱們點到為止即可。

我們先說指針數組,既然指針是一種數據類型,那么它有數組也不是什么怪事,那你們說說,指針數組是個嘛玩意?」

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

我和小弦子異口同聲道。

「冰狗,回答正確!那么再請你們大膽的猜想一下,如何定義一個指針數組。」

聞言后,我先總結了一下普通數據類型聲明數組的方式,然后依葫蘆畫瓢寫出了自己的答案,沒想到居然還被我蒙對了。

「其實指針數組從你們寫下第一行代碼的時候就見到了哦!而且在這之后,你們每次寫代碼的時候指針數組都默默地陪伴在你們身邊。它認識你們,你們卻不認識它。」

這個時候,老爹突然神秘地笑了笑。

「寫下第一行代碼的時候就見到了指針數組這么高深的知識?不可能啊,寫的第一段代碼分明是一個輸出『hello world』的程序嘛。

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

我在心里暗自揣摩了一下老爹的話,最終推斷出只有main函數才滿足老爹的這個說法。

因為main函數從我們開始寫第一段代碼到之后的每次寫代碼都會用到它,那么指針數組出現的位置就呼之欲出了,只能是main函數的參數!

關于main函數,一開始老爹也沒有給我解釋太多,只是說這是程序的入口地址,所有程序都是從main函數開始執行的,讓我給硬背下來。

main函數的第一個參數是argc,int類型的變量,第二個參數是argv,指數組參數就只能是它了。

「看來你們已經猜到了,那我們今天就順帶來揭開main函數什么的面紗,現在我們寫一段代碼來運行一下:

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;

}

在小黑屏里面運行可執行文件的時候,咱們在后面加點東西,程序編譯出來的可執行文件名字叫point.exe,那小黑屏就執行這個:

pointer.exe hello world Java」

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

argv[0]= pointer.exe

argv[1]= hello

argv[2]= world

argv[3]= Java

原來argv是一個字符指針數組,而字符指針就是一個字符串,所以argv是一個字符串數組,而argc是這個數組的長度!并且字符串數組的元素來自于我們運行程序時攜帶的參數!

哈哈,沒想到學到這里,居然才把main函數給弄清楚。難怪當初老爹不給我多講main函數,因為講我的確也難以理解,說不定還會因此畏難而放棄學習。

主站蜘蛛池模板: 马龙县| 沅江市| 安图县| 兴文县| 浪卡子县| 石家庄市| 兴国县| 兴业县| 盐池县| 阿拉尔市| 耿马| 玛纳斯县| 沽源县| 怀柔区| 洛浦县| 库尔勒市| 马关县| 南召县| 蒙城县| 扎鲁特旗| 大关县| 武穴市| 天镇县| 桐梓县| 文登市| 城固县| 汝阳县| 桂东县| 德兴市| 清徐县| 六枝特区| 博爱县| 永宁县| 多伦县| 鄂州市| 清新县| 乌兰察布市| 望谟县| 武川县| 龙口市| 福海县|