我有以下宏来打印出整数数组的内容以用于调试目的:
#define PRINT_ARRAY(ary, num) \
int ai = 0; \
printf("{"); \
for(ai=0; ai < num; ++ai) { \
printf("%d", ary[ai]); \
if(ai < num-1) printf(", "); \
} \
printf("}\n");
我遇到的问题是,当我多次使用它时,一些编译器会抱怨我正在重新定义ai
。
有没有办法让每次调用宏时标识符都不同?我可以提出一个名称冲突变化非常小的命名方案,但我想让它自动化。
我知道我可以使用一个函数,但我仍然很好奇,因为我想知道是否有办法用宏来做这个。
答案 0 :(得分:6)
为什么不使用经典的do-while技巧?例如:
#define FOO(EXPR) \
do { \
(EXPR); \
} while(0)
答案 1 :(得分:2)
你可以把它放在它自己的范围内,例如用{
和}
像这样:
#define PRINT_ARRAY(ary, num) \
{ \
int ai = 0; \
printf("{"); \
for(ai=0; ai < (num); ++ai) { \
printf("%d", ary[ai]); \
if(ai < (num)-1) printf(", "); \
} \
printf("}\n"); \
}
我还在num参数周围添加了parantheses,因此您可以使用复杂的表达式而不会产生奇怪的副作用。
WRT到您的标识符命名:
您可以使用宏扩展来使用参数更改名称,但由于我知道所有c预处理器中都没有计数器或循环结构,因此我认为不可能在每个用户之后自动更改标识符。另一种方法是让宏每次重新定义自己,但是这也是不可能的。
编辑:
正如已经指出的那样(感谢Aaron McDaid,也看到他提出的链接:https://stackoverflow.com/a/1067238/146041),你应该在代码周围使用do {
} while(0)
构造,这样你的宏会成为:
#define PRINT_ARRAY(ary, num) \
do { \
int ai = 0; \
printf("{"); \
for(ai=0; ai < (num); ++ai) { \
printf("%d", ary[ai]); \
if(ai < (num)-1) printf(", "); \
} \
printf("}\n"); \
} while(0)
答案 2 :(得分:2)
如果您的C符合C99,请将ai
的声明放在for
循环的标题中。您还应该使用do / while(0)
#define PRINT_ARRAY(ary, num) \
do {printf("{"); \
for(int ai=0; ai < num; ++ai) { \
printf("%d", ary[ai]); \
if(ai < num-1) printf(", "); \
} \
printf("}\n"); } while(0)
这样它就可以在控制结构之后使用而不用花括号括起来。