“;”的目的是啥在 for 循环结束时?

Posted

技术标签:

【中文标题】“;”的目的是啥在 for 循环结束时?【英文标题】:What is the purpose of ";" at the end of for loop?“;”的目的是什么在 for 循环结束时? 【发布时间】:2015-07-02 09:16:55 【问题描述】:

我找到了以下代码:

int func_prim (int zahl) 
    int count;
    if (zahl < 0)
        return -1;

    for (count = 2; zahl % count != 0 && zahl >= count; count++);
    if (count == zahl)
        return 1;
    return 0;

功能的重点是检查一个数是否是素数。

我不明白为什么 for 循环末尾有 ;

                                                            v
for (count = 2; zahl % count != 0 && zahl >= count; count++);

否则,代码将无法正常工作。

解释是什么?

【问题讨论】:

for循环末尾有分号,因为作者是邪恶的!在这种情况下,它应该独立运行。 @sh1 或者,如果作者希望将整个循环放在一行上,可以使用 代替 ; 来记录循环有一个空主体而不是有意的包括任何后续行。 @EliahKagan,有时当我想强调循环体的空虚时,我会写for (...) continue; @coredump 但是以这种方式使用分号的两个问题是(1)它看起来像是一个错误,一些好心的开发人员可能有一天会删除; (2) 如果您没有看到它,您会认为它下面的语句将是“循环”的语句。后者特别危险,因为程序员学会了不要特别注意行尾的分号;就像人们阅读时往往不会注意到一个句子是否以句号结尾 @Marco13 为什么自动假设原作者是无知的?你讨厌这种写作,很好。但是您会发现很多人更喜欢for 循环方法:毕竟,for 结构自然地表达了初始化、停止条件和迭代。你不同意,但我相信作者知道while 循环是什么。顺便说一句,这就是为什么您需要团队中的编码约定。 【参考方案1】:

for 循环末尾的分号表示它没有主体。如果没有这个分号,C 认为 if 语句是 for 循环的主体。

【讨论】:

+int(PI/3) 没有进入“编码实践是好还是坏”的争论。 绝对是 +1,一个干净、简短的事实答案,不会尝试将代码声明为 bador 糟糕的风格。 for 循环肯定有一个主体。只是正文仅由空语句; 组成。一个单独的; 在允许声明的每个地方实际上(如果不是实际上)都是有效的,因为一个单独的; 是一个空声明(这是一个声明)。【参考方案2】:

for 循环只是为了增加count 的值。

【讨论】:

【参考方案3】:

for 循环将(通常)有一个主体,

主体用大括号括起来

但是,对于单个语句体,大括号是可选的。

; 是一个空语句。

结合以上内容,很明显for循环一直执行,直到条件变为false

【讨论】:

【参考方案4】:

for 循环之后的; 仅仅意味着for 循环除了增加计数器count 之外不会做任何事情。

【讨论】:

【参考方案5】:

for循环基本上是遍历所有小于或等于zahl但大于2的数字并将其存储在变量count中。当它遍历所有这些数字时,它正在检查zahl 是否可以被count 整除。如果zahl 可以被count 整除,则循环停止。否则,当count 等于zahl 时,循环停止。

for 循环后的 if 语句检查 count 是否等于 zahl。如果是,那么这一定意味着循环遍历了所有小于 zahl 且大于 2 的数字。这意味着 zahl 可以被所有小于自身且大于 2 的数字整除,这使得 zahl素数。

【讨论】:

【参考方案6】:

意思完全一样:

for(count = 2; zahl % count != 0 && zahl >= count; count++)


【讨论】:

这是编写空循环体的更好方法(尽管在单行上写 可能在视觉上更容易获得空循环体的线索)。如果不是遗留代码,那么没有; 空语句规则的语言会更好。 ;do ... while(...) 之后是必须的,也很愚蠢,但至少在那里我看到了一些巧妙的用法。 @MarcvanLeeuwen 我发现; 更具可读性。空块看起来像一个意外,就像程序员刚刚忘记填写正文一样。空洞的陈述清楚地表明了他的意图。 @Paulpro,我发现两者都是潜在的错误,for (...) /* empty block */ 比两者都更清楚,只要证明这是故意的。 我不是C 程序员,但是为什么这样做会有用呢? @EthanBierlein “工作”是由 ( ) 中的语句完成的;这个循环的重点是结束 count 具有基于 zahl 的特定值【参考方案7】:

for 循环有 for 关键字,后跟包含三个可选表达式的括号,用分号分隔,然后是在循环的每次迭代中执行的主体。

您的示例中 for 循环的目标是设置 count 的值,该值将在随后的 if 语句中与 zahl 进行比较。这是在分号分隔的表达式中实现的,因此循环体不需要做任何事情。

由于循环不需要做任何事情,它使用空语句作为它的主体。

如果末尾的; 被省略并且没有进行其他更改,那么for 循环之后的if 语句本身将成为for 循环的主体。 (正如您所观察到的,这不是故意的,并且会破坏程序。)

然而,让一个循环体由同一行上的单个; 组成并不是编写空循环体的唯一方法,也可能不是最明智的方法。它工作得非常好,但问题是其他读者——也许是同一个程序员,稍后返回项目——可能想知道它是否真的是一个错误。毕竟,在使用 C 风格的语言编码时,一个分号经常会在行尾输入分号,因此很容易在不属于它的地方输入一个额外的分号。

另一个问题是,在以; 为主体的单行循环是所选样式的代码中,当某人实际上时很难识别 em> 犯了一个错误,当一个不属于的时候放一个;

因此,这些替代方案可能更可取:

;,缩进,放在下一行——as sh1 suggests 将循环体写为空块 ,而不是空语句 使循环体成为continue; 语句,这只会导致循环继续进行下一次迭代(这与循环体为空时发生的情况相同)--also as sh1 suggests

【讨论】:

虽然我同意;,但我会觉得continue; 非常奇怪。在我看来,好像有人期望continue 一个外循环或其他东西。绝对是 WTF 时刻,你想在代码中避免这些。我想说 以最易读的方式捕捉到意图。 另一个选项(可以与其他选项结合使用)是插入评论:for (...) /* do nothing */ ;,以表明这是故意的。 我会添加替代方案在循环内增加变量,例如:for(count=2; zahl % count != 0 &amp;&amp; zahl &gt;= count;) ++count; @Massa - 根据定义,for 循环是计数循环;将增量器导出循环使您没有理由使用 forwhile @vaxquis 你还有初始化;无论如何我都会选择int count = 2; while( zahl % count &amp;&amp; zahl &gt;= count ) ++count; :D【参考方案8】:

除了其他优秀答案已经说过的内容之外,我想指出

for(count=2; zahl % count != 0 && zahl >= count; count++);

(即for 循环,其中包含用于递增“计数器”的空语句)等价于

count=2;
while(zahl % count != 0  && zahl >= count)

    count++;

这将使代码的目标比列出的一些替代方案更清晰:如果不存在 cmets,如在所介绍的情况下,带有空语句的循环可能会使另一个必须维护或使用代码的程序员感到困惑(就像这里的 OP 一样)。

上下文可能有助于辨别语句的真实范围,但在带有空语句的 for 循环和带有语句的 while 循环之间,后者需要较少的工作来理解其范围。

【讨论】:

次要 nitpick:这不是严格等价的,因为在第二个版本中 count 被声明在更大的范围内。 我的意思是,一般来说......这里count在两个版本的函数开头都声明了。 @coredump:考虑到这个循环的目的——在这种特殊情况下——是将count 设置为正确的值,以便可以进一步使用,count 确实必须存在于更大的范围内以使其完全起作用,因此它是完全等价的。 (不过,这仍然是对 for 循环的丑陋滥用,Federico 是对的,这是表达所涉及语义的正确方法。) @MasonWheeler 是的,我在考虑一般情况。两者在这里确实是等价的。 为什么for循环不清楚?我知道一个 for 循环明确地将初始化、条件和迭代语句逻辑捆绑在一起。从来没有必要使用 for 循环,但这种情况似乎很明智,而且写得很干净。【参考方案9】:

for循环的语法(迭代语句)是

for ( clause-1 ; expression-2 ; expression-3 ) statement 

statement 可以是 null 语句 (;)。 C11 6.8.3 说

空语句(仅由分号组成)不执行任何操作。

在第 5 段中给出了一个例子

在程序片段中

char *s;
/* ... */
while (*s++ != '\0')
    ;

使用空语句为迭代语句提供空循环体

同样的事情发生在

for (count = 2; zahl % count != 0 && zahl >= count; count++);

; 用于为for 语句提供一个空循环体。如果没有;,则for 循环旁边的语句将被视为其主体并被执行。

【讨论】:

+int(PI/3) 在没有进入“是好还是坏的编码实践”辩论的情况下保持准确。 @vaxquis;是的,因为问题是关于 “为什么 for 循环的末尾有 ;?”。这不是关于“这是否是一种好的做法?”【参考方案10】:

for Statement:

for 语句是一个循环语句,其结构允许简单 变量初始化、表达式测试和变量 修改。制作反控非常方便 循环。下面是 for 语句的一般形式:

 for (initialize; test; step)
   statement

[...]

Null Statement:

null 语句只是一个分号而已。

 ;

空语句不做任何事情。它不会在任何地方存储值。 在执行期间不会导致时间流逝 你的程序。

大多数情况下,空语句用作循环语句的主体, 或作为 for 语句中的一个或多个表达式。这是一个 使用 null 语句作为主体的 for 语句示例 循环(并且还计算 n 的整数平方根,仅用于 有趣):

 for (i = 1; i*i < n; i++)
   ;

这是另一个使用 null 语句作为主体的示例 一个 for 循环并产生输出:

 for (x = 1; x <= 5; printf ("x is now %d\n", x), x++)
   ;

空语句有时也用于跟随一个标签,该标签将 否则是块中的最后一件事。


在您的情况下,;for Statement 的Null Statement:

int func_prim (int zahl) 
  int count;
  if (zahl < 0)
    return -1;

  for (count = 2; zahl % count != 0 && zahl >= count; count++)
    ;
  if (count == zahl)
    return 1;
  return 0;

没有它,if 就变成了 for 语句:

int func_prim (int zahl) 
  int count;
  if (zahl < 0)
    return -1;

  for (count = 2; zahl % count != 0 && zahl >= count; count++)
    if (count == zahl)
      return 1;
  return 0;

因此,行为不同。

【讨论】:

很好地引用了文档。 +1【参考方案11】:

它表示for循环用于的语句。不能为空。至少它应该包含一个声明。 ;是为其完成迭代的空语句。

【讨论】:

以上是关于“;”的目的是啥在 for 循环结束时?的主要内容,如果未能解决你的问题,请参考以下文章

“回声退出|”的目的是啥在“回声退出 | sqlplus 用户/pass@ora_instance @file.sql”?

while循环结构的语法和执行顺序是啥?

beanshell中break的使用(break不再只是结束循环!)

循环结构实验报告

javascript中的for(;;)后面的括号中的符号是啥意思?

在js中怎么结束当前for循环?