scanf/printf在大量整数i/o时因格式解析、locale检查、缓冲同步等开销成为瓶颈;快读用fread批量读入+字符解析,快写用栈存数字+缓冲区批量输出,并需关闭iostream同步、手动flush。

为什么 scanf/printf 在大量整数 I/O 时会成为瓶颈
标准库的 scanf 和 printf 做了太多事:格式解析、locale 检查、缓冲区同步、错误检查。当你要读写百万级整数(比如 OI 题、数据预处理),这些开销会明显拖慢整体速度。实测中,关闭同步的 cin/cout 仍比手写快读慢 20%~40%,而纯 C 风格的 fread+手动解析可提速 3~5 倍。
快读模板:用 fread 批量读入 + 字符解析
核心思路是绕过 stdio 缓冲,用 fread 一次性读大块内存,再逐字节解析数字。注意几个关键点:
- 必须用
static char buf[1 静态缓冲区,避免频繁栈分配; - 解析时跳过空白字符(
' '、'\n'、'\t'、'\r'),但别漏掉负号'-'; - 用
ch - '0'比isdigit(ch)更快,且无需<cctype></cctype>; - 溢出检测可省略(OI 场景通常保证输入合法),否则加
if (x > INT_MAX / 10 || (x == INT_MAX / 10 && ch > '7'));
static char buf[1inline int read() {
int x = 0, f = 1; char ch = gc();
while (ch '9') { if (ch == '-') f = -1; ch = gc(); }
while (ch >= '0' && ch 10 + ch - '0'; ch = gc(); }
return x f;
}
快写模板:避免递归 + 小缓冲区批量输出
递归写法(如 write(x/10); putchar(x%10+'0'))函数调用开销大,且栈深度不可控。更优做法是用栈式数组暂存各位数字,再一次性 fwrite 输出:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 缓冲区大小建议设为
1(64KB),太小导致系统调用频繁,太大无意义; - 负数先输出
'-',再转正处理; - 数字为 0 要特判,否则循环不进;
- 别用
std::to_string或sprintf,字符串构造和内存分配太重;
static char outbuf[1inline void write(int x) {
if (!x) { pc('0'); return; }
if (x <h3>使用前必须关同步 + 清空缓冲区</h3><p>即使你写了快读快写,如果没关掉 iostream 同步,<code>stdin/stdout</code> 仍可能被 <code>cin/cout</code> 污染或阻塞:</p>
- 在
main()开头加ios::sync_with_stdio(false); cin.tie(nullptr);; - 若之前用过
cin >> x或printf,必须先fflush(stdout)和fflush(stdin)(后者在 Linux 下有效,Windows 需用_flushall()); - 快写缓冲区记得在程序退出前
if (outp != outbuf) fwrite(outbuf, 1, outp - outbuf, stdout);;
最易被忽略的是多组测试数据下缓冲区未清空——某次 write 后没 flush,下一轮读就卡住。别指望析构函数自动 flush,它不一定触发。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










