1

我有

#define ADD 5
#define SUB 6

给定它们的值 5 和 6,我可以打印 ADD 和 SUB 吗?

4

4 回答 4

4

不。

defined 符号的名称被预处理器删除,因此编译器永远不会看到它们。

如果这些名称在运行时很重要,那么它们需要以比预处理器符号名称更持久的方式编码。也许是一个带有字符串和整数的表:

#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;
}
于 2012-09-20T08:46:17.040 回答
2

你可以做类似的事情

printf("%d", ADD);

它会打印 5

关于定义,您必须记住的是:
定义在编译之前由预处理器替换到源代码中,因此代码中的所有 ADD 实例都替换为 5。在预处理器之后,printf 如下所示:

printf("%d", 5); 

所以回答你的问题:
不,你不能那样做。

于 2012-09-20T08:46:56.417 回答
0

使用现代 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)在编译时扩展调用。

于 2012-09-20T11:42:32.313 回答
0

是的,但不是通过某种反向查找机制,其中值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);
}
于 2012-09-20T08:49:56.417 回答