条件运算符中的赋值有什么问题?

时间:2017-07-27 10:33:38

标签: c compiler-errors variable-assignment conditional-operator lvalue

有错误。 在以下代码中为[i]赋值是不对的? 或条件运算符出了什么问题?

#include<stdio.h>
#include<string.h>
int main(){
  char a[12]="sumit tyagi";
  int i=0;
  while(a[i]!='\0'){ 
  a[i]>90 ? a[i]=a[i]-32 : a[i]=a[i]+32; //error in this line
  i++;
  } 
  printf("\n %s",a);

4 个答案:

答案 0 :(得分:4)

a[i]>90 ? a[i]=a[i]-32 : a[i]=a[i]+32;

评估为

a[i]>90 ? (a[i]=a[i]-32) : (a[i]=a[i]+32);

因为=的优先级低于?:。在标准C中,您不能像上面那样编写它,尽管有些编译器允许它作为扩展。

你可以把它写成更具可读性(和便携性)

a[i] += a[i] > 90 ? -32 : +32;

答案 1 :(得分:4)

这实际上是理解conditional operator的语法的问题。这在C11标准的§6.5.15中有详细说明:

  

条件表达式:
  逻辑或表达
   logical-OR-expression?表达式:条件表达式

因此,条件运算符的第三个操作数必须是条件表达式。通过标准中定义的语法跟踪条件表达式的可能性,可以发现赋值表达式不是其中一个选项。相关的语法定义可在§6.5 Expressions中找到。

通过跟随条件表达式的可能性链一直回到 primary-expression ,可以看出条件表达式可以是 logical-OR-expression ,或 logical-AND-expression ,或 inclusive-OR-expression ,或者异或表达式,或 AND表达式,或等式表达式,或关系表达式,或 shift-expression ,或 additive-expression ,或乘法表达式,或 cast-expression ,或一元表达式,或后缀表达式一级表达式 primary-expression 标识符常量字符串 - 文字(表达式) ),或泛型选择

因此,assignment-expression可能是条件表达式)不在条件表达式的可能性列表中。这就是问题中报告错误的原因:因为赋值表达式在这里不是有效语法,所以声明:

a[i]>90 ? a[i]=a[i]-32 : a[i]=a[i]+32;

被解释为:

(a[i]>90 ? a[i]=a[i]-32 : a[i]) = a[i]+32;

上述赋值表达式的左侧不是赋值表达式所需的可修改左值,因此是错误。

但请注意,表达式 形式的带括号的表达式是有效的条件表达式赋值表达式表达式。所以,这是一份法律声明:

a[i]>90 ? a[i]=a[i]-32 : (a[i]=a[i]+32);

所有这些都说,这可能不是编码的正确方法。最好使用其他答案中提出的替代方案之一,例如:

a[i] += a[i] > 90 ? -32 : 32;

答案 2 :(得分:3)

这有点棘手。有一个很好的概述“有效operator precedence in C,我会引用那里的笔记来解释你的问题*):

  

有一部分语法不能用优先级表来表示:不允许赋值表达式作为条件运算符的右手操作数,因此e = a < d ? a++ : a = d是一个无法解析的表达式,因此,无法轻易描述条件和赋值运算符的相对优先级   但是,许多C编译器使用非标准表达式语法,其中?:的优先级高于=,后者将该表达式解析为e = ( ((a < d) ? (a++) : a) = d ),然后由于语义限制而无法编译:{ {1}}永远不会是左值?:左侧需要可修改的左值

DavidBowling在标准中的发现(感谢这项工作!),上面的第二段并不完全正确,或者至少有点令人困惑。正确的是=的右手操作数不能是赋值,但中间操作数可以。因此,对于右侧,?:“优先于”?:,而不是中间部分。任何部分都可以是主要表达式,因此,对“更改优先级”进行限制会按预期工作:

=

但是,正如其他人所说的那样,无论如何这都是不必要的复杂,你可以用

来达到你想要的效果。
a[i]>90 ? a[i]=a[i]-32 : (a[i]=a[i]+32);

也更容易理解。

*)要理解此引文中的推理,您必须知道在C标准中使用 lvalue 来描述可能出现在左侧的内容 (因此名称)作业(也可以分配)。这是一个有点草率的定义,并在C标准中进一步澄清,我认为这对于这个答案的背景是足够的。

答案 3 :(得分:0)

在语句中使用=一次,因为它的优先级低于?:。类似的东西:

a[i] = a[i] > 90 ? a[i] - 32 : a[i] + 32;