条件运算符中的这个赋值有什么问题?
What is wrong with this assignment in a conditional operator?
出现错误。
下面代码中给a[i]赋值是不是错了?
或者条件运算符有问题?
#include<stdio.h>
#include<string.h>
int main(){
char a[12]="sumit tyagi";
int i=0;
while(a[i]!='[=10=]'){
a[i]>90 ? a[i]=a[i]-32 : a[i]=a[i]+32; //error in this line
i++;
}
printf("\n %s",a);
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;
这有点棘手。 “effective”operator precedence in C 有一个很好的概述,我将引用那里的注释来解释您的问题 *):
There is a part of the grammar that cannot be represented by a precedence table: an assignment-expression is not allowed as the right hand operand of a conditional operator, so e = a < d ? a++ : a = d
is an expression that cannot be parsed, and therefore relative precedence of conditional and assignment operators cannot be described easily.
However, many C compilers use non-standard expression grammar where ?:
is designated higher precedence than =
, which parses that expression as e = ( ((a < d) ? (a++) : a) = d )
, which then fails to compile due to semantic constraints: ?:
is never lvalue and =
requires a modifiable lvalue on the left.
根据 DavidBowling 在标准中的发现(感谢这项工作!),上面的第二段并不完全正确,或者至少有点令人困惑。 ?:
的右边操作数不能是赋值是正确的,但中间操作数可以。所以对于右侧,?:
"takes precedence" 在 =
之上,而对于中间部分则不是。任何部分都可以是 主表达式 ,因此对 "change precedence" 的泛化按预期工作:
a[i]>90 ? a[i]=a[i]-32 : (a[i]=a[i]+32);
但是,正如其他人所说,无论如何这都是不必要的复杂,您只需
就可以实现您想要的
a[i] += a[i]>90 ? -32 : 32;
这样也比较容易理解
*) 要理解此引用中的推理,您必须知道 lvalue 在 C 标准中用于描述可能出现在 上的内容左侧(因此得名)赋值(又名可以分配给)。这是一个有点草率的定义,并在 C 标准中进一步阐明,我认为这对于这个答案的上下文已经足够了。
在您的语句中使用一次 =
,因为它的优先级低于 ?:
。类似于:
a[i] = a[i] > 90 ? a[i] - 32 : a[i] + 32;
这确实是理解 conditional operator 语法的问题。这在 C11 标准的 §6.5.15 中有详细说明:
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
因此,条件运算符的第三个操作数必须是条件表达式。通过标准中定义的语法跟踪条件表达式的可能性,发现赋值表达式不是选项之一。相关语法定义见§6.5 Expressions.
沿着从条件表达式一直回到主要表达式的可能性链,可以看出条件表达式可以是逻辑或表达式,或逻辑与表达式,或包含或表达式,或异或表达式,或与表达式,或等式表达式,或关系表达式,或移位表达式,或加法表达式,或乘法表达式,或强制转换表达式,或一元表达式,或后缀表达式,或主表达式。 主表达式是一个标识符,一个常量,一个字符串文字、( 表达式 ) 或 通用选择 .
因此,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;
上述赋值表达式的左侧不是赋值表达式所需的可修改左值,因此会出现错误。
但是,请注意 ( expression ) 形式的括号表达式是 有效的条件表达式,而赋值表达式是一个表达式。所以,这是一个合法的声明:
a[i]>90 ? a[i]=a[i]-32 : (a[i]=a[i]+32);
综上所述,这可能不是正确的编码方式。最好使用其他答案中提出的替代方案之一,例如:
a[i] += a[i] > 90 ? -32 : 32;
出现错误。 下面代码中给a[i]赋值是不是错了? 或者条件运算符有问题?
#include<stdio.h>
#include<string.h>
int main(){
char a[12]="sumit tyagi";
int i=0;
while(a[i]!='[=10=]'){
a[i]>90 ? a[i]=a[i]-32 : a[i]=a[i]+32; //error in this line
i++;
}
printf("\n %s",a);
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;
这有点棘手。 “effective”operator precedence in C 有一个很好的概述,我将引用那里的注释来解释您的问题 *):
There is a part of the grammar that cannot be represented by a precedence table: an assignment-expression is not allowed as the right hand operand of a conditional operator, so
e = a < d ? a++ : a = d
is an expression that cannot be parsed, and therefore relative precedence of conditional and assignment operators cannot be described easily.
However, many C compilers use non-standard expression grammar where?:
is designated higher precedence than=
, which parses that expression ase = ( ((a < d) ? (a++) : a) = d )
, which then fails to compile due to semantic constraints:?:
is never lvalue and=
requires a modifiable lvalue on the left.
根据 DavidBowling 在标准中的发现(感谢这项工作!),上面的第二段并不完全正确,或者至少有点令人困惑。 ?:
的右边操作数不能是赋值是正确的,但中间操作数可以。所以对于右侧,?:
"takes precedence" 在 =
之上,而对于中间部分则不是。任何部分都可以是 主表达式 ,因此对 "change precedence" 的泛化按预期工作:
a[i]>90 ? a[i]=a[i]-32 : (a[i]=a[i]+32);
但是,正如其他人所说,无论如何这都是不必要的复杂,您只需
就可以实现您想要的a[i] += a[i]>90 ? -32 : 32;
这样也比较容易理解
*) 要理解此引用中的推理,您必须知道 lvalue 在 C 标准中用于描述可能出现在 上的内容左侧(因此得名)赋值(又名可以分配给)。这是一个有点草率的定义,并在 C 标准中进一步阐明,我认为这对于这个答案的上下文已经足够了。
在您的语句中使用一次 =
,因为它的优先级低于 ?:
。类似于:
a[i] = a[i] > 90 ? a[i] - 32 : a[i] + 32;
这确实是理解 conditional operator 语法的问题。这在 C11 标准的 §6.5.15 中有详细说明:
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
因此,条件运算符的第三个操作数必须是条件表达式。通过标准中定义的语法跟踪条件表达式的可能性,发现赋值表达式不是选项之一。相关语法定义见§6.5 Expressions.
沿着从条件表达式一直回到主要表达式的可能性链,可以看出条件表达式可以是逻辑或表达式,或逻辑与表达式,或包含或表达式,或异或表达式,或与表达式,或等式表达式,或关系表达式,或移位表达式,或加法表达式,或乘法表达式,或强制转换表达式,或一元表达式,或后缀表达式,或主表达式。 主表达式是一个标识符,一个常量,一个字符串文字、( 表达式 ) 或 通用选择 .
因此,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;
上述赋值表达式的左侧不是赋值表达式所需的可修改左值,因此会出现错误。
但是,请注意 ( expression ) 形式的括号表达式是 有效的条件表达式,而赋值表达式是一个表达式。所以,这是一个合法的声明:
a[i]>90 ? a[i]=a[i]-32 : (a[i]=a[i]+32);
综上所述,这可能不是正确的编码方式。最好使用其他答案中提出的替代方案之一,例如:
a[i] += a[i] > 90 ? -32 : 32;