逗号分隔的表达式作为 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 &lt; 5, j &lt; 4j &lt; 4具有相同的效果,因为逗号表达式是从左到右计算的,并且使用最后一部分的值,并且由于i &lt; 5在这里没有副作用,所以整个表达式等同于j &lt; 4。您可能想要i &lt; 5 &amp;&amp; j &lt; 4。)

for 循环的原始形式(没有声明)中,你有 (6.8.5)

 for ( expression_opt ; expression_opt ; expression_opt ) statement

分号用于分隔 3 个(可选)表达式。

在包含声明的表单中,第一个分号被解析为声明的一部分

for ( declaration expression_opt ; expression_opt ) statement

【讨论】:

@RobertS-ReinstateMonica 逗号表达式从左到右求值,并使用最后一部分的值(该部分在技术上是一个赋值表达式)。由于i&lt;5, j&lt;4 中的i &lt; 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 循环中的条件如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

JS中循环嵌套六大经典例题+六大图形题,你知道哪几个?

20 循环控制

for循环的初始化和增量部分中的逗号如何工作?

FOR循环中的逗号运算符,它是如何工作的?

循环通过逗号分隔的 shell 变量

00012_循环语句for