我們經(jīng)常會(huì)聽到這樣的說法,,不懂得函數(shù)指針就不是真正的C語言高手,。我們不管這句話對(duì)與否,但是它都從側(cè)面反應(yīng)出了函數(shù)指針的重要性,所以我們還是有必要掌握對(duì)函數(shù)指針的使用,。先來看看函數(shù)指針的定義吧。 函數(shù)是由執(zhí)行語句組成的指令序列或者代碼,,這些代碼的有序集合根據(jù)其大小被分配到一定的內(nèi)存空間中,,這一片內(nèi)存空間的起始地址就成為函數(shù)的地址,不同的函數(shù)有不同的函數(shù)地址,,編譯器通過函數(shù)名來索引函數(shù)的入口地址,,為了方便操作類型屬性相同的函數(shù),c/c++引入了函數(shù)指針,,函數(shù)指針就是指向代碼入口地址的指針,,是指向函數(shù)的指針變量。 因而“函數(shù)指針”本身首先應(yīng)該是指針變量,,只不過該指針變量指向函數(shù),。這正如用指針變量可指向整形變量、字符型,、數(shù)組一樣,,這里是指向函數(shù)。C在編譯時(shí),,每一個(gè)函數(shù)都有一個(gè)入口地址,,該入口地址就是函數(shù)指針?biāo)赶虻牡刂贰S辛酥赶蚝瘮?shù)的指針變量后,,可用該指針變量調(diào)用函數(shù),,就如同用指針變量可引用其他類型變量一樣,在這些概念上是一致的,。函數(shù)指針有兩個(gè)用途:調(diào)用函數(shù)和做函數(shù)的參數(shù),。 函數(shù)指針的聲明方法為: 數(shù)據(jù)類型標(biāo)志符 (指針變量名) (形參列表); “函數(shù)類型”說明函數(shù)的返回類型,由于“()”的優(yōu)先級(jí)高于“*”,所以指針變量名外的括號(hào)必不可少,,后面的“形參列表”表示指針變量指向的函數(shù)所帶的參數(shù)列表,。例如: int function(int x,int y); /* 聲明一個(gè)函數(shù) */ int (*f) (int x,,int y); /* 聲明一個(gè)函數(shù)指針 */ f=function; /* 將function函數(shù)的首地址賦給指針f */ 賦值時(shí)函數(shù)function不帶括號(hào),,也不帶參數(shù),由于function代表函數(shù)的首地址,,因此經(jīng)過賦值以后,,指針f就指向函數(shù)function(int x,int y);的代碼的首地址,。 下面的程序說明了函數(shù)指針調(diào)用函數(shù)的方法: 例一,、 #include<stdio.h> 注意:以上代碼的紅色部分我們將會(huì)在接下來的代碼分析部分進(jìn)行講解,讀者也可以思考下如果運(yùn)行注釋部分,結(jié)果是否還是正確的呢,? f是指向函數(shù)的指針變量,,所以可把函數(shù)max()賦給f作為f的值,即把max()的入口地址賦給f,以后就可以用f來調(diào)用該函數(shù),,實(shí)際上f和max都指向同一個(gè)入口地址,,不同就是f是一個(gè)指針變量,不像函數(shù)名稱那樣是死的,,它可以指向任何函數(shù),,就看你想怎么做了。在程序中把哪個(gè)函數(shù)的地址賦給它,,它就指向哪個(gè)函數(shù),。而后用指針變量調(diào)用它,因此可以先后指向不同的函數(shù),。不過注意,,指向函數(shù)的指針變量沒有++和--運(yùn)算,用時(shí)要小心,。
函數(shù)括號(hào)中的形參可有可無,,視情況而定,不過,在某些編譯器中這是不能通過的,。這個(gè)例子的補(bǔ)充如下,。 1.定義函數(shù)指針類型: typedef int (*fun_ptr)(int,int); 2.申明變量,賦值: fun_ptr max_func=max; 也就是說,,賦給函數(shù)指針的函數(shù)應(yīng)該和函數(shù)指針?biāo)傅暮瘮?shù)原型是一致的,。 例二、 #include<stdio.h> void FileFunc() { printf("FileFunc\n"); } void EditFunc() { printf("EditFunc\n"); } void main() { typedef void (*funcp)(); funcp pfun= FileFunc; pfun(); pfun = EditFunc; pfun(); } 看了上面兩段代碼,,應(yīng)該都知道如何用函數(shù)指針來調(diào)用函數(shù)了,,但是我們剛剛在上面的描述中留下過一個(gè)問題,就是運(yùn)行注釋部分f=&max;結(jié)果是否還是正確的呢,?下面我就給出上面兩個(gè)運(yùn)行結(jié)果的對(duì)別,,然后來分析下原因。 有注釋前的運(yùn)行結(jié)果為: 把注釋部分加進(jìn)去的運(yùn)行結(jié)果為: 對(duì)比以上的運(yùn)行結(jié)果可以看出,,f=&max語句被執(zhí)行時(shí)的結(jié)果和沒有被執(zhí)行時(shí)的結(jié)果是一樣的,。為什么會(huì)出現(xiàn)這樣的結(jié)果呢?答案是這是編譯器處理的,,max本身就是個(gè)地址,,它沒有放到任何變量里,自然沒有取它的地址一說,。所以我們可以看看在調(diào)試的過程中&max的值和max的值是一樣的,。調(diào)試代碼如下: root@ubuntu:/home/shiyan# gdb ss Breakpoint 1, main () at hanshu.c:5 在調(diào)試的過程中我print了很多的信息,,細(xì)心的讀者肯定能獲得更多的收獲,尤其是對(duì)變量f的print,,讀者可以自己閱讀,,學(xué)到更多的東西。我給出的只是一個(gè)參考的調(diào)試方式,,希望讀者能夠舉一反三,,自己對(duì)代碼進(jìn)行實(shí)際的調(diào)試,加深理解,。 上面說的都是用指針來實(shí)現(xiàn)函數(shù)的調(diào)用,接下來我們看一個(gè)用函數(shù)指針作為參數(shù)的用法,。 #include <iostream> 運(yùn)行結(jié)果如下:
看了上面的描述,,我想都對(duì)函數(shù)指針的概念有了大致的了解,另外一個(gè)希望大家不要混淆的概念就是指針函數(shù),,,這兩個(gè)概念都是簡稱,,指針函數(shù)是指帶指針的函數(shù),即本質(zhì)是一個(gè)函數(shù),。我們知道函數(shù)都又有返回類型(如果不返回值,,則為無值型,即為void),,只不過指針函數(shù)返回類型是某一類型的指針,。 其定義格式如下所示: 返回類型標(biāo)識(shí)符 *返回名稱(形式參數(shù)表) { 函數(shù)體} 返回類型可以是任何基本類型和復(fù)合類型。返回指針的函數(shù)的用途十分廣泛,。事實(shí)上,,每一個(gè)函數(shù),即使它不帶有返回某種類型的指針,,它本身都有一個(gè)入口地址,,該地址相當(dāng)于一個(gè)指針。比如函數(shù)返回一個(gè)整型值,,實(shí)際上也相當(dāng)于返回一個(gè)指針變量的值,,不過這時(shí)的變量是函數(shù)本身而已,而整個(gè)函數(shù)相當(dāng)于一個(gè)“變量”,,關(guān)于函數(shù)的返回值問題我將在下一章來講解,,本章到此為止。希望以上內(nèi)容對(duì)你有所幫助,! 還是那句話,,c語言博大精深,本人還是菜鳥,,難免有錯(cuò),,希望大家指正,如需轉(zhuǎn)載,請(qǐng)注明出處,。
|
|