在C中重命名宏

时间:2014-10-22 22:39:30

标签: c macros rename

假设我已经定义了9个宏 ABC_1到ABC_9

如果有另一个宏XYZ(num)的目标是根据num的值调用ABC_ {i}之一,那么这样做的好方法是什么?即XYZ(num)应该调用/返回ABC_num。

2 个答案:

答案 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;
}