在我的C项目中我有五个不同的函数(具有相同的名称),它们以不同的方式实现一个算法。在编译时,我只需要选择其中的一个函数。 我可以使用#define
和一堆#ifndef
来实现吗?有没有更好的方法来做到这一点?在编译时选择一个函数
回答
可能是一个更优雅的方法是用5个不同的名称(例如F1,F2,F3,F4,F5)定义它们,但总是调用使用相同的不同名称的功能(例如F)。然后编译类似的东西:
gcc -Df=f1
这将编译任何调用f()作为调用f1()。
在C中,这是我知道这样做的唯一途径。 C++你会很幸运。
ifndef宏在编译时似乎是唯一的可能性。
您可以在运行时尝试使用函数ptrs。
只是认为你可以创建不同的文件中的每个功能,并连接适当的一个,只要你想。没有宏,只是一个Makefile开关。这样你保持相同的签名并在链接时决定使用哪个实现。链接algo1.o或链接algo2.o ...
是的。你要做的就是在代码中这样说:
#if defined(FUNC1)
...func1 here
#elif defined(FUNC2)
...func2 here
...ect. ect.
#endif
然后当你编译添加例如gcc的选项-DFUNCX:
gcc -DFUNC1 -o myprogram myfile.c
然后你可以选择哪些功能通过改变来编译值放在-D选项中。这是非常普遍的做法。
一个小问题是,它可以调用如果您意外地同时定义了FUNCx和FUNCy,则可以使用多种功能。要解决这个问题,你应该使用“#if defined(FUNC1)”,“#elif defined(FUNC2)”等。 – 2009-10-28 22:40:56
好点;我的错。现在编辑代码以反映这一点。 – 2009-10-28 22:45:14
如果我是你,我会拥有5种不同的函数名,然后使用if语句来找出在运行时调用哪一个。
C没有重载(操作符或其他),所以没有其他方法来做到这一点。恐怕你被预处理器命令困住了。
您不能在一个翻译单元中定义具有相同名称的两个不同功能。
所以我想你已经有不同的源文件分开的功能。只要有你想要的文件,当您编译...例如,用gcc
gcc -o testsort main.c bubble.c
gcc -o testsort main.c merge.c
gcc -o testsort main.c radix.c
凡有任何的bubble.c
,merge.c
,radix.c
(和其他人)具有相同名称的功能:
int sort(int *data, size_t len) { /* ... */ }
如果你有单独文件中的函数源(对于我的例子,在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
行。
如果你一定要坚持使用C,你可以使用函数指针,但我会建议你使用C++和多态,这将让你你的烦恼:)
- 1. 在编译时选择使用模板调用哪个函数
- 2. 在编译时选择/发现extern函数调用的签名
- 3. 如何在编译时选择函数行为?
- 4. 在运行时编译函数C++编译时编译的函数的数量
- 5. 编译如何选择调用哪个模板函数?
- 6. Go - 编译一组函数时出错
- 7. 在编译时将一个泛型类传递给函数
- 8. 编译时纯虚函数
- 9. C++编译错误只有一个候选函数
- 10. 编译时检查jQuery选择器
- 11. 如何在运行时编译函数?
- 12. JAVA \仅在运行时编译函数
- 13. 在QComboBox中选择一个新项目时运行函数
- 14. “TypeError:$(...)。timepicker不是一个函数”在jquery时间选择器
- 15. 为什么C++编译器(VS2013)选择错误的函数?
- 16. SQL 2005 - 表值函数编译确定,但选择
- 17. 编译器如何选择正确的函数?
- 18. SqlParameter构造函数编译器超载选择
- 19. 哪个Android SDK选择编译
- 20. 如何在编译时在C#中运行一个函数或一段代码
- 21. 在PostgreSQL中编写一个函数来只在平日选择数据
- 22. CMake,选择Xcode编译器
- 23. 选择一个随机函数
- 24. 选择一个哈希函数
- 25. 强制选择另一个函数
- 26. 编写一个只需要编译时常量参数的函数?
- 27. 使用像宏一样的位图在编译时创建一个函数
- 28. 在运行时选择一个类的味道来实现一个函数?
- 29. 调用日期选择器选择从另一个函数
- 30. JIT编译器 - 编译器选择选项
+1为避免无尽的#ifdef的。无论如何编译器会优化未使用的函数。 – 2009-10-28 22:44:31
编译器应该优化它,但实际上呢? (只读这让我想知道: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
如果函数被声明为静态,它可能无法编译 – eyalm 2009-10-29 03:04:41