[英]Ternary operator in loop conditional: evaluation order / op. precedence unclear
编辑:
表达式“ 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)
可以解释为<
运算符的右操作数,还是?
的左操作数?
运营商。 (但我想不能同时使用两者。)
哪些规则适用? 这是运算符优先级的问题吗? 序列点起作用吗? 评价的顺序是什么,为什么?
我很困惑。 任何帮助是极大的赞赏。
三元条件运算符的优先级较低。
所以
row < (mode == TEST) ? NO_OF_TESTS : ROWS
分组为
(row < (mode == TEST)) ? NO_OF_TESTS : ROWS
人们喜欢根据运算符优先级表进行思考,但实际上,分组是硬连接到语言语法中的。
问题是:为什么?
这是运算符优先级的问题吗?
是的!
三元运算符的优先级非常危险 ,您不是第一个犯该错误的人,我自己做了
在表达式中保持安静的最佳方法是添加()
是的,这是一个优先级问题-关系运算符(以及按位,逻辑,算术,一元和后缀运算符)的优先级高于三元运算符,因此表达式a < b ? c : d
a < b ? c : d
被解析为(a < b) ? c : d
(a < b) ? c : d
。
如果最左边的表达式是a && b
, a == b
, a * b
等,则相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.