2013年8月19日 星期一

指向函數的指標(pointer to function)(aka: Function Pointer) V.S. 傳回指標的函數(function return a pointer)

From: 指標的藝術

Function Pointer:(指向函數的指標)

int (*pf)(int);

在指標的藝術一書(p.87)中又名Pointer to function。目的是經過宣告後,會有一個指標是指向函數的起始位址,當我們要使用某個函數的時候,只要將此指標指向那個函數,就可使用,其實函數名稱是一個位址,因此只要將函數名稱設定給此指標即可。

使用函數指標的時候必須注意指標的引入與回傳參數是否與原函式匹配,就說原函式引入、回傳的資料型態,引入參數個數,通通要一樣才可以。

例如三個副函式:

(1) int add(int);
(2) float add2(float);
(3) int add3(int,int);

並且宣告一個函式指標:
int (*pf)(int);

則:

(a.) pf = add;     //正確
(b.) pf = add2;   //錯誤,參數資料型態不匹配
(c.) pf = add3;   //錯誤,引入參數個數不匹配

#################################################################################

Function return a pointer:(回傳指標的函數)

int *pf(int); //少了一個括號cf: int (*pf)(int);

表示pf是一個函數,這個函數會引入一個整數型態的參數,經過函數運算後會回傳一個整數型態的指標(回傳的東西是一個位址,假設回傳x,則x可以是指標(x存的內容是指向的位址),也可以是變數的位址,若x是一般變數,則回傳&x;若x是陣列則回傳x。

#################################################################################

typedef與函數指標(from wiki typedef)

Using typedef with function pointers[edit source | editbeta]

Function pointers are somewhat different than all other types because the syntax does not follow the pattern typedef <old type name> <new alias>;. Instead, the new alias for the type appears in the middle between the return type (on the left) and the argument types (on the right). Consider the following code, which does not use a typedef:
int do_math(float arg1, int arg2) {
    return arg2;
}
 
int call_a_func(int (*call_this)(float, int)) {
    int output = call_this(5.5, 7);
    return output;
}
 
int final_result = call_a_func(do_math);
This code can be rewritten with a typedef as follows:
typedef int (*MathFunc)(float, int);
 
int do_math(float arg1, int arg2) {
    return arg2;
}
 
int call_a_func(MathFunc call_this) {
    int output = call_this(5.5, 7);
    return output;
}
 
int final_result = call_a_func(do_math);
Here, MathFunc is the new alias for the type. A MathFunc is a pointer to a function that returns an integer and takes as arguments a float followed by an integer.

typedef int (*MathFunc)(float, int);是別名的宣告,就只是在最前面加上typedef則以後就可以只用MathFunc這樣的名稱來宣告同類型的函數指標。


5 則留言:

  1. 請問大大,指向函數的指標傳回值為指標的宣告方式為何?
    類似這樣子嗎? --> int *(*pf)(int *)
    蠻好奇的 ^^

    回覆刪除
  2. 請問為何不直接呼叫do_math就好

    回覆刪除
    回覆
    1. 我也想要知道你的問題,希望能解惑

      刪除
    2. function pointer通常是用在作業系統相關的程式上
      讓一堆function有一樣的return value, argument type可以在thread create或是工作排程的時候作為argument丟進去OS的API.
      可以看看Pthread_create

      刪除