逗号分隔的表达式作为 for 循环中的条件如何工作?
Posted
技术标签:
【中文标题】逗号分隔的表达式作为 for 循环中的条件如何工作?【英文标题】:How do Comma-separated expressions as condition in a for-loop work? 【发布时间】:2020-04-23 22:41:21 【问题描述】:我已经在 Stack Overflow 上的答案和问题中看到过几次,这是一个以逗号分隔的列表作为 for 循环的循环条件,例如:for(int i = 0, int j = 0 ; i < 2, j < 4; i++, j++) ...
.这是如何工作的?
逗号分隔的条件如何在 C 中的 for 循环中工作?
喜欢:
for(int i = 0, int j = 1 ; i < 5, j < 4; i++, j++) ...
这不是因为条件需要是一个评估表达式而无效吗?多个逗号分隔的表达式如何在 for 循环中计算为一个表达式?
上述表达式用分号; i < 5, j < 4;
括起来,这就是循环的条件。还是我错了?
【问题讨论】:
【参考方案1】:带有声明的for
循环的语法是(6.8.5):
for ( declaration expression_opt ; expression_opt ) statement
这个
for(int i = 0, int j = 1 ; i < 5, j < 4; i++, j++)
不解析是因为
int i = 0, int j = 1 ;
在语法上作为声明(或 C 中的任何句子形式)在语法上无效,但
for(int i = 0, j = 1; i < 5, j < 4; i++, j++)
会解析,因为
int i = 0, j = 1;
是一个有效的声明(具有多个包含初始化器的声明器)并且
i < 5, j < 4
是一个有效的包含逗号运算符的表达式,原样
i++, j++
.
(注意i < 5, j < 4
与j < 4
具有相同的效果,因为逗号表达式是从左到右计算的,并且使用最后一部分的值,并且由于i < 5
在这里没有副作用,所以整个表达式等同于j < 4
。您可能想要i < 5 && j < 4
。)
在 for
循环的原始形式(没有声明)中,你有 (6.8.5)
for ( expression_opt ; expression_opt ; expression_opt ) statement
分号用于分隔 3 个(可选)表达式。
在包含声明的表单中,第一个分号被解析为声明的一部分
for ( declaration expression_opt ; expression_opt ) statement
。
【讨论】:
@RobertS-ReinstateMonica 逗号表达式从左到右求值,并使用最后一部分的值(该部分在技术上是一个赋值表达式)。由于i<5, j<4
中的i < 5
没有副作用,并且它的值被丢弃(仅使用最终部分的值),因此可以对其进行优化。我现在已经把它放在答案中了。
@RobertS-ReinstateMonica 在i++, j++
中对于最终表达式,最终值是无关紧要的。你不能删除第一部分,因为它有副作用,而副作用才是最重要的,因为for
中最后一个表达式的值无论如何都会被丢弃。
@RobertS-ReinstateMonica i puts("hello"),puts("world"),puts("!") 将按顺序运行 puts。 extern int x; if ((x,x,x,x,x,x)) foo();
只会获取一次x
,因为除了最后一个之外,每个x
的值都被丢弃了。
@RobertS-ReinstateMonica 它们是一个 hack,您可以使用它来绕过语法限制,例如 for
的最后一部分是一个表达式。如果要指定在迭代后完成多项操作,则不能使用 i++; j++;
之类的多个语句,因为 for 的更改部分需要是表达式,但您可以使用 i++, j++
,因为它的作用相同同时限定为表达式。
@RobertS-ReinstateMonica 在 for 的控制表达式中,除非您尝试测试 C 解析器或类似的东西,否则它是无用的并且是错误的。【参考方案2】:
以逗号分隔的列表中的所有表达式都被计算,但只有最后一个表达式用于 for 循环条件。所以实际上 i
【讨论】:
以上是关于逗号分隔的表达式作为 for 循环中的条件如何工作?的主要内容,如果未能解决你的问题,请参考以下文章