是什么导致“警告:条件表达式中的指针/整数类型不匹配”?

我有一个枚举,一个宏定义和一个所有使用枚举的方法。 我无法编译。 请考虑以下代码段。

typedef enum fruits_t { APPLE, ORANGE, BANANA } fruits_t; #define KEY_TO_VALUE(x) ((x == APPLE) ? 0 : \ (x == ORANGE) ? 1 : \ (x == BANANA) ? 2 : \ "Undefined") static void foo(char fruit) { if (fruit == KEY_TO_VALUE(APPLE)) { /* do something */ } } 

编译,但我得到以下警告。

warning: pointer/integer type mismatch in conditional expression

warning: comparison between pointer and integer

为什么? 我是C的新手,所以如果你能解释一些对经验丰富的C开发人员来说显而易见的事情,我会很感激。 我的大多数编程知识都是基于Java的。

编译器试图找出程序中每个表达式的类型。

表达式如x > 0 ? 5 : "no" x > 0 ? 5 : "no"使编译器抓住它的头。 如果x大于零,则类型为int ,但如果不是,则类型为const char * 。 这是一个问题,因为没有从指针到int自动转换(反之亦然)。 所以编译器警告它。

解决方案是确保无论fruit的价值是什么, KEY_TO_VALUE的值都是单一类型。 例如,代替“Undefined”(类型为const char * ,因为它是文字字符串),您可以使用特殊值,例如-1。

另请注意, APPLE是值为0的常量, ORANGE是值为1的常量, BANANA是值为2的常量(这是enum工作原理)。 所以你不需要KEY_TO_VALUE ,因为常量已经有了所需的值。 您可以直接将fruitAPPLE进行比较:

 if (fruit == APPLE) { ... } 

在C语言中, ?:运算符对其第二个和第三个操作数强加了以下要求

下列之一应适用于第二和第三个操作数:

  • 两个操作数都有算术类型;
  • 两个操作数具有相同的结构或联合类型;
  • 两个操作数都有空白类型;
  • 两个操作数都是指向兼容类型的限定或非限定版本的指针;
  • 一个操作数是指针,另一个是空指针常量; 要么
  • 一个操作数是指向对象或不完整类型的指针,另一个是指向void的限定或非限定版本的指针。

在你的代码中,你将算术类型和指针类型(字符串文字衰减到char *类型)混合为?:第二和第三个操作数。 这是不允许的。

非正式地说,你是怎么想出这个想法的? x == BANANA ? 2 : "Undefined"之类的东西是x == BANANA ? 2 : "Undefined" x == BANANA ? 2 : "Undefined"intchar * ? 别的什么?

注意,允许混合指针值和常量0 ,即表达式x == APPLE ? 0 : "Undefined" x == APPLE ? 0 : "Undefined"实际上会编译没有任何问题。 但是, 0将被解释为空指针常量 ,整个表达式将具有指针类型( char * )并在x == APPLE为true时计算为空指针。 这可能不是你想要的。