即使在三元运算符中给出的左值很好,赋值语句也会出错

Posted

技术标签:

【中文标题】即使在三元运算符中给出的左值很好,赋值语句也会出错【英文标题】:Error in assignment statement even when l-value given is fine in ternary operator 【发布时间】:2018-11-30 07:54:07 【问题描述】:

考虑以下 C 代码。

#include <stdio.h>

int main(void)

  int test = 0;
  int a= 10,b = 20;
  test ? a*2 : b*3;
  printf("a = %d, b = %d\n",(test ? a = 200 : b = 300),(test ? a =2 : b = 3));

  return 0;

尝试编译时会抛出以下错误。

file1.c:11:50: error: lvalue required as left operand of assignment
printf("a = %d, b = %d\n",(test ? a = 200 : b = 300),(test ? a =2 : b = 3));
                                              ^
file1.c:11:74: error: lvalue required as left operand of assignment
printf("a = %d, b = %d\n",(test ? a = 200 : b = 300),(test ? a =2 : b = 3));
                                                                      ^

我已经为赋值操作提供了一个 l 值作为左操作数,而且为什么它不会在行中抛出错误

test ? a*2 : b*3;

它只在行中产生错误

printf("a = %d, b = %d\n",(test ? a = 200 : b = 300),(test ? a =2 : b = 3));

请解释一下。

【问题讨论】:

为语句test ? a*2 : b*3result= test ? a*2 : b*3 一样提供一个变量 请提供您对问题陈述的期望。不太清楚你想要什么。 @Ac3_DeXt3R:该声明只是为了表明它没有引发任何编译错误。 Errors using ternary operator in c的可能重复 【参考方案1】:

与赋值(=)相比,三元运算符(?:)具有更高的优先级(not strict)。因此,将赋值语句放在圆括号内可以具有更高的优先级,如下所示:

#include <stdio.h>

int main(void)

  int test = 0, ret;
  int a= 10,b = 20;
  test ? a*2 : b*3;
  printf("a = %d, b = %d\n",(test ? (a = 200) : (b = 300)), (test ? (a =2) : (b = 3)));

  return 0;

严格来说,不是运算符优先级的问题,而是语言语法的问题。

根据C Operator Precedence:

C 语言标准没有指定运算符优先级。它指定了语言语法,并从中派生了优先级表以简化理解。有一部分语法不能用优先表表示:赋值表达式不允许作为条件运算符的右手操作数,所以 e = a 是一个无法解析的表达式,因此不能轻易描述条件和赋值运算符的相对优先级。

但是,许多 C 编译器使用非标准表达式语法,其中 ?: 指定的优先级高于 =,后者将该表达式解析为 e = ( ((a

【讨论】:

优先级是语法的结果。 @LightnessRacesinOrbit,是的,简而言之!【参考方案2】:

您可能缺少括号,编译器认为您的意思是:

(test ? a = 200 : b) = 300

当你真正的意思是:

test ? (a = 200) : (b = 300)

【讨论】:

原因是:赋值的优先级低于三元运算符 @StoryTeller 这个讨论正在讨论on Meta。

以上是关于即使在三元运算符中给出的左值很好,赋值语句也会出错的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 三元运算符中给出错误:只有赋值、调用、递增、递减和新对象表达式可以用作语句

在 C 中评估赋值运算符的左操作数有啥意义?

在C#三元运算符给出错误:只有赋值,调用,递增,递减和新对象表达式可用作语句

在C语言中赋值语句有啥作用?

`(i) = 1` 在标准 C 中是非法的吗?

运算符和表达式--C++复习