我有
#define ADD 5
#define SUB 6
给定它们的值 5 和 6,我可以打印 ADD 和 SUB 吗?
不。
define
d 符号的名称被预处理器删除,因此编译器永远不会看到它们。
如果这些名称在运行时很重要,那么它们需要以比预处理器符号名称更持久的方式编码。也许是一个带有字符串和整数的表:
#define DEFINE_OP(n) { #n, n }
static const struct {
const char *name;
int value;
} operators[] = {
DEFINE_OP(ADD),
DEFINE_OP(SUB),
};
这使用字符串化预处理器运算符#
来避免重复。
有了上面的内容,您可以轻松编写查找代码:
const char * op_to_name(int op)
{
size_t i;
for(i = 0; i < sizeof operators / sizeof *operators; ++i)
if(operators[i].value == op)
return operators[i].name;
return NULL;
}
你可以做类似的事情
printf("%d", ADD);
它会打印 5
关于定义,您必须记住的是:
定义在编译之前由预处理器替换到源代码中,因此代码中的所有 ADD 实例都替换为 5。在预处理器之后,printf 如下所示:
printf("%d", 5);
所以回答你的问题:
不,你不能那样做。
使用现代 C,自 C99 以来,这甚至比使用指定初始化程序和复合文字的 unwind 答案简单得多
#define DEFINE_OP(n) [n] = #n
#define OPNAMES ((char const*const opNames[]){ \
DEFINE_OPT(ADD), \
DEFINE_OPT(SUB), \
})
inline
char const* getOp(unsigned op) {
size_t const maxOp = sizeof OPNAMES/ sizeof *OPNAMES;
if (op >= maxOp || !OPNAMES[op]) return "<unknown operator>";
else return OPNAMES[op];
}
任何现代编译器都应该能够getOp(ADD)
在编译时扩展调用。
是的,但不是通过某种反向查找机制,其中值5
对于 string 具有某种象征意义"ADD"
。通过 a 定义的符号#define
在结构上被预处理器替换。但是,您可以保持简单:
const char *get_name(int value) {
switch(value) {
case ADD:
return "ADD";
case SUB:
return "SUB";
default:
return "WHATEVER";
}
}
#include <stdio.h>
int main() {
printf("%s = %d\n", get_name(ADD), ADD);
printf("%s = %d", get_name(SUB), SUB);
}