目錄
1.概念
2.例程
3.參考文獻
「in c, a function itself is not a variable, but it is possible to define pointers to functions, which can be assigned, placed in arrays, passed to functions, returned by functions, and so on.」在c語言中,乙個函式的函式名其實就是乙個位址,即該函式的入口位址。我們可以宣告乙個函式指標,並將函式的入口位址(函式名)賦值給這個指標,然後使用這個指標來呼叫具體的函式。
(1)宣告函式指標
有兩種方法,第一種:
int (*fun1)(int , int ) ;
第二種:
typedef int (*calculate_fun_t)(int ,int) ;
calculate_fun_t fun1 ;
在原理上,兩種都是一樣的,都是宣告了乙個名為fun1的函式指標,該指標指向的是乙個帶有兩個int型引數且返回值型別為int的函式。兩種方法的區別在於,第二種方法使用了型別定義(typedef)。一般在專案開發的時候,都是使用第二種方法。
使用型別定義有四個明顯的好處:1.自定義的型別名(此例為calculate_fun_t)為程式提供了更好更直觀的說明;2.在視覺上才像是宣告,便於理解;3.當函式指標指向的函式有很多引數且它們的型別各式各樣時,使用型別定義可以減少很多重複的東西,讓程式更簡潔;4.當乙個函式的引數型別是函式指標時(這裡可能有些拗口,不過看了例程後你就明白了),使用型別定義能讓程式更直觀易懂。
下面舉個例子,假設要宣告5個函式指標,它們都是指向乙個帶有6個引數(具體型別如下所示)且返回值型別為int的函式。很明顯,第二種方法寫出來的程式更順眼一些,能很直觀的看到宣告了5個函式指標,而第一種方法讓人眼花繚亂。
第一種:
int (*fun1)(int , char , void * , char * , short , long) ;
int (*fun2)(int , char , void * , char * , short , long) ;
int (*fun3)(int , char , void * , char * , short , long) ;
int (*fun4)(int , char , void * , char * , short , long) ;
int (*fun5)(int , char , void * , char * , short , long) ;
第二種:
typedef int (*fun_t)(int , char , void * , char * , short , long) ;
fun_t fun1 ;
fun_t fun2 ;
fun_t fun3 ;
fun_t fun4 ;
fun_t fun5 ;
在宣告函式指標的時候要特別注意括號,有沒有括號完全是兩種截然不同的意思。
int (*fun1)(int , int ) ;
int *fun1(int , int ) ;
第一行表示宣告了乙個名為fun1的函式指標,該指標指向的是乙個帶有兩個int型引數且返回值型別為int的函式;下面一行表示宣告了乙個名為fun1的函式,該函式的返回型別是int *,有兩個int型的引數。
(2)給函式指標賦值
函式指標和指向資料型別的指標沒有太大的區別,都可以被賦值、成為陣列元素、成為結構體成員、作為函式的引數、作為函式的返回值等等。指標是一種特殊的變數,裡面存放的是位址,對32位系統而言,存放的是乙個4位元組的無符號整數,對64位系統而言,指標存放的是乙個8位元組的無符號整數。
函式指標存放的也是位址,這個位址是乙個函式的入口位址,更直觀一點來說就是函式名。給函式指標賦值就是將乙個函式的入口位址存放到函式指標中。要特別注意的一點是,函式的引數個數,引數型別,返回值型別要和宣告函式指標時完全一致,才能賦值給函式指標。
給函式指標賦值有兩種形式,結果是一樣的:
int add(int , int) ;
typedef int (*calculate_fun_t)(int ,int) ;
calculate_fun_t fun1 ;
fun1 = add ; /* 第一種形式 */
fun1 = &add ; /* 第二種形式 */
第一種形式很直觀,函式名就是函式的入口位址,可以直接將它賦給函式指標;
第二種形式很奇怪,先對函式名取位址操作,再賦給函式指標。這時候就有疑問了,函式名不是變數,怎麼可以對它用取位址符呢?取位址之後會變成什麼呢?
「本來對函式名取位址是非法的,但很久以前有些編譯器已經允許這樣做,c/c++標準的制定者出於物件的概念已經有所發展的緣故,也承認了對函式名取位址的合法性。」add和&add的位址值是一樣的,但它們的型別不一樣,後者的型別是int (*)(int ,int)。所以,&add、(calculate_fun_t)add、(int (*)(int ,int))add是完全等價的,位址值和型別都相同。
(3)使用函式指標
給函式指標賦值後,就可以使用函式指標來呼叫具體的函式了。
使用函式指標也有兩種形式,這兩種形式的結果也是一樣的。
int a = 20 , b = 10 ;
calculate_fun_t fun1 = add ;
fun1(a,b) ; /* 第一種形式 */
(*fun1)(a,b); /* 第二種形式 */
下面用乙個具體的例程來說明上面描述的概念
例程的編輯環境和執行環境是ubuntu16.04
C語言 指標函式和函式指標
指標函式和函式指標 指標函式其實是乙個簡稱,是指帶指標的函式,它本質上是乙個函式,只是返回的是某種型別的指標。其定義的格式為 型別識別符號 函式名 參數列 函式指標,從本質上說是乙個指標,只是它指向的不是一般的變數,而是乙個函式。因為每個函式都有乙個入口位址,函式指標指向的就是函式的入口位址。其定義...
C語言 指標函式和函式指標
1 指標函式是指帶指標的函式,本質上是乙個函式,函式返回值是某一型別的指標 定義 型別識別符號 函式名 參數列 int f int x,int y 它首先是乙個函式,只不過這個函式的返回值是乙個位址值,函式返回值必須用同型別的指標變數來接受,也就是說,指標函式一定有函式返回值,而且,在主調函式中,函...
c語言函式指標與指標函式
include include include using namespace std 1 c語言函式指標 解釋 這是一種很特殊的指標,它的指向是乙個函式的入口 作用 該指標可以接受乙個函式的位址,代表這個函式執行函式的操作 函式指標舉例 下面是乙個函式指標pfunc,它只能指向返回值為float,...