我编写了一个使用for循环打印整数值的程序,打印完成后,程序应等待一秒钟,然后用双倍空格字符覆盖这些整数,换句话说,程序的目的是在等待后擦除那些整数一秒钟。
这个程序:
#include <stdio.h>
#include <time.h>
int main (void) {
int i;
for(i=1;i<=5;i++){
printf("%d ",i);
}
for(;clock () < CLOCKS_PER_SEC;){} /*wait for one second*/
printf("\r"); /*move to the beginning of the line*/
for(i=1;i<=5;i++){
printf(" "); /*overwriting the integers*/
}
printf("\n");
return 0;
}
问题在于等待循环循环括号`for(; clock()&lt; CLOCKS_PER_SEC;){}&#39;当我 删除程序正常工作的括号。但如果for循环带括号。程序不起作用,我的意思是程序仍然运行,但它会覆盖整数,而不是先显示那些整数。
请有人解释一下发生了什么?
答案 0 :(得分:2)
当你删除括号时,printf(“\ n”)语句成为for循环的主体,在逻辑上等同于:
for(;clock () < CLOCKS_PER_SEC;) {printf("\r");}
因此,整数会立即被覆盖,而不是在延迟期结束后被覆盖。
当然,真正的问题是为什么你使用忙循环来进行延迟而不是仅仅调用sleep(1),这样效率要高得多(即在延迟期间不会将CPU固定为100%)周期)
答案 1 :(得分:2)
你不是自己刷新stdout(printf写入的流),所以直到&#39; \ r&#39;才会发生这种情况。是写的,然后你立即清除它。
如果删除{}
,则循环等同于
for(;clock () < CLOCKS_PER_SEC;)
printf("\r");
写了一堆\r
,其中第一个刷新输出,其余的都是冗余的。循环完成后,清除该行,按照您的意愿工作。
打印数字后,您应该致电fflush(stdout)
。或者你可以移动printf(&#34; \ r&#34;),使它在等待循环之前出现(差异是光标结束的地方)。
你的循环是有问题的,因为不能保证clock()从0开始,并且在许多系统上都不会,并且你不应该像那样旋转...它会减慢关闭系统上运行的其他程序。你可以使用sleep(1),虽然它不是很准确。
答案 2 :(得分:1)
我怀疑输出缓冲区在两种情况下的刷新方式不同。您可以通过在有问题的循环之前使用fflush(stdout)
手动刷新缓冲区来检查这一点。
另请注意,对于循环内的单行语句,C中的{}
不是必需的。
答案 3 :(得分:0)
在第一个'for'循环中,您使用printf打印值。这里'printf'使用'stdout',这是一个缓冲输出 - 除非提供'\ n'或缓冲区已满,否则不会打印输出。所以你可以在第一次循环后使用flush(stdout)
或使用fprintf(stderr, "")
打印到不是缓冲输出的标准错误。
答案 4 :(得分:0)
以下是您可能需要的代码:
#include <stdio.h>
int main(int argc, char * argv[]) {
int seconds = 10;
while(seconds>0) {
printf("%10d", --seconds);
fflush(stdout);
sleep(1);
printf("\r");
}
printf("%10s\n", "time up!");
return 0;
}
(因为你问fflush()是什么意思,这里有一个基于我理解的小解释)
关于io缓存,1缓存存在的原因是:读/写内存可能比硬盘快1000倍。
所以程序应该尝试减少读/写硬盘的频率,改为使用内存,但需要对用户体验和延迟进行适当的权衡。
例如
fflush(FILE *文件),是stdio.h中的一个函数,它刷新指定FILE的缓存。在您的情况下,该文件是stdout(标准输出),它打印到您的控制台。当你使用printf()打印一个数字时,它可能会写入stdout的缓存,所以你没有在控制台中看到它,但调用fflush(stdout)将缓存刷新到你的控制台。