C语言中while循环的未解释行为

5
我将尝试运行以下代码:

我正在尝试运行以下代码:

#include <sys/time.h>
#include <stdio.h>

int main()
{
unsigned int ms, oldms = 0,dif;
struct timeval tv;
while(1)
{
 gettimeofday(&tv, NULL);
 ms=tv.tv_sec; 
 //printf("%d\n",ms-oldms );
 dif=ms-oldms;
 if(dif>3)
   {    
        printf("3 seconds up");
        oldms=ms;
   }
 }
}

我希望每隔3秒就能打印出“3 seconds up”,但是并没有显示这个消息。我尝试使用gdb进行调试,但是似乎没有任何问题,也没有输出。在尝试调试时,我添加了一个printf语句,神奇的是输出可以被看到。
如果我删除//printf("%d\n",ms-oldms );语句后再运行程序,再次没有输出。我不确定发生了什么以及它是否依赖于任何东西。 $gcc --version gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

4
尝试在你的printf语句中换行。 - Jorgel
@Jorgel,在printf中加入换行符起作用了。但是,我仍然对这种行为感到困惑。这是我第一次遇到这种情况。 - kid
你的程序进入了无限循环,这是“第一次”。即使没有换行符,在printf之后添加break也可以正常工作。 - i486
stdoutprintf()写入的地方)通常是缓冲的,直到您打印换行符(或调用fflush(stdout))之前,通常不会看到任何内容。 - TripeHound
2个回答

10

输出缓冲是原因。

stdout 默认情况下与终端设备相关联时是行缓冲的。您可以使用 fflush(stdout); 将其刷新或在 printf() 中使用 \n,例如 printf("3秒到了\n");。或使用 setbuf(stdout, 0); 禁用缓冲。

总的来说,I/O 操作速度较慢。因此,实现使用固定大小的缓冲区,一旦其充满就会执行 printf。 实际上,过于频繁地调用 fflush(stdout); 可能会影响性能。


所以这个问题是关于printf的,从你的回答中我可以假设while循环或代码中发生的大量处理没有问题。 - kid
没错。循环没有问题。但我不会说它是一个“问题”。libc实现缓冲的原因是性能好。 - P.P
printf("3 seconds up\n"); 或 printf("\n3 seconds up"); 都没有起作用。即使在 printf("3 seconds up\n") 之前添加一个新的 printf("\n"),也没有帮助。如果我在代码中放置一个 printf("\n") 而不是注释掉的 printf (//printf("%d\n",ms-oldms );),那么代码就可以正常工作。 - kid
@kid,“处理量”的问题是由于你的无限循环引起的。在这个循环中没有sleep,所以得到100%的CPU负载是正常的。 - i486
@kid 只有在控制台打印时才能正常工作,如果你正在进行某种重定向,则不行。例如,如果你正在执行 ./a.out > file,那么就不行。因此,在 printf 语句之后调用 fflush(stdout); - P.P

1

发布的代码存在一些问题

  1. 在检查经过的时间之前,变量oldms没有被设置为任何特定值
  2. 如果格式字符串中没有调用fflush(stdout);或者末尾带有换行符('\n'),则不会输出任何内容(直到系统stdout缓冲区被填满)
  3. 为了可读性,将公理每行只有一个语句,每个语句最多只有一个变量声明应用于代码

以下代码可以编译并执行所需操作

#include <sys/time.h>
#include <stdio.h>

int main()
{
    unsigned int ms;
    unsigned int oldms = 0;
    unsigned int dif;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    oldms = tv.tv_sec;

    while(1)
    {
        gettimeofday(&tv, NULL);
        ms=tv.tv_sec;
        //printf("%d\n",ms-oldms );
        dif=ms-oldms;

        if(dif>3)
        {
            printf("3 seconds up\n");
            oldms=ms;
        }
    }
} // end function: main

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接