2009-10-28 36 views
1

在我的C項目中我有五個不同的函數(具有相同的名稱),它們以不同的方式實現一個算法。在編譯時,我只需要選擇其中的一個函數。 我可以使用#define和一堆#ifndef來實現嗎?有沒有更好的方法來做到這一點?在編譯時選擇一個函數

回答

15

可能是一個更優雅的方法是用5個不同的名稱(例如F1,F2,F3,F4,F5)定義它們,但總是調用使用相同的不同名稱的功能(例如F)。然後編譯類似的東西:

 
gcc -Df=f1 

這將編譯任何調用f()作爲調用f1()。

+1

+1爲避免無盡的#ifdef的。無論如何編譯器會優化未使用的函數。 – 2009-10-28 22:44:31

+0

編譯器應該優化它,但實際上呢? (只讀這讓我想知道:http://utilitybase.com/article/show/2007/04/09/225/Size+does+matter:+Optimizing+with+size+in+mind+with+GCC) – 2009-10-28 23:02:21

+0

如果函數被聲明爲靜態,它可能無法編譯 – eyalm 2009-10-29 03:04:41

1

在C中,這是我知道這樣做的唯一途徑。 C++你會很幸運。

0

ifndef宏在編譯時似乎是唯一的可能性。

您可以在運行時嘗試使用函數ptrs。

只是認爲你可以創建不同的文件中的每個功能,並連接適當的一個,只要你想。沒有宏,只是一個Makefile開關。這樣你保持相同的簽名並在鏈接時決定使用哪個實現。鏈接algo1.o或鏈接algo2.o ...

5

是的。你要做的就是在代碼中這樣說:

#if defined(FUNC1) 
    ...func1 here 
#elif defined(FUNC2) 
    ...func2 here 
...ect. ect. 
#endif 

然後當你編譯添加例如gcc的選項-DFUNCX:

gcc -DFUNC1 -o myprogram myfile.c 

然後你可以選擇哪些功能通過改變來編譯值放在-D選項中。這是非常普遍的做法。

+3

一個小問題是,它可以調用如果您意外地同時定義了FUNCx和FUNCy,則可以使用多種功能。要解決這個問題,你應該使用「#if defined(FUNC1)」,「#elif defined(FUNC2)」等。 – 2009-10-28 22:40:56

+0

好點;我的錯。現在編輯代碼以反映這一點。 – 2009-10-28 22:45:14

0

如果我是你,我會擁有5種不同的函數名,然後使用if語句來找出在運行時調用哪一個。

0

C沒有重載(操作符或其他),所以沒有其他方法來做到這一點。恐怕你被預處理器命令困住了。

3

您不能在一個翻譯單元中定義具有相同名稱的兩個不同功能。

所以我想你已經有不同的源文件分開的功能。只要有你想要的文件,當您編譯...例如,用gcc

gcc -o testsort main.c bubble.c 
gcc -o testsort main.c merge.c 
gcc -o testsort main.c radix.c 

凡有任何的bubble.cmerge.cradix.c(和其他人)具有相同名稱的功能:

int sort(int *data, size_t len) { /* ... */ } 
1

如果你有單獨文件中的函數源(對於我的例子,在f1.c和f2中。C),那麼這個方案的工作原理:

$ cat so.c 
#define STRINGIZER(x) #x 
#define HEADER(x) STRINGIZER(x) 

#include HEADER(SOURCE) 

int main(void) 
{ 
    return(function()); 
} 
$ cat f1.c 
static int function(void) 
{ 
    return(1); 
} 
$ cat f2.c 
static int function(void) 
{ 
    return(2); 
} 
$ 

然後,我可以這樣進行編譯:

$ gcc -DSOURCE=f1.c -o so1 so.c 
$ gcc -DSOURCE=f2.c -o so2 so.c 

注意使用stringize運營商和雙宏觀舞蹈 - 這是爲一個標準的成語標準C預處理器。它允許我避免在C編譯器命令行中放置引號;認爲這將是多麼更難使用,如果你有寫:

$ ./so1; echo $? 
1 
$ ./so2; echo $? 
2 
$ 

這顯示了一種替代的方式來實現,沒有任何希望的結果:

$ gxx -DSOURCE='"f1.c"' -o so1.c 

是正在運行的S01和S02的結果#ifdef行。

0

如果你一定要堅持使用C,你可以使用函數指針,但我會建議你使用C++和多態,這將讓你你的煩惱:)

相關問題