简体   繁体   English

循环条件中的三元运算符:评估顺序/操作。 优先顺序不清楚

[英]Ternary operator in loop conditional: evaluation order / op. precedence unclear

Edit: 编辑:

What is the real groups of the expression “3<8 ? 表达式“ 3 <8”的真实组是什么? (9<6 ? 7 : 5) : 2>0 ? (9 <6?7:5):2> 0? 4 : 1” and the meaning of non-associative in PHP? 4:1”和PHP中非关联的含义?

has been offered as a duplicate, but that concerns PHP, not C. 已作为副本提供,但涉及PHP,而不涉及C。

While building some test cases for a small program, I introduced a bug into the conditional part of a for loop, like this: 在为小型程序构建一些测试用例时,我在for循环的条件部分中引入了一个错误,如下所示:

for(int row = 0; row < (mode == TEST) ? NO_OF_TESTS : ROWS; row++){}

(I know one should pull that out of the for loop, but that does not change the problem.) (我知道应该将其拉出for循环,但这不会改变问题。)

This lead to a segmentation fault by overrunning the end of an array as the above results in an infinite loop. 这会导致越过数组末端而导致分段错误,因为上述情况会导致无限循环。

Of course, the fix was easy enough: 当然,修复很容易:

for(row = 0; row < ((mode == TEST) ? NO_OF_TESTS : ROWS); row++)
//                 ^                                   ^

But I am more interested in the way the faulty implementation behaved. 但是我对错误实现的行为方式更感兴趣。

Here is a complete piece of code (does not make sense in itself, as it is ripped out of context, but it demonstrates the problem). 这是一段完整的代码(本身没有任何意义,因为它脱离了上下文,但可以证明问题所在)。

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

#define TEST 0
#define INTERACTIVE 1

#define ROWS 2
#define NO_OF_TESTS 3
#define MAX_FRUIT_LEN 50

int main(void)
{
    char test_cases[NO_OF_TESTS][MAX_FRUIT_LEN] =
    {{"Orange"},
     {"Apple"},
     {"Pineapple"}};

    int mode = TEST;
    int row = 0;

    //This fails - but in a strange way
    //Uncomment this `for` loop and comment the other one to see the effects

    //for(int row = 0; row < (mode == TEST) ? NO_OF_TESTS : ROWS; row++)

    //With the parantheses, obviously, it works.
    for(row = 0; row < ((mode == TEST) ? NO_OF_TESTS : ROWS); row++)
    {
        printf("Working:\tIn row %d: Mode: %d condition_eval: %d\n"
        , row , mode, row < ((mode == TEST) ? NO_OF_TESTS : ROWS));

        printf("Not Working:\tIn row %d: Mode: %d condition_eval: %d\n"
        , row, mode, row < (mode == TEST) ? NO_OF_TESTS : ROWS);

        printf("Row: %d \tFruit Name: %s\n",row, test_cases[row]);
    }
    printf("\nTerminating conditional evaluation (at row %d):\n", row);

    printf("Working:\tIn row %d: Mode: %d condition_eval: %d\n"
    , row , mode, row < ((mode == TEST) ? NO_OF_TESTS : ROWS));

    printf("Not Working:\tIn row %d: Mode: %d condition_eval: %d\n"
    , row, mode, row < (mode == TEST) ? NO_OF_TESTS : ROWS);

    return 0;
}

Looking at the output and the (wrong) conditional 查看输出和(错误的)条件

row < (mode == TEST) ? NO_OF_TESTS : ROWS

it appears that the compiler interprets this as: 似乎编译器将其解释为:

   (row < (mode == TEST)) ? NO_OF_TESTS : ROWS
// ^                    ^

The question is: Why? 问题是:为什么?

This expression: 该表达式:

(mode == TEST)

could be interpreted as either being the right operand to the < operator, or as the left operand to the ? 可以解释为<运算符的右操作数,还是?的左操作数? operator. 运营商。 (But not both at the same time, I guess.) (但我想不能同时使用两者。)

Which rules apply? 哪些规则适用? Is it a matter of operator precedence? 这是运算符优先级的问题吗? Do sequence points play a role? 序列点起作用吗? What is the order of evaluation, and why? 评价的顺序是什么,为什么?

I'm quite confused; 我很困惑。 any help is greatly appreciated. 任何帮助是极大的赞赏。

The ternary conditional operator has a low precedence. 三元条件运算符的优先级较低。

So 所以

row < (mode == TEST) ? NO_OF_TESTS : ROWS

is grouped as 分组为

(row < (mode == TEST)) ? NO_OF_TESTS : ROWS

Folk like to think in terms of operator precedence tables , but really the groupings are hardwired into the language grammar. 人们喜欢根据运算符优先级表进行思考,但实际上,分组是硬连接到语言语法中的。

The question is: Why? 问题是:为什么?

Is it a matter of operator precedence ? 这是运算符优先级的问题吗?

yes ! 是的!

The precedence of the ternary operator is quite dangerous , you are not the first doing that error, I did myself 三元运算符的优先级非常危险 ,您不是第一个犯该错误的人,我自己做了

The best way to be quiet in expressions is to add the () 在表达式中保持安静的最佳方法是添加()

Yes, it is a matter of precedence - relational operators (as well as bitwise, logical, arithmetic, unary, and postfix operators) have higher precedence than the ternary operator, so the expression a < b ? c : d 是的,这是一个优先级问题-关系运算符(以及按位,逻辑,算术,一元和后缀运算符)的优先级高于三元运算符,因此表达式a < b ? c : d a < b ? c : d is parsed as (a < b) ? c : d a < b ? c : d被解析为(a < b) ? c : d (a < b) ? c : d . (a < b) ? c : d

Same if the leftmost expression is a && b , a == b , a * b , etc. 如果最左边的表达式是a && ba == ba * b等,则相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM