「哦,曉得了。」
老爹說這些的確是現實中存在的問題,班上就有很多同學的家長不讓他們玩兒手機和電腦,說是會影響到學習。一方為了防止對方玩兒手機,另一方想突破對方的封鎖,於是雙方展開了一場場鬥智鬥勇,各有輸贏。
這大概就和老爹說的一樣吧,不能單純地從某個方面來看待這件事情。學習成績好的人有玩兒手機和電腦的,學習成績不好的也有不玩兒手機和電腦的,關鍵還是在於使用者如何使用吧。
當然了,一般來說小孩兒的自製能力比較差,這個時候就需要家長合理的管控了。毋庸置疑的是,老爹在這一點做得非常好。
「好了好了,閑話就說到這裡,咱們還是繼續說函數和指針之間那點事兒。其實函數和指針的關系也挺簡單的,無非就三種情況:指針作為函數參數,函數返回值為指針。
其中指針作為函數參數又有兩種情況,第一是指針變量指向的是數據,如int、double以及結構體或者枚舉這種,還有一種特例,那就是指針變量指向的是一個函數,我們把一個函數A的指針作為參數傳給另一個函數B,這樣在函數B中就可以通過這個指針調用函數A了,這就是所謂的回調函數。
概念性的東西咱們就先說到這裡,還是以實際的例子來說明吧。
首先說普通指針作為函數的參數,其實這種情況你們已經見識過了,我一開始說到的swap函數就是這樣了。我相信通過之前的講解,你們對這個函數的理解已經算是比較透徹了,這裡我們就不再贅述。
所以我們接下來看看當指針作為一個函數的返回值的這種情況,比如說我們來實現一個函數,功能是把給定的字符串轉成大寫的,並把轉換後的字符串返回。
由於字符串是一個char*,正好滿足指針作為返回值。
typedef char* String;
String toUpperCase(String str)
{
const char delta ='A'-'a';
String temp = str;
while (*temp !='\0')
{
if ('a' b ? b : a;
}
比如說這裡的max和min都符合條件,所以我們就可以這樣:
int (*fp_max)(int,int);
int (*fp_min)(int,int);
fp_max = max;
fp_min = min;
如果要使用函數指針來執行指向的函數,就需要這樣:
int maxValue =(*fp_max)(3,4);
int minValue =(*fp_min)(1,2);」
「看上去就好複雜的樣子……」
我皺著眉頭看著老爹幻燈片上敲出來的這些內容,突然覺得腦袋運轉都幾乎停滯了。
「既然如此,那我們就來解析一下。我們在聲明一個變量時,會使用int、
double等類型描述符,其本質在於告訴計算機這個變量的內存佔用情況,以及讀寫時的規則。是這樣的吧?」
我和小弦子點了點了點頭。
「那麽我們聲明這些變量的指針的時候,是不是也要聲明使用指針讀寫數據時的規則呢?」
「嗯嗯~」
「同樣的,我們在定義一個函數的時候,是不是要告訴計算機這個函數的返回值、參數列表?那麽同樣的,我們聲明一個函數指針也要具備這些啊。
在聲明一個指針變量的時候我們是不是會用到『*』?」
「是的~」
「同理,函數指針它也是一個指針,那它憑哪樣搞特殊不使用『*』來自報家門,告訴計算機自己是一個指針變量呢?
再問,當我們要訪問一個指針的指向的地址中的內容是,會使用什麽?」
「*」
「那不就結了麽?那函數指針雖然指向的是一個函數,那麽我們要訪問這個函數,不得也用『*』麽?
按照這個思路,你們再去看看上面的代碼,是不是就能夠明白其中的含義了呢?」
「臥槽,有道理啊!」
還別說,經過老爹這麽解釋,似乎還真的有那麽一些道理。
「其實啊,這種格式看上去的確是麻煩,而且fp_max和fp_min除了指針名字不一樣之外,其它都完全一樣,這不是重複代碼麽?所以我們得像個辦法把這個問題給解決了,不然以後我們要聲明很多類似函數指針的時候還不得累死。
要是後面再修改,比如說修改返回值類型,或者修改參數列表類型……」