我有一个枚举,一个宏定义和一个都使用枚举的方法。我无法编译。请考虑以下几段代码。
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的。
答案 0 :(得分:10)
编译器正试图找出程序中每个表达式的类型。
x > 0 ? 5 : "no"
之类的表达式使编译器脱颖而出。如果x大于零,则类型为int
,但如果不是,则类型为const char *
。这是一个问题,因为没有从指针到int
的自动转换(反之亦然)。所以编译器警告它。
解决方案是确保无论fruit
的值是什么,KEY_TO_VALUE
的值都是单一类型。例如,代替“Undefined”(类型为const char *
,因为它是文字字符串),您可以使用特殊值,例如-1。
另请注意,APPLE
是一个值为0的常量,ORANGE
是一个值为1的常量,BANANA
是一个值为2的常量(这是{ {1}}有效)。因此,您不需要enum
,因为常量已经具有所需的值。您可以直接将KEY_TO_VALUE
与fruit
进行比较:
APPLE
答案 1 :(得分:3)
在C语言中,?:
运算符对其第二个和第三个操作数强加了以下要求
以下其中一项适用于第二和第三个操作数:
- 两个操作数都有算术类型;
- 两个操作数具有相同的结构或联合类型;
- 两个操作数都有void类型;
- 两个操作数都指向兼容类型的限定或非限定版本的指针;
- 一个操作数是指针,另一个是空指针常量;或
- 一个操作数是指向对象或不完整类型的指针,另一个是指向合格或非限定版本的void的指针。
在你的代码中,你将算术类型和指针类型(字符串文字衰减到char *
类型)混合为?:
的第二和第三个操作数。这是不允许的。
非正式地说,你是怎么想出这个主意的?像x == BANANA ? 2 : "Undefined"
这样的东西是什么类型的? int
? char *
?还有别的吗?
请注意,允许混合指针值和常量0
,即表达式x == APPLE ? 0 : "Undefined"
实际上会编译而没有任何问题。但是,0
将被解释为空指针常量,整个表达式将具有指针类型(char *
)并在x == APPLE
时计算为空指针是真的。这可能不是你想要的。