5

我有一个枚举、一个宏定义和一个都使用枚举的方法。我无法编译它。考虑以下代码。

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 的。

4

2 回答 2

13

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

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

解决方案是确保无论值fruit是什么,值都KEY_TO_VALUE具有单一类型。例如const char *,您可以使用特殊值,例如 -1,而不是“未定义”(类型为 ,因为它是文字字符串)。

另外,请注意,它APPLE是一个值为 0ORANGE的常数,是一个值为 1BANANA的常数,是一个值为 2 的常数(这就是enum工作原理)。所以你不需要KEY_TO_VALUE,因为常量已经有了想要的值。您可以简单fruitAPPLE直接比较:

if (fruit == APPLE) { ... }
于 2012-11-10T01:44:12.990 回答
4

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

第二个和第三个操作数应满足以下条件之一:

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

在您的代码中,您将算术类型和指针类型(字符串文字衰减为char *类型)混合为?:. 这是不允许的。

非正式地说,你是怎么想到这个主意的?什么类型的东西x == BANANA ? 2 : "Undefined"int? char *? 还有什么?

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

于 2012-11-10T02:47:28.810 回答