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

时间:2019-01-10 12:03:09

标签: c ternary-operator operator-precedence

编辑:

  

表达式“ 3 <8”的真实组是什么? (9 <6?7:5):2> 0?   4:1”和PHP中非关联的含义?

已作为副本提供,但涉及PHP,而不涉及C。

在为一个小程序构建一些测试用例时,我向其中引入了一个错误 for循环的条件部分,例如:

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

(我知道应该将其从for循环中删除,但这不会改变问题。)

这会导致分段错误,原因是将数组末尾作为 以上将导致无限循环。

当然,修复很容易:

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

但是我对错误实现的行为方式更感兴趣。

这是完整的代码(本身没有意义,因为它是 脱离上下文,但可以证明问题所在。

#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;
}

查看输出和(错误的)有条件的

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

似乎编译器将其解释为:

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

问题是:为什么?

此表达式:

(mode == TEST)

可以解释为<运算符的正确操作数,也可以解释为 向?运算符左操作数。 (但我想不能同时做到)。

哪些规则适用?这是运算符优先级的问题吗?序列点起作用吗? 评估的顺序是什么,为什么?

我很困惑;任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:3)

三元条件运算符的优先级较低。

所以

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

分组为

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

伙计喜欢用 operator优先级表来思考,但实际上这些分组是硬连接到语言语法中的。

答案 1 :(得分:0)

  

问题是:为什么?

     

这是运算符优先级的问题吗?

是的!

三元运算符的优先级是危险,您不是第一个犯此错误的人,我自己做了

在表达式中保持安静的最佳方法是添加()

答案 2 :(得分:0)

是的,这是一个优先级问题-关系运算符(以及按位,逻辑,算术,一元和后缀运算符)的优先级高于三元运算符,因此表达式a < b ? c : d解析为{ {1}}。

最左边的表达式是(a < b) ? c : da && ba == b等。