c中使用三元运算符的错误

时间:2014-10-19 08:08:07

标签: c gcc turbo-c

我在C中有一段代码,如下所示:

main()
{
    int a=10, b;
    a>=5 ? b=100 : b=200 ;
    printf("%d" , b);
}

在unix中运行gcc编译器上的代码会生成编译时错误 '左值作为赋值的左操作数'并将错误指向b = 200,而在使用Turbo C编译的窗口中,将200作为输出。

有人可以解释一下这种情况究竟发生了什么吗?

5 个答案:

答案 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);

}