函數指針,指針函數,返回值爲指針的函數

摘要:

在學習C語言時,一個比較容易混淆的概念就是函數指針、指針函數、返回值爲指針的函數。本文將對這三個概念進行區分。指針函數就是返回值爲指針的函數,兩個本質上是同一事物,只是叫法不同。函數指針就是一個指向函數的指針,本質上是一個指針,只是這個指針指向的對象是函數,而不是一般意義上的存儲對象。

正文:

指針函數

指針函數就是返回指針值的函數,本質是一個函數。所以指針函數等價於“返回值爲指針的函數”。

定義

指針函數的定義格式如下:函數類型 *函數名([參數列表])

當然,也可以讓指針標誌*與函數類型緊貼在一起,與函數名分開,其含義一致,格式如下:函數類型* 函數名([參數列表])

相比上一種,這種方式更能表示這是一個指針函數。在將指針函數與函數指針區分時,也可以通過“指針標誌*能否和函數名分離”來判斷這個一個指針函數,還是一個函數指針。

返回值問題

指針函數的使用和一般函數的使用相同,但需注意返回值問題。對於一個返回值爲指針的函數,不能返回auto型局部變量的地址,但可返回static型變量的地址。

這是因爲auto型變量的生存週期很短,當函數返回時,auto型變量的內存空間將被釋放,如果返回值是auto型變量,那麼這個返回指針將無效,變成野指針。而static類型變量佔用的內存空間則不會因爲函數返回而被釋放,不會出現野指針問題。

所以編寫指針函數使要注意返回值。總體原則是:返回的指針對應的內存空間不會因函數返回則被釋放掉。常用的返回指針有以下幾種:

(1)      函數中動態分配內存空間(通過malloc等實現)的首地址;

(2)      靜態變量(static)或全局變量所對應的變量的首地址;

(3)      通過指針形參所獲得的實參的有效地址。

函數指針

函數指針就是一個指向函數的指針。每個函數在編譯時,會被分配一個入口地址,一般用函數名來表示,這個地址就是該函數的指針。

定義

函數指針的定義格式如下:函數類型 (*指針變量) ([參數列表])

在形式上,函數指針的特徵是使用一個括號包裹指針標誌和指針變量,將括號移除,函數指針就變成指針函數。

之所以容易混淆指針函數和函數指針,是因爲指針函數的形式如一般指針變量類型,如:int *x、int *y()、int(*z)()

這裏x和z表示一個指針,而y則表示一個函數,所以要注意區分指向變量的指針和指向函數的指針的形式區別。

賦值

函數指針的賦值操作:

使用函數名給指向函數的指針變量賦值。其賦值的一般格式如下:函數指針 = [ &] 函數名;

其中,函數名後不能帶括號和參數,函數名前的&是可選,建議不要使用。

調用

函數指針調用格式:函數指針變量([實參列表]); 或 (*函數指針變量)([實參列表]);

推薦第二種用法。這種方法可以很好的表明這是一個函數。而第一種方法則很容易造成誤導。

之所以容忍一種調用方法是因爲ANSI C 委員會決定容許這種普通函數調用句法。這是因爲編譯器知道它是一個指向函數的指針,並且它還知道在該環境下所能做的惟一的一件事就是調用函數,因此這裏沒有任何模糊不清的表達。

使用場景

函數指針的常見用途就是把函數指針作爲參數傳遞給函數。

一個函數通過由運行時決定的指針來調用另一個函數的行爲叫做回調(callback)。用戶將一個函數指針作爲參數傳遞給其它函數,後者將“回調”用戶的函數。這樣就可實現通過同一接口實現對不同類型數據、不同功能的處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章