继续声明

Continue statement

提问人:user3737377 提问时间:8/19/2023 最后编辑:Jonathan Leffleruser3737377 更新时间:8/19/2023 访问量:94

问:

continue 语句用于跳过迭代,但它不能像我预期的那样工作。这是我的代码:

int i = 0;
do
{
  if(i== 10)continue;
  printf("\n This is = %d",i);
  
  i++;
} while (i<20);

我的理解是,它会跳过

这是 = 10

其余的它会打印,但它正在跳过,因为

这是 = 9 到 19

这是输出

 This is = 0
 This is = 1
 This is = 2
 This is = 3
 This is = 4
 This is = 5
 This is = 6
 This is = 7
 This is = 8

为什么?

另外,当我在这个循环之前添加for循环时,它完全被忽略并且没有被执行?

int i = 0;
do
{
  if(i== 10)continue;
  printf("\n This is = %d",i);
  
  i++;
} while (i<20);

for(int a = 0 ; a<20 ; a++)
{
    if(a==10)continue;
    printf("\nHere = %d",a);
}

输出:

 This is = 0
 This is = 1
 This is = 2
 This is = 3
 This is = 4
 This is = 5
 This is = 6
 This is = 7
 This is = 8

为什么?请解释。

c 无限循环 do-while 继续

评论

3赞 mkrieger1 8/19/2023
你怎么想象变成 11?i
3赞 Shawn 8/19/2023
当为 10 时,循环在递增之前继续,因此它始终为 10,形成无限循环。i
2赞 mkrieger1 8/19/2023
请参阅什么是调试器以及它如何帮助我诊断问题?
1赞 Some programmer dude 8/19/2023
橡皮鸭详细解释代码。
2赞 Some programmer dude 8/19/2023
今天的第二课:打印输出时,使用尾随换行符打印。该函数将写入 。在交互式终端中运行时是行缓冲的。这意味着当您打印换行符时,输出将被刷新(实际写入)。打印前导换行符时,刷新(实际写入)上一行,而不是当前文本。因此,将所有调用更改为 .printfstdoutstdoutprintf("\n anything")printf("anything\n")

答:

0赞 Vlad from Moscow 8/19/2023 #1

在这个 do-while 循环中,@When 等于i10

int i = 0;
do
{
  if(i== 10)continue;
  printf("\n This is = %d",i);
  
  i++;
} while (i<20);

然后由于 continue 语句,它看起来像

int i = 0;
do
{
  i = 10;
  if(i== 10)continue;
} while (i<20);

int i = 10;
do
{
  if(i== 10)continue;
} while (i<20);

你有一个无限循环,因为变量被更改的语句i

  i++;

被跳过。

由于您有一个无限循环,因此循环之后的代码包括 for 语句

for(int a = 0 ; a<20 ; a++)
{
    if(a==10)continue;
    printf("\nHere = %d",a);
}

没有得到控制权。

为了避免这个问题,你可以写如下

int i = 0;
do
{
  if(i== 10)
  {
      ++i;
      continue;
  }
  printf("\n This is = %d",i);
  
  i++;
} while (i<20);

或者写起来会更简单

int i = 0;
do
{
  if(i== 10)continue;
  printf("\n This is = %d",i);
  
} while ( ++i<20);

至于为什么是

this is = 9

没有打印,那么这是由于printf的调用中没有换行符

  printf("\n This is = %d",i);

尝试像这样重写它

  printf("This is = %d\n",i);

也就是说,当遇到换行符时,输出缓冲区被释放。这就是所谓的“线路缓冲”。

从 C 标准(7.21.3 文件)

当流被行缓冲时,字符应为 当换行时,作为块传输到主机环境或从主机环境传输 遇到字符。

评论

0赞 user3737377 8/19/2023
感谢您的回复,我明白了为什么是无限的,但为什么“这是 = 9”没有被打印出来?
0赞 Vlad from Moscow 8/19/2023
@user3737377 请参阅我附加的答案。
0赞 user3737377 8/19/2023
我明白了,这是与缓冲区有关的东西,我仍然需要研究,因为我的理解是它会在我指定换行字符\n时打印,编译器应该移动到下一行并打印它。
0赞 Vlad from Moscow 8/19/2023
@user3737377 在缓冲区被填充并遇到换行符之前,字符不会传输到屏幕。
0赞 user3737377 8/19/2023
但是您提到“没有打印,那么这是由于 printf 的调用中没有换行符”,但在 start 本身中我指定了 \n ?
2赞 Tom Karzes 8/19/2023 #2

这里发生了几件事。首先,格式字符串以换行符开头,但不以换行符结尾。这与通常的做法相反。但是,由于每个打印的字符串都不以换行符结尾,因此它很可能被缓冲到下一个换行符。所以事实上,它正在打印,但它实际上直到下一个换行符才真正通过,而换行符永远不会出现。printf" This is = 9"

下一个换行符永远不会出现的原因是,一旦是,它就会进入无限循环。每次通过时,它都会进行比较,这是真的,因此它会立即继续循环,从不执行增量。在后一个示例中,永远不会到达循环,因为它卡在 / 循环中。i10i == 10i++;fordowhile

为了解决第一个问题,我建议使用传统的格式字符串,例如 换行符位于末尾,通常会立即看到(至少在不重定向到文件时)。或者,您可以通过在调用后立即调用来强制刷新缓冲区。无论您的换行符在哪里,这都将起作用。printf("This is = %d\n",i);printffflush(stdout)printf

第二个问题可以通过在继续之前递增来解决,例如i

if (i == 10) {
    i++;
    continue;
}

但是编写循环的更简洁的方法是:

do {
  if (i != 10) {
      printf("This is = %d\n", i);
  }
  i++;
} while (i<20);

这通过避免 .continue

评论

0赞 user3737377 8/19/2023
感谢您的回复,我明白了为什么是无限的,但为什么“这是 = 9”没有被打印出来?
0赞 Tom Karzes 8/19/2023
@user3737377 发生了调用,但它最终卡在缓冲区中。调用 、 等时,字符将放置在缓冲区中。在某个时候,该缓冲区被写入(刷新),此时您将实际看到这些字符。通常,在写入 时,当看到换行符时会发生这种情况。当程序退出或调用时,也会发生这种情况。但在这种情况下,这些事情都没有发生(在下一条评论中继续)。"This is = 9"printfstdoutprintfputcharstdoutfflush(stdout)
0赞 Tom Karzes 8/19/2023
@user3737377 由于它卡在无限循环中,最后一个字符串被卡在缓冲区中,等待换行符。通常不会发生这种情况,因为字符串通常以换行符结尾,但由于这个字符串没有,它只是停留在缓冲区中。在那一刻,它进入了一个无限循环,没有更多的打印,所以你永远不会看到最后一个字符串。正如我所说,将缺少的尾随换行符添加到字符串中可能会修复它。在调用后调用也会修复它,即使没有换行符也是如此。fflush(stdout)printf
0赞 user3737377 8/19/2023
感谢您的回复,我没有完全了解所有事情,因为我需要深入研究缓冲区和标准输出