2009-10-28 60 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++和多态,这将让你你的烦恼:)