函式指標指向的是函式而非物件。和其他指標一樣,函式指標指向某種特定型別。函式的型別由它的返回型別和形參型別共同決定,與函式名無關。例如:
//比較兩個stirng物件的長度
bool
lengthcompare
(const string &s1,
const string &s2)
;
該函式的型別是bool(const string &, const string &)。要宣告乙個可以指向該函式的指標,只需要用指標替換函式名即可:
//pf指向乙個函式,該函式的引數是兩個const string的引用,返回值是bool型別
bool
(*pf)
(const string &s1,
const string &s2)
;//未初始化
*pf兩段的括號必不可少。如果不寫這對括號,則pf是乙個返回值為bool指標的函式:
//宣告乙個名為pf的函式,該函式返回bool*
bool*pf
(const string &
,const string &
);
bool
(*pf)
(const string &s1,
const string &s2)
; pf = lengthcompare;
//pf指向名為lengthcompare的函式
pf =
&lengthcompare;
還能直接使用指標函式的指標呼叫該函式,無限提前解引用指標:
bool b1 =pf(
"hello"
,"goodbye");
//呼叫lengthcompare函式
bool b2 =
(*pf)
("hello"
,"goodbye");
//乙個等價的呼叫
bool b3 =
lengthcompare
("hello"
,"goodbye");
//另乙個等價的呼叫
可以為函式指標賦乙個nullptr或者值0的整型數常量表示式,表示該指標沒有指向任何乙個函式:
string::size_type sumlength
(const string&
,const string&);
bool
cstringcompare
(const
char*,
const
char*)
;pf =0;
//正確:pf不指向任何函式
pf =sumlength;
//錯誤:返回型別不匹配
pf =cstringcompare;
//錯誤:形參型別不匹配
pf =lengthcompare;
//正確:函式和指標的型別精確匹配
使用過載函式時,上下文必須清晰地界定到底應選用哪個函式。如果定義了指向過載函式的指標:
voidff(
int*);
voidff(
unsigned
int)
;void
(*pf1)
(unsigned
int)
=ff;
//pf1指向ff(unsigned)
編譯器通過指標型別決定選用哪個函式,指標型別必須與過載函式中的某乙個精確匹配:
void
(*pf2)
(int
)=ff;
//錯誤:沒有任何乙個ff與該形參列表匹配
double
(*pf3)
(int*)
=ff;
//錯誤:ff和pf3的返回型別不匹配
和陣列類似,雖然不能定義函式型別的形參,但是形參可以是指向函式的指標。此時,形參看起來是函式型別,實際上卻是當成指標使用:
//第三個形參是函式型別,它會自動轉換成指向函式的指標
void
usebigger
(const string &s1,
const string &s2,
boolpf(
const string&
,const string&))
;//等價的宣告:顯示地將形參定義成指向函式的指標
void
usebigger
(const string &s1,
const string &s2,
bool
(*pf)
(const string&
,const string&))
;
可以直接把函式作為實參使用,此時它會自動轉換成指標:
//自動將函式lengthcompare轉換成指向該函式的指標
usebigger
(s1,s2,lengthcompare)
;
直接使用函式指標型別顯得煩瑣。型別別名和decltype能簡化使用函式指標的**:
//func和fun2是函式型別
typedef
bool
func
(const string&
,const string&);
typedef
decltype
(lengthcompare) func2;
//等價的型別
//funcp和funcp2是指向函式的指標
typedef
bool
(*funcp)
(const string&
,const string&);
typedef
decltype
(lengthcompare)
*funcp2;
//等價的型別
decltype返回函式型別,不會將函式型別自動轉換成指標型別。所以要在結果前面加上*才能得到指標。可以使用如下的形式重新宣告usebigger:
//usebigger的等價宣告,其中使用了型別別名
void
usebigger
(const string &s1,
const string &s2,func)
;void
usebigger
(const string &s1,
const string &s2,funcp2)
;
和陣列類似,雖然不能返回乙個函式,但是能返回指向函式型別的指標。然而,必須把返回型別寫成指標形式,編譯器不會自動地將函式返回型別當成對應的指標型別處理。想要宣告乙個返回函式指標的函式,最簡單的方法使用型別別名:
using f =
int(
int*
,int);
//f是函式型別,不是指標
using pf =
int(*)
(int*,
int)
;//pf是指標型別
返回型別不會自動轉換成指標。必須顯示地將返回型別指定為指標:
pf f1
(int);
//正確:pf是指向函式的指標,f1返回指向函式的指標
f f1
(int);
//錯誤:f是函式型別,f1不能返回乙個函式
f *f1
(int);
//正確:顯示地指定返回型別是指向函式的指標
也能用下面的形式直接宣告f1:
int(*
f1(int))(
int*
,int
);
C 學習筆記 函式指標與指標函式
函式指標 指向函式的指標,首先它是指標變數 同指向乙個整形變數 字元 陣列一樣 其次它指向乙個函式 位址 宣告 函式型別 指標變數名 形參列表 函式型別,指明函式的返回型別,由於 優先順序高於 所以指標變數名外的括號不能少,後面形參列表表示指標變數指向的函式所帶的引數列表。上面相當於用函式指標p,代...
C 學習筆記 函式指標
1 c 指標函式基礎 函式是有位址的,它表示函式執行的入口。我們知道位址值並沒有用,但是可以將位址值當做實參傳入到其它函式中,這可以在不同的時期呼叫不同的函式。函式指標包括三點 如何獲取函式位址,如何申明函式指標,如何呼叫函式。簡單示例 include double betsy int double...
《C語言筆記 函式指標》
一,函式指標的實質 1,函式指標的實質還是指標,還是指標變數。本身佔四個位元組 32位系統 2,函式指標 陣列指標 普通指標之間本身沒有區別,區別在於指標指向的東西是個什麼玩意。函式指標指向乙個函式,陣列指標指向乙個陣列。3,函式的實質是一段 這一段 在記憶體中是連續分布的 乙個函式的大括號括起來的...