如果我使用宏:
#define AND
以下列方式:
if(...)
{
...
}
elseANDif(...)
{
...
}
预处理器产生什么输出?
修改 我打算用:
#define TEST(params) if(...){...}else
... in if(...)是一个使用params的复杂表达式
... {...}执行一些操作&独立于params
#define AND
TEST(x1) AND TEST(x2)
{
//the code for the final else
}
AND在这里有帮助还是没有它?
答案 0 :(得分:9)
不,这不会像你期望的那样起作用。您可以通过cpp
运行代码来测试预处理器的功能。
eliben@eliben-desktop:~/temp$ cat z.c
#define AND
if(...)
{
...
}
elseANDif(...)
{
...
}
eliben@eliben-desktop:~/temp$ cpp z.c
# 1 "z.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "z.c"
if(...)
{
...
}
elseANDif(...)
{
...
}
技术原因是当cpp
扩展宏时,它会查找与此宏名称匹配的完整标识符标记。即在您的情况下,它会查找标识符AND
。但是,当它解析代码时,它找不到这样的标识符。它找到elseANDif
这是一个完全不同的标识符。它无法将elseANDif
分解为成分,这是一件好事,因为否则宏会非常糟糕。想象:
const int FUSIONDEBUG = 5;
无论这意味着什么,在真正的C代码中,这会破坏性,因为NDEBUG
几乎总是在生产代码中定义为空(谷歌在NDEBUG
意味着什么)。
关于您的编辑,我可以就此类问题向您提供的最佳建议是不要做。 (ab)使用这样的宏可能首先出现,使代码更具可读性,但从长远来看,它使得它的可读性更低,增加的危险是宏很难完全正确并且令牌的某些组合可以吹非常感谢你。
所以你绝对可以不使用AND
以及完全不使用TEST
。
答案 1 :(得分:2)
此:
#define TEST(condn) if(...){...}else
是胡说八道;你期望椭圆(...)做什么!?
您提供的示例用法将扩展为
if(...){...} else if(...){...}else
{
//the code for the final else
}
这显然是胡说八道;使用condn
参数在哪里?无论哪种方式你真正想要的除了虚拟可读性之外没有任何影响。如果您尝试发明一种新语言,则C预处理器不是这样做的方法。我认为你试图通过更直接的代码实现的目标没有任何优势。
如果您打算:
#define TEST(condn) if(condn){/*some code*/}else
那么结果如何:
if(a==b){/*some code*/} else if(b==c){/*some code*/}else
{
//the code for the final else
}
优于:
if(a==b || b==c)
{
/*some code*/
}
else
{
//the code for the final else
}
哪里/*some code*/
没有不必要的重复?
请注意,||
链接的单个条件等同于else if
链接的多个条件,因此即使您使用TEST
宏,也无需使用它这样的时候:
TEST( a==b || b==c)
{
//the code for the final else
}
就足够了。
在最好的时候,宏往往是不明智的,但你选择了宏观滥用的一个特别好的例子!例如,考虑如何在源级调试器中调试此类代码。
答案 2 :(得分:1)
对你的问题的简短回答是“是”。你当然可以做你的建议。这是一个基本的工作示例:
#include <stdio.h>
#define AND
#define TEST(params) if (!params) { printf(#params " was false\n"); } else
int main(int argc, char ** argv)
{
int param_1 = 1;
int param_2 = 0;
TEST(param_1) AND TEST(param_2)
{
printf("success!\n");
}
}
宏扩展后,代码基本上如下所示:
int main(int argc, char ** argv)
{
int param_1 = 1;
int param_2 = 0;
if (!param_1) { printf("param_1 was false\n"); } else
if (!param_2) { printf("param_2 was false\n"); } else
{
printf("success!\n");
}
}
正如其他人所指出的,做这样的事情是值得怀疑的,因为它会让人们阅读代码的方式变得混乱,并且可能使未来的调试变得困难。在这种情况下,如果可能的话,我肯定会建议使用函数调用。这是Secure在其评论中建议的方法:
int test_parameters(int params)
{
if (!params) { printf("bad parameters"); return 0; }
else { return 1; }
}
int main(int argc, char ** argv)
{
int param_1 = 1;
int param_2 = 0;
if (test_parameters(param_1) && test_parameters(param_2))
{
printf("success!\n");
}
}