函式指標,顧名思義,也就是指標,不過這個指標是指向函式的指標。
在【 c 】高階指標話題之高階宣告的演進 這篇博文中提到了函式指標的宣告等,摘出來:
接下來的乙個宣告更有趣,但也更容易讓人疑惑:如果上面的引用不清楚的話,我在試著解釋一遍:確定括號的含義是分析這個宣告的乙個重要步驟。這個宣告有兩個括號,每對的含義各不相同。第2個括號是函式呼叫操作符,第1個括號只起到聚組的作用。它迫使間接訪問在函式呼叫之前進行,使 f 成為乙個函式指標,它所指向的函式返回乙個整型值。int (*f)();
何為函式指標?
程式中的每個函式都位於記憶體中的某個位置,所以存在指向那個位置的指標是完全可能的。
int (*f)();
先執行括號裡面的內容,也就是間接訪問操作,可見 f 是乙個指標,可是之後就進行函式呼叫的操作,可見該指標是還不是一般的指標,該指標指向乙個函式,稱該指標為函式指標。
函式指標有什麼用呢?最常見的兩個用途是轉換表(jump table)和作為引數傳遞給另乙個函式。但是本博文不涉及其應用,只是簡單地了解一下函式指標以及函式指標的初始化!
必須提出,和其他型別的指標一樣,簡單宣告乙個函式指標並不意味著可以馬上使用,對函式指標執行間接訪問之前必須初始化為指向某個具體的函式。而這個過程十分的有意思,下面的**說明了一種初始化函式指標的方法:
int f( int );
int (*pf)( int ) = &f;
第2個宣告建立了乙個函式指標並把它初始化為指向函式 f 。這裡關鍵的問題是:在函式初始化之前具有 f 的原型是很重要的,否則編譯器就無法檢測 f 的型別是否與 pf 所指向的型別一致。
下面更有意思的內容來了:
初始化表示式中的 &(取位址操作符)是可選的,因為函式名被使用時總是由編譯器把它轉換為函式指標。&操作符只是顯式地說明了編譯器隱式執行的任務。
在函式指標被宣告以及初始化之後,我們就可以使用三種方式來呼叫函式:
int ans;
ans = f( 25 );
ans = (*pf)(25);
ans = pf(25);
這三種方式呼叫函式完成的功能是完全相同的,這看起來有些荒謬,特別是第三條,而實際上並非如你所想,下面一一道來:
第1條語句簡單地使用名字來呼叫函式,這是我們最常用的呼叫函式的方法,但它的執行過程可能和你想象的不太一樣。函式名f首先被轉化為乙個函式指標,該指標指定函式在記憶體中的位置。然後,函式呼叫操作符()呼叫該函式,執行開始於這個位址的**。
第2條語句對pf執行間接訪問操作,它把函式指標轉化為乙個函式名。這個轉換並不是真正需要的,因為編譯器在執行函式呼叫操作符之前又會把它轉換回去。
第3條語句和前兩天語句效果一樣,只不過省去了在第1種情況下,編譯器把函式名 f 轉換為函式指標的過程,這裡是直接執行函式在該處的**。
仔細品味這些說明,真是大開眼界!
C指標初識
指標是乙個變數,其值為另乙個變數的位址,即,記憶體位置的直接位址。就像其他變數或常量一樣,您必須在使用指標儲存其他變數位址之前,對其進行宣告。指標變數宣告的一般形式為 type var name 在這裡,type是指標的基型別,它必須是乙個有效的 c 資料型別,var name是指標變數的名稱。用來...
C 初識指標
定義乙個指標指向乙個變數的位址 type p var int i int p i 通過 p讀寫i的值 p 10 int a p 用乙個指標指向另乙個指標的位址,不管幾級指標都是指標.type q p char p abc char q p 讀取二級指標的值 printf s n q 等價於 prin...
初識C指標
什麼是指標?type var name int a 乙個整型的指標 double b 乙個 double 型的指標 float c 乙個浮點型的指標 char ch 乙個字元型的指標 所有實際資料型別,不管是整型 浮點型 字元型,還是其他的資料型別,對應指標的值的型別都是一樣的,都是乙個代表記憶體位...