2012-07-19 85 views
3

我想要一個函數指針,它可以採用各種類型的參數。我怎麼做?帶有未確定參數的函數指針

下面的例子(第1行),我想void (*fp)(int)也能夠採取void (*fp)(char*)以及。下面的代碼沒有正確編譯,因爲我傳遞了char *,其中int是預期的,所以編譯下面的代碼會給你警告(並且不能正常工作)。

void callIt(void (*fp)(int)) 
{ 
    (*fp)(5); 
} 

void intPrint(int x) 
{ 
    printf("%d\n", x); 
} 

void stringPrint(char *s) 
{ 
    printf("%s\n", s); 
} 

int main() 
{ 
    void (*fp1)(int) = intPrint; 
    callIt(fp1); 
    void (*fp2)(char*) = stringPrint; 
    callIt(fp2); 
    return 0; 
} 

注:我知道,試圖通過整數5爲char *參數是愚蠢的,但是這不是對這個問題的關注。如果你願意,你可以用float替換char *。

+0

你不會準確地得到你想要的C.你可以在C++中使用模板。在C中,您需要針對不同的類型使用不同的callIt函數。 – 2012-07-19 14:24:33

+0

無論如何'int(5)'是'floatPrint(float f)'的一個有效參數?您需要進行強制轉換,但如果您通過強制轉換擦除了函數指針類型,那麼這將不起作用。 – MSalters 2012-07-19 16:11:10

回答

3

我會說使用void (*fp)(void*),然後將指針傳遞給您的變量並將它們轉換爲void *。這很不好,但它應該工作。

如:

void callIt(void (*fp)(void*)) 
{ 
    int x = 5; 
    (*fp)((void*)&x); 
} 
+0

讓我試試看。 – 2012-07-19 14:26:50

+3

雖然這並不理想。你應該真的考慮重新設計這個程序,這樣你就不必訴諸這種拙劣的方法。 :) – 2012-07-19 14:27:30

+0

注意int x = 5的力量類型是int( – 2012-07-19 14:38:50

1

你期望調用stringPrint到底該怎麼做?

它看起來好像如果你得到這個工作,它會試圖打印內存位置5的內容作爲一個字符串。我懷疑這不是你想要的,因爲它會崩潰,我懷疑你打算輸出'5'。

還要注意...要求至少一個命名參數。傳遞一個void *和一個濫用數量的鑄造至少會編譯。

0

爲什麼不讓它成爲接受void *參數的函數指針?

void(*fp)(void*) 

這將處理所有可能的指針參數。現在對於數據類型,您可以爲每個函數指針類型指定一個函數指針類型,或者爲函數指針使用的函數指定一個函數指針類型,將數據類型作爲指針傳遞並在函數的開始處對它們進行解引用。這只是一個想法,不知道你想要做什麼。

1

雖然不好,但函數指針的類型並不重要。

只是把它定義爲

typedef void (*fp_t)(void * pv); 

你必須確保的唯一的事情是,你怎麼稱呼它的方式,你assigend它的功能相匹配。

int intFuncWithTwoDoubles(double d1, double d2); 
char * pCharFuncWithIntAndPointer(int i, void * pv); 

... 

fp_t fp = NULL; 

fp = intFuncWithTwoDoubles; 
printf("%d", fp(0.0, 1.0)); 

fp = pCharFuncWithIntAndPointer; 
printf("%s", fp(1, NULL)); 

... 
+0

我不是C標準大師,但這看起來相當哈克,可能是未定義的行爲,我絕對喜歡它完全無視類型安全。基本上,您依賴於編譯器安排任何參數並返回您在調用時設置的值,而不是使用函數指針的類型。你真的嘗試過嗎?它產生了哪些警告,錯誤和/或結果? – 2012-07-19 16:22:19

+0

@KevinVermeer:是的,看起來像一個骯髒的黑客。但是:它可以工作,但是在將函數addesses分配給指針時會產生關於類型不匹配的警告。但據我的調查顯示,它不**導致未定義的行爲(我將盡力在今天晚些時候發掘關於此的標準)。 – alk 2012-07-20 08:21:56