在gcc中使用嵌套循环时printf不工作

在gcc中使用嵌套循环时printf不工作,c,linux,gcc,printf,C,Linux,Gcc,Printf,在使用C和gcc进行一个项目时,我遇到了一些我无法理解的非常奇怪的事情。下面的代码应该至少打印一次i的值,但出于某种原因,在Linux和gcc(也是g++)上,它没有打印,只是挂起而不输出任何内容。注意printf确实在其他场景中工作 #include <stdio.h> int main() { int i; int j; int z; for (i = 0; i < 47966; i++) { printf("%d ", i

在使用C和gcc进行一个项目时,我遇到了一些我无法理解的非常奇怪的事情。下面的代码应该至少打印一次i的值,但出于某种原因,在Linux和gcc(也是g++)上,它没有打印,只是挂起而不输出任何内容。注意printf确实在其他场景中工作

#include <stdio.h>

int main() {
    int i;
    int j;
    int z;
    for (i = 0; i < 47966; i++) {
        printf("%d ", i);
        for (j = 0; j < 47966; j++) {
            for (z = 0; z < 47966; z++) {
            }
        }
    }
    return 0;
}
#包括
int main(){
int i;
int j;
intz;
对于(i=0;i<47966;i++){
printf(“%d”,i);
对于(j=0;j<47966;j++){
对于(z=0;z<47966;z++){
}
}
}
返回0;
}
有人遇到过这种情况吗?为什么会发生这种情况?

你很有可能

在大多数情况下,以大数据块的形式写入设备比以大量小数据块的形式写入设备更有效。写入文件句柄时,
printf
正在写入
stdout
,通常在发送到实际设备之前保存在内存缓冲区中。该缓冲区必须“刷新”,这意味着缓冲区的内容将写入设备。缓冲有三种类型:无缓冲、块缓冲和行缓冲

stderr
通常是无缓冲的,对
stderr
的每次写入都会立即发送到设备。这很好,因为您希望立即查看错误信息

文件通常是块缓冲的。写入操作存储在的内存缓冲区中,并在到达缓冲区或显式关闭文件句柄或进程终止时刷新

stdout
行缓冲的意味着它有一个缓冲区,但当它看到换行符或从
stdin
读取某些内容时会自动刷新。这是可用性和性能之间的折衷,通常您希望一次或在提示输入时显示整行

您的程序从不输出换行符,因此您的数字将保留在行缓冲区中,直到缓冲区已满或进程终止。由于打印单个整数需要2300737156次迭代,因此在填充缓冲区之前需要一段时间。和110357158424696次迭代,然后程序终止并自动刷新和关闭
stdout
。虽然如果你用优化编译它,编译器会识别出内部循环,什么也不做,并消除它们;然后您的代码将很快执行和打印

您可以在打印后立即手动刷新缓冲区来解决此问题。

您很可能会这样做

在大多数情况下,以大数据块的形式写入设备比以大量小数据块的形式写入设备更有效。写入文件句柄时,
printf
正在写入
stdout
,通常在发送到实际设备之前保存在内存缓冲区中。该缓冲区必须“刷新”,这意味着缓冲区的内容将写入设备。缓冲有三种类型:无缓冲、块缓冲和行缓冲

stderr
通常是无缓冲的,对
stderr
的每次写入都会立即发送到设备。这很好,因为您希望立即查看错误信息

文件通常是块缓冲的。写入操作存储在的内存缓冲区中,并在到达缓冲区或显式关闭文件句柄或进程终止时刷新

stdout
行缓冲的意味着它有一个缓冲区,但当它看到换行符或从
stdin
读取某些内容时会自动刷新。这是可用性和性能之间的折衷,通常您希望一次或在提示输入时显示整行

您的程序从不输出换行符,因此您的数字将保留在行缓冲区中,直到缓冲区已满或进程终止。由于打印单个整数需要2300737156次迭代,因此在填充缓冲区之前需要一段时间。和110357158424696次迭代,然后程序终止并自动刷新和关闭
stdout
。虽然如果你用优化编译它,编译器会识别出内部循环,什么也不做,并消除它们;然后您的代码将很快执行和打印


您可以通过在打印后立即手动刷新缓冲区来解决此问题。

只有三种情况会将输出从缓冲区发送到屏幕:

1:缓冲区满时发送

2:遇到换行符时(在行缓冲终端中)

3:当有即将到来的输入时

与评论中所说的不同,如果这里出现了缓冲问题,那么这个简单的单循环也不会起作用:

for(i=0;i<47966;i++)
{
    printf(" %d",i);
}
在您的例子中,在第一次缓冲区溢出发生之前需要等待很长时间。我提到溢出是因为:

  • 即使您的终端设置为行缓冲区,也没有
    \n
    来刷新它
  • 没有即将到来的输入
来源: -

注意:忽略
未签名的long
部分-它只是来自某个我懒得更改的旧程序


MAJOR-->如果在最里面的循环中使用
fflush(stdout)
,您会发现,这只是一个计时问题—将所有数据从0缓冲到47966需要花费大量时间,因为在两次连续刷新之间,缓冲区中只有一个数字。

只有三种情况下,输出从缓冲区发送到屏幕:

1:缓冲区满时发送

2:遇到换行符时(在行缓冲终端中)

3:当有即将到来的输入时

与评论中所说的不同,如果这里出现了缓冲问题,那么这个简单的单循环也不会起作用:

for(i=0;i<47966;i++)
{
    printf(" %d",i);
}
#include<stdio.h>

int main(void)
{
    unsigned long int i=47966,k;

    for(i=0;i<47966;i++)
        for(k=0;k<47966;++k)
            {

            }

    return 0;
}
#include<stdio.h>

int main(void)
{   
    unsigned long int i=47966,k,z;

    for(i=0;i<47966;i++)
    {
        printf(" %d",i);
        for(k=0;k<47966;++k)
        {

        }
    }

    return 0;
}
//WRITTEN TO CHECK WHEN DOES THE FIRST OVERFLOW OCCURS
#include<stdio.h>

int main(void)
{
    unsigned long int i=47966,k,z;

    for(i=0;i<47966;i++)
    {
        printf(" %d",i);
        for(k=0;k<47966;++k)
        {
            printf("-");
        }
    }

    return 0;
}