2017-07-06 61 views
4

我看了,但找不到這個問題的直接參考。我是新來的函數指針(和C),所以我不知道所有的招數一個可以做但:)這是一個將函數傳遞給結構的正確方法嗎?

我已經得到了有效的函數:

void select_comparator(My_Struct *structure, int (*comp)(int x, int y)) { 
    ... 

...其中My_Struct有原型:

typedef struct my_struct { 
    int (*comp)(int x, int y); 
} My_Struct; 

Modulo一些小的細節。我只想知道下面的語法是否正確:

void select_comparator(My_Struct *structure, int (*comp)(int x, int y)) { 
    structure->comp = comp; 
} 

看起來好像太簡單了,我很擔心它。

回答

3

沒什麼錯:這是中回調的基礎。只要確保函數指針的簽名與結構中定義的類型相匹配即可。當它得到遠程棘手的是,當你在一個大型項目中使用此,人們忘記檢查,如果函數指針是有效或void,帶參數一起等

代碼


/******************************************************************************* 
* Preprocessor directives. 
******************************************************************************/ 
#include <stdio.h> 


/******************************************************************************* 
* Data types. 
******************************************************************************/ 
typedef struct my_struct { 
    int (*comp)(int x, int y); 
} My_Struct; 


/******************************************************************************* 
* Function prototypes. 
******************************************************************************/ 
int c(int a, int b); 
void select_comparator(My_Struct *structure, int (*comp)(int x, int y)); 


/******************************************************************************* 
* Function definitions. 
******************************************************************************/ 
/*----------------------------------------------------------------------------*/ 
int main(void) 
{ 
    My_Struct s; 

    select_comparator(&s, &c); 
    s.comp(1, 2); 

    return 0; 
} 

/*----------------------------------------------------------------------------*/ 
void select_comparator(My_Struct *structure, int (*comp)(int x, int y)) 
{ 
    structure->comp = comp; 
} 

/*----------------------------------------------------------------------------*/ 
int c(int a, int b) 
{ 
    int ret = 0; 
    if (a < b) { 
     ret = (-1); 
    } else if (a > b) { 
     ret = 1; 
    } 

    return ret; 
} 
+1

謝謝你關於退貨類型的提示!這實際上*是*將會是相關的,因爲我正在一個大型項目上工作...... – Chris

1

代碼沒問題。

雖然請注意,函數指針在C中具有簡單可怕的語法,特別是在傳遞給函數或從函數返回時。試着寫一些類似「函數返回函數指針,並將函數指針作爲參數」,你很快就會意識到語法是純粹的瘋狂。

因此,通過使用typedefs使函數指針與其他語言「一致」是一個好主意。

你的代碼可以這樣寫:

typedef int comp_t (int x, int y); // typedef a function type 

typedef struct { 
    comp_t* comp; // pointer to such a function type 
} My_Struct; 

void select_comparator(My_Struct *structure, comp_t* comp) { 
    structure->comp = comp; 
} 

現在的代碼變成更容易閱讀和函數指針的行爲非常像任何其他指針。

+1

他們可能會令人望而生畏,但並不存在那**不好。在我的「C」研究中,我很幸運地遇到了[對左右規則的很好解釋](http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html),並且它使語言的許多怪癖更容易遵循。 – DevNull

+0

@DevNull不,他們真的**很可怕。我有大約20年的C語言經驗,即使對於我來說,寫一些類似'function taking parameters ... ...函數指針函數帶參數...'的函數也是毫無意義的任務......(加上限定符)。在沒有typedef的情況下寫這樣的東西會花費我10分鐘。用typedefs寫它會花費我10秒。語法**是延遲的**,句號。甚至不值得花時間去學習語法 - 這是無用的知識。只要學習typedef,高效工作,編寫漂亮可讀的代碼。 – Lundin

+0

我一直在這個行業工作的時間相同,並且有着非常不同的經歷。解釋它們的邏輯雖然凌亂,但是僵化且明確。誠然,typedefs有自己的位置,並且使用大型團隊的函數指針更容易。 – DevNull

相關問題