首页 > 解决方案 > 循环条件中的三元运算符:评估顺序/运算。优先级不明确

问题描述

编辑:

表达式“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)

可以被解释为运算符的右操作数<,或运算符的左操作数?。(但我猜不是同时两者。)

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

我很困惑;任何帮助是极大的赞赏。

标签: cternary-operatoroperator-precedence

解决方案


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

所以

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

被分组为

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

人们喜欢根据运算符优先级表来思考,但实际上分组是硬连线到语言语法中的。


推荐阅读