我在C中有一段代码,如下所示:
main()
{
int a=10, b;
a>=5 ? b=100 : b=200 ;
printf("%d" , b);
}
在unix中运行gcc编译器上的代码会生成编译时错误 '左值作为赋值的左操作数'并将错误指向b = 200,而在使用Turbo C编译的窗口中,将200作为输出。
有人可以解释一下这种情况究竟发生了什么吗?
答案 0 :(得分:14)
在C中,三元运算符定义为
逻辑-OR-表达?表达式:条件表达式
其中 条件表达式 的定义类似于
logical-OR-expression
赋值运算符的优先级低于OR运算符。因此你必须写
a >= 5 ? b = 100 : ( b = 200 );
否则编译器会考虑像
这样的表达式( a >= 5 ? b = 100 : b ) = 200;
由于C中的三元运算符不是左值,因此上述表达式无效,编译器发出错误。
来自C标准:
结果是第二个或第三个操作数的值(以较大者为准) 被评估),转换为下面描述的类型
和脚注:
110)条件表达式不会产生左值。
考虑到C和C ++中的运算符定义之间存在本质区别。在C ++中,它被定义为
逻辑或表达?表达式:赋值表达式
在C ++中,相同的GCC成功编译代码
#include <iostream>
int main()
{
int a = 10, b;
a >= 5 ? b = 100 : b = 200;
std::cout << "b = " << b << std::endl;
return 0;
}
答案 1 :(得分:2)
你可以把它放在括号里让它工作..比如
(a>=5)?(b=100):(b=200);
并请为您的函数main()
答案 2 :(得分:1)
此错误是由条件表达式
的语法引起的logical-OR-expression ? expression : conditional-expression
因此,:
之后的部分必须能够解析b = 200
。但是,conditional-expression
无法解析它,因为赋值表达式的优先级较低 - 您需要在赋值表达式周围加上一个括号
a>=5 ? b=100 : (b=200);
但是你需要一个括号的事实 not 意味着表达式否则被解析为(a>=5 ? b=100 : b) = 200
,它只是一个编译器的内部人工制品,它在错误信息中谈到赋值的左操作数。 C语言对赋值表达式语法具有以下两个规则,并且应用匹配的规则
conditional_expression
unary_expression '=' assignment_expression
这会干扰递归下降解析器,它只会调用parseConditionalExpression
,并检查后面的令牌。因此,一些C语法分析器实现选择不在此处给出语法错误,但是解析它就好像上面的语法说conditional_expression '=' ...
,稍后在检查解析树时,验证左侧是左值。例如,Clang源代码说
/// Note: we diverge from the C99 grammar when parsing the assignment-expression
/// production. C99 specifies that the LHS of an assignment operator should be
/// parsed as a unary-expression, but consistency dictates that it be a
/// conditional-expession. In practice, the important thing here is that the
/// LHS of an assignment has to be an l-value, which productions between
/// unary-expression and conditional-expression don't produce. Because we want
/// consistency, we parse the LHS as a conditional-expression, then check for
/// l-value-ness in semantic analysis stages.
GCC解析器的源代码说
/* ...
In GNU C we accept any conditional expression on the LHS and
diagnose the invalid lvalue rather than producing a syntax
error. */
答案 3 :(得分:0)
在这种情况下,括号应在条件周围。
(a>=5) ? b=100 : b=200;
应该正确编译
RE: K&R The C Programming Language (2nd):
条件表达式的第一个表达式周围不需要括号,因为?:
的优先级非常低,刚好高于赋值。 (强调我的)无论如何还是建议的,因为它们使表达式的条件部分更易于查看。
答案 4 :(得分:-7)
试试这个!因为三元运算符返回值,所以必须将其赋值给b
!
#include <stdio.h>
main() {
int a = 10, b;
b = a >= 5 ? 100 : 200;
printf("%d" , b);
}