假设我已经定义了9个宏 ABC_1到ABC_9
如果有另一个宏XYZ(num)的目标是根据num的值调用ABC_ {i}之一,那么这样做的好方法是什么?即XYZ(num)应该调用/返回ABC_num。
答案 0 :(得分:4)
这是串联运算符##
的用途:
#define XYZ(num) ABC_ ## num
使用串联(并与运算符一起使用)的宏的参数的计算方式不同,但是(在与##
一起使用之前不会对它们进行求值,以允许名称粘贴,仅在重新扫描传递中) ,如果数字存储在第二个宏(或任何类型的扩展的结果,而不是普通的文字),你将需要另一层评估:
#define XYZ(num) XYZ_(num)
#define XYZ_(num) ABC_ ## num
在评论中,您说num
应该是变量,而不是常量。预处理器构建编译时表达式,而不是动态表达式,因此宏在这里并不是非常有用。
如果您真的希望XYZ
拥有宏定义,可以使用以下内容:
#define XYZ(num) ((int[]){ \
0, ABC_1, ABC_2, ABC_3, ABC_4, ABC_5, ABC_6, ABC_7, ABC_8, ABC_9 \
}[num])
假设ABC_{i}
被定义为int值(无论如何它们都必须是相同的类型 - 这适用于任何动态选择其中一个的方法),这将选择一个具有动态num
的方法。通过构建一个临时数组并从中进行选择。
答案 1 :(得分:2)
是的,这是可能的,使用连接。例如:
#define FOO(x, y) BAR ##x(y)
#define BAR1(y) "hello " #y
#define BAR2(y) int y()
#define BAR3(y) return y
FOO(2, main)
{
puts(FOO(1, world));
FOO(3, 0);
}
这变为:
int main()
{
puts("hello " "world");
return 0;
}