c - 循环条件中的三元运算符:评估顺序/运算。优先级不明确
问题描述
编辑:
表达式“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
人们喜欢根据运算符优先级表来思考,但实际上分组是硬连线到语言语法中的。
推荐阅读
- javascript - 电话号码和帐号的自定义格式
- python-3.x - 重新格式化以获得 Python 中的帮助。错误在体内
- r - 如何使很长的代码行在 R 中可读?
- excel - 折叠具有重复出现/名称的数据透视字段
- react-native - 如何在不失去对 ReactNative 的关注的情况下关闭键盘。(至少显示光标)
- git - GitLab CI - 尝试使用 docker buildx 为 ARM64 构建
- java - SWT GC 剪裁圆
- c# - Elasticsearch 7 和 Nest 7 - 检索结果时,我收到一个键值对列表或空对象列表
- ios - 是否可以将 UITests 目标中的文件复制到应用程序的文档目录中?
- python - 根据python数据框中的特定条件减去特定列的行值