【发布时间】:2018-07-22 01:20:35
【问题描述】:
当我使用printf() 编写一个小程序时,我注意到在随后的printf() 调用中使用的每个\t 字符都从上一个printf() 调用中的字符串末尾继续。
下面的图片和代码示例将阐明我的意思。
预期输出示例
printf("\t%d", i); // Prints multiples of 1
printf("\t%d", i * 2); // Prints multiple of 2
printf("\t%d", i * 3); // ... multiple of 3
printf("\t%d", i * 4); // ... multiple of 4
printf("\t%d", i * 5); // ... multiple of 5
printf("\n"); // Starts new line after each number printed.
要在上图中获得所需的输出,我期望必须这样做:
printf("\t%d", i);
printf("\t\t%d", i * 2);
printf("\t\t\t%d", i * 3);
printf("\t\t\t\t%d", i * 4);
printf("\t\t\t\t\t%d", i * 5);
但这不起作用,后面的每个 printf() 调用都从前一个字符串的末尾继续,这是有道理的,因为我们不使用新行。
最终,我决定一个 printf 调用做同样的事情,虽然可读性稍差,而且开销可能更少。
printf("\t%d\t%d\t%d\t%d\t%d\n", i, i, i * 2, i * 3, i * 4, i * 5);
这让我对 printf() 的工作原理感到好奇。对函数的每个后续调用是否使用第一次调用创建的相同内部缓冲区?
谢谢!
【问题讨论】:
-
它有什么不同?
-
处理缓冲的不是
printf调用,而是FILE流。printf函数写入有自己的缓冲区的stdout。实际创建stdout(或任何FILE流)缓冲区的方式、时间和地点在很大程度上无关紧要。 -
对于您展示的简单案例,“开销”可以忽略不计。将文本写入控制台可能比六个
printf调用慢得多。 -
最后,提前考虑这些事情通常是过早的优化,这往往会导致糟糕的代码。首先要专注于编写好的、可读的和可维护的代码。然后,如果有一些效率要求(并且程序“不够好”(通常是足够好)),那么测量、分析和基准测试以找到瓶颈和热点,并专注于最糟糕的那些第一。使用适当的文档和注释(因为优化通常会使代码几乎无法维护)。
-
使用新的/相同的缓冲区无法解释您所看到的。