有错误。 在以下代码中为[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);
答案 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;