指向函数的指针--转
http://book.51cto.com/art/200908/146363.htm
5.1.2 指向函數的指針
C語言通過&和*操作符來操作數據的地址,但它并沒有提供一個用一般的方式來操作代碼的地址。然而,C語言并沒有完全切斷程序員操作代碼地址的可能,它提供了一些"受限制的"方式來操作代碼的地址。之所以說這些方式是"受限制的",那是因為這些方式并不像操作數據地址那樣自由和靈活。
在C語言中,指針變量也可以指向一個函數。我們已經知道代碼也是有地址的,一個函數在編譯時會被分配給一個入口地址,這個入口地址就是該函數中第一條指令的地址,這就是該函數的指針。當調用一個函數時除了通過函數名來調用以外,還可以通過指向該函數的指針變量來調用。一個指向函數的指針其初始值不能為空,因為它在使用之前必須被賦予一個真實的函數地址。指向函數的指針變量的一般定義形式如下(其中的函數類型是指函數返回值的類型):
請看下面這段示例代碼,它使用普通的函數名方式來實現函數的調用,此函數用于實現矩形法求解
?
函數定積分的功能。
現在我們改寫上面的代碼,使用一個指向函數的指針變量來調用函數。
關于上面的代碼,有如下幾點需要說明。
①語句"double (*p)(double, double);"定義p是一個指向函數的指針變量,此函數的返回值類型為double型。特別地,double (*p) ()并非是指向某一固定函數的,它僅僅表示定義了這樣一個類型的變量,在程序中可以將不同的函數地址賦給它,由此它所指向的函數就會隨之變化。
②(*p)兩側的括號不能省略,這樣的語法意味著p先與*結合,是一個指針變量;再與后面的括號()結合,表示此指針變量指向函數而非變量。如果將*p兩側的括號去掉,則變成double *p(),這樣表示的意思是函數p()的返回值類型是一個指向double型變量的指針。本書前面也介紹過因為()的優先級高于*,所以p會先與()結合,由此就聲明了一個函數而非指針。
③賦值語句"p = func1;"的意思是將函數func1的入口地址(即函數中首條指令的地址)賦給指針變量p。易見,在給函數指針變量賦值時,只需要給出函數名即可,并不需要給出參數,因此如果將上面的賦值語句改寫成"p = func1(0.0, 1.0);"則是錯誤的!但是由于這里僅僅使用了函數名,而不帶括號和參數,為了不讓編譯器將其與變量混淆,必須在使用之前進行聲明,表明func1是函數名而非變量名,這樣編譯時它們才會被當作函數名來處理。
④在使用函數指針時,只需將(*p)替代函數名即可,但是需要在其后的括號里顯式地添加實參,即使函數不傳遞任何參數,該括號也不可省略。
⑤數組名可以代表數組的起始地址(數組中首元素的地址),所以函數名也可以代表函數的入口地址(函數中的首條指令的地址)。但是對于指向函數的指針變量,它只能指向函數的入口處而無法指向函數中某一條具體的指令,因此對于p+n、p++等指針運算對于指向函數的指針是沒有意義的。
⑥獲得一個函數地址的方法與獲得一個變量地址的方法一樣,于是前面程序中的語句"p = func1;"也可以寫作"p = &func1; "。但是,必須保證函數func1已經在某個地方被聲明過了。
指向函數的指針可以獲得函數的入口地址,但它并不能像操作數組一樣獲得函數中每一條指令的地址,這樣的操作是相對受限的。但人們不禁要問,這種語法有什么用處呢?函數指針最常用的地方是作為參數傳遞給其他的函數。指向函數的指針也可以作為參數以實現函數地址的傳遞,也就是將函數名傳遞給形式參數。但是我們知道,在某個函數中調用另外一個函數僅僅需要在此函數中直接調用所需的函數就可以了,這是C語言所支持的非常基本的函數調用語法。如此看來,將函數指針作為參數來傳遞,然后在函數體中使用實在是多此一舉、畫蛇添足。然而,將函數指針作為參數來使用還是非常有用的,尤其當每次函數所調用的其他函數無法固定時,這就顯得尤為重要了。假設有函數fun,在某次執行過程中需要調用函數func1,而下一次就需要調用函數func2,再下一次又可能調用func3。如果使用函數指針,則不必對函數fun進行修改,只需要讓其每次調用函數時通過不同的函數名來作為形參傳遞即可。這種方法極大地增加了函數使用的靈活性,我們可以編寫一個通用的函數來實現各種專用的功能,這是符合結構化程序設計思想的方法。
下面通過一個簡單的示例程序來說明這種方法的應用。該例子編寫了一個求定積分的通用函數,用它可以分別求得3個函數的定積分:。可見,每次需要求定積分的函數并不相同,但是我們可以使用一個通用的函數integral,并通過3個形式參數:上限 b、下限a和指向函數的指針變量fun來顯示各自專用的定積分求解函數。其中,函數func1用于求解函數? 的定積分,func2用于求解函數?的定積分,func3用于求解函數? 的定積分。
完成編碼后,編譯并運行程序。
轉載于:https://www.cnblogs.com/davidwang456/p/3456963.html
總結
以上是生活随笔為你收集整理的指向函数的指针--转的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c之指针与数组(1)
- 下一篇: JAVA的静态代理与动态代理比较--转载