【发布时间】:2021-11-17 14:52:51
【问题描述】:
假设我定义了以下宏:
#define TEST0 100
#define TEST1 101
...
#define TEST9 109
假设我有一个 int 表示这样一个宏的索引:
int idx=3;
如果 idx 等于 3,有没有办法访问 TEST3?
这段代码可以正常工作,因为我在这里传递了一个编译时已知的值:
#define TEST(id) (TEST##id)
printf("Retrieved value: %d\n",TEST(3));
但我还没有找到一种方法来对变量做同样的事情,即:
printf("Retrieved value: %d\n",TEST(i));
添加间接级别
#define STR_INDIR(x) #x
#define STR(x) STR_INDIR(x)
这里也没有帮助,因为此评估发生在编译时。
一种可能性是使用 switch 语句创建一个 C 函数:
int test(int x) {
switch(x) {
case 0: return TEST0;break;
case 1: return TEST1;break;
...
case 9: return TEST9;break;
}
}
但这并不能很好地扩展......
【问题讨论】:
-
#define TEST(id) (100+(id))怎么样? -
您已经注意到为什么这是不可能的:宏名称只存在于预处理器中,在运行时不存在。在几乎所有你认为你想要一个编号的变量序列的情况下,能够通过数字访问它们,那么你想要的通常是一个数组:
const int test[] = { [0] = 100, [1] = 101, ... }; -
这里最好的可能是根本不使用宏。
-
如果你使用 GCC,那么它有一个语言的扩展,带有一个特殊的
__COUNTER__宏,它被增加以在单个翻译单元中非常有用。请参阅the GCC online documentation 了解更多信息。 -
关于不使用宏或将 TEST(id) 重新定义为 100+(id) 的建议,问题是我不控制定义这些宏的文件,并且它们的值并非微不足道作为一个简单的增量 100,这只是一个例子。