三元运算符错误:当 i 除以 2 的余数为 0 时,将 arr[i] 设置为 0;否则,将 arr[i] 设置为 1。

3

关于三目运算符。我正在使用更加简洁的三目运算符重写一个C语言中的if-else语句。

以下是代码:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int arr[10];
    int i;

//    for ( i = 0; i < 10; i++ )
//    {
//        if ( i % 2 == 0 )
//        {
//            arr[i] = 0;
//        }
//
//        else arr[i] = 1;
//    }

    for ( i = 0; i < 10; i++ )
    {
         i % 2 == 0 ? arr[i] = 0 : arr[i] = 1;//Line in question
    }

    /* Just to check the result */
    for ( i = 0; i < 10; i++ )
    {
        printf ( "%d ", arr[i] );
    }

    return 0;
}

注释掉的代码确实有效,但令我惊讶的是,当我使用三元运算符编译文件时,我得到了以下错误信息:
C:\Users...\main.c|21|error: lvalue required as left operand of assignment|
这是一个简单的代码来检查数组中的位置是奇数还是偶数。搜索了一下,我唯一找到与此代码相关的内容就是lvalue是一个变量。如果这是真的,我要提到一个例子,迄今为止我还没有得到答案。
printf ( "%d", 23 + 4 );

占位符将被字面值27替换。这里没有涉及任何变量,它可以正常工作。 谢谢。

5
三目运算符并不比if-else更清晰。你出现的意外错误是对这一事实的证明。 - user1084944
2
至少在这种情况下,三元运算符并不比 if/else 语句更加简洁。它只会使代码更难阅读(而且,正如你所看到的,语法上不正确)。 - Keith Thompson
1
不要将三元运算符用作控制结构(即根据条件执行一个或多个语句);这不是它的本意。这会导致代码难以阅读,并且正如您发现的那样,存在一些优先级问题。 - John Bode
1
我认为大多数C程序员都会同意,当if/else可以完成相同的事情时,使用三元运算符只会使代码更加晦涩。如果在表达式中使用它可以是有用的,如果这意味着同一表达式的其他部分不必重复。 - Keith Thompson
1
@mxajd:请不要认真听从您老师在这一点上的建议。在一行代码中编写复杂代码可能很有趣,但结果难以阅读和维护。任何给定的代码块都会被读取多次,而且很可能会被多次修改。优化清晰度,而不是简洁度。 - Keith Thompson
显示剩余6条评论
4个回答

8

变更:

i % 2 == 0 ? arr[i] = 0 : arr[i] = 1;

转换为:

i % 2 == 0 ? (arr[i] = 0) : (arr[i] = 1);

条件运算符的优先级高于赋值运算符。

正如评论中所建议的那样,您可以通过以下方式获得相同的结果:

arr[i] = (i % 2 == 0 ? 0 : 1);

或者简单说:
arr[i] = i % 2;

或者,arr[i] = <三元运算表达式> 可能更清晰。 - juanchopanza
1
@KeithThompson 没错,那个绝对是最好的。 - juanchopanza
@ouah,你的解释对我来说不够清晰:“条件运算符比赋值运算符具有更高的优先级”。 这也是我的想法;首先评估条件,然后执行赋值。虽然我同意一些用户提出的解决方案(比我的好多了),但我记得几年前第一次看到三元运算符时,括号很重要。只是不记得是什么时候,在这种情况下为什么。 - mxajd
@mxajd的意思是,像x ? y = a : y = b这样的表达式被解析为(x ? (y = a) : y) = b而不是(x ? (y = a) : y) = b - ouah
@mxajd "首先评估条件,然后执行赋值操作" - 您将求值顺序与优先级混淆了。 - The Paramagnetic Croissant

4
你可以简单地将它改为 :)。
arr[i] = i%2;

2
或者更好的方法是使用 i & 1 来正确处理负值,尽管在原始示例代码中这并不是问题。 - doynax

1
由于运算符优先级问题,我认为您的代码被解析为:(i % 2 == 0 ? arr[i] = 0 : arr[i]) = 1;。三元运算符产生一个rvalue,在C语言中无法赋值。您应该将其更改为:i % 2 == 0 ? (arr[i] = 0) : (arr[i] = 1); 总之,这整个结构都是多余的,最好用arr[i] = i % 2;替换。

0
为什么不这样做:
for (i=0; i < 10; i+=2)  {
    arr[i]   = 0;
    arr[i+1] = 1;
}

挑战在于要在一行代码中完成所有操作。 - mxajd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接