跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 快读快写技术详解

C++ 快读快写是解决大规模数据输入输出瓶颈的关键手段。通过 getchar/putchar 基础版可提速 2-3 倍,缓冲区优化版(fread/fwrite)进一步减少系统调用开销,性能再翻倍。终极版本结合命名空间封装,兼顾效率与易用性。根据数据量选择合适方案,避免超时。

邪神洛基发布于 2026/3/25更新于 2026/6/921 浏览

C++ 高性能输入输出优化实战

在算法竞赛或高并发场景下,cin/cout 和 scanf/printf 往往成为性能瓶颈。当数据量达到百万级时,标准 IO 可能直接导致超时。这时候,手写快读快写就成了必备技能。

基础版:getchar / putchar

最基础的优化是利用字符缓冲流。相比 scanf,直接读取字符并手动解析整数能减少大量函数调用开销。

支持负数的整数快读

inline int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + (ch - '0');
        ch = getchar();
    }
    return x * f;
}

无符号整数快读(更快)

inline unsigned int read() {
    unsigned int x = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') ch = getchar();
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + (ch - '0');
        ch = getchar();
    }
    return x;
}

整数快写(递归实现)

inline void write(int x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

进阶版:缓冲区优化

如果数据量极大,频繁的系统调用依然是瓶颈。利用 fread 和 fwrite 一次性读写大块内存,可以显著降低 I/O 等待时间。

静态缓冲区快读

char buf[1 << 21], *p1 = buf, *p2 = buf;
inline char get_char() {
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline int read() {
    int x = 0, f = 1;
    char ch = get_char();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = get_char();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + (ch - '0');
        ch = get_char();
    }
    return x * f;
}

缓冲区快写与刷新

char pbuf[1 << 21], *pp = pbuf;
inline void push(const char& c) {
    if (pp - pbuf == (1 << 21)) {
        fwrite(pbuf, 1, 1 << 21, stdout);
        pp = pbuf;
    }
    *pp++ = c;
}
inline void write(int x) {
    static int sta[35];
    int top = 0;
    if (x < 0) {
        push('-');
        x = -x;
    }
    do {
        sta[top++] = x % 10;
        x /= 10;
    } while (x);
    while (top) push(sta[--top] + '0');
    push('\n');
}
inline void flush() {
    fwrite(pbuf, 1, pp - pbuf, stdout);
    pp = pbuf;
}

注意:程序结束前需调用 flush() 确保剩余数据写入。

扩展类型与命名空间封装

针对 long long 或字符串也有对应的实现。为了代码整洁,通常会将这些功能封装进命名空间。

长整型读取

inline long long readll() {
    long long x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + (ch - '0');
        ch = getchar();
    }
    return x * f;
}

一行字符串读取

inline void readstr(char* str) {
    char ch = getchar();
    while (ch == ' ' || ch == '\n') ch = getchar();
    while (ch != ' ' && ch != '\n' && ch != EOF) {
        *str++ = ch;
        ch = getchar();
    }
    *str = '\0';
}

终极优化版本(Namespace 封装) 这种写法将输入输出逻辑完全隔离,方便复用且不易污染全局命名空间。

namespace FastIO {
    const int SZ = 1 << 20;
    char inbuf[SZ], outbuf[SZ];
    int in_left = 0, in_right = 0;
    int out_right = 0;

    inline void load() {
        int len = fread(inbuf, 1, SZ, stdin);
        in_left = 0;
        in_right = len;
    }

    inline char get_char() {
        if (in_left >= in_right) load();
        if (in_left >= in_right) return EOF;
        return inbuf[in_left++];
    }

    inline int read() {
        int x = 0, f = 1;
        char ch = get_char();
        while (ch < '0' || ch > '9') {
            if (ch == '-') f = -1;
            ch = get_char();
        }
        while (ch >= '0' && ch <= '9') {
            x = x * 10 + (ch - '0');
            ch = get_char();
        }
        return x * f;
    }

    inline void flush() {
        fwrite(outbuf, 1, out_right, stdout);
        out_right = 0;
    }

    inline void put_char(char ch) {
        outbuf[out_right++] = ch;
        if (out_right == SZ) flush();
    }

    inline void write(int x) {
        if (x < 0) {
            put_char('-');
            x = -x;
        }
        if (x > 9) write(x / 10);
        put_char(x % 10 + '0');
    }

    struct Flusher {
        ~Flusher() { flush(); }
    } flusher;
}
using FastIO::read;
using FastIO::write;
using FastIO::put_char;

使用示例

int main() {
    int n = read(); // 读取一个整数
    write(n);       // 输出一个整数
    put_char('\n'); // 输出换行

    // 使用命名空间版本
    int m = FastIO::read();
    FastIO::write(m);
    FastIO::put_char('\n');

    return 0; // Flusher 会在程序结束时自动调用 flush()
}

性能对比与建议

实际测试中,不同版本的提升幅度大致如下:

  • 基础版 (getchar/putchar):比 scanf/printf 快约 2-3 倍。
  • 缓冲区版 (fread/fwrite):比基础版再快 2-3 倍。
  • 终极优化版:在极端大数据量下表现最佳,比缓冲区版再快约 1.5 倍。

对于大多数算法竞赛题目,基础版或缓冲区版已经足够应对。只有面对千万级数据输入的极限情况,才建议启用终极优化版本。合理选择方案,别让 IO 拖了算法的后腿。

目录

  1. C++ 高性能输入输出优化实战
  2. 基础版:getchar / putchar
  3. 进阶版:缓冲区优化
  4. 扩展类型与命名空间封装
  5. 性能对比与建议
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Typora 软件安装与基础配置指南
  • Linux 核心 IO 模型深析:CMake 构建与 Poll 多路转接实现
  • Seedance 2.0 成本诊断插件:内置实时 FLOPs/USD 热力图与优化策略
  • 大模型学习路线与实战项目推荐:多模态、医学 AI 及数字人
  • AIGC 技术发展历程与核心应用
  • AI 赋能 FPGA 开发:Vivado 配置与智能编程实践
  • Python 爬虫入门实战:Requests、Scrapy 与异步爬取
  • OpenClaw 从零部署指南:安装、QQ 机器人接入与运维详解
  • Claude Code 高级编程技巧实战项目详解
  • OpenClaw 安装部署全流程:搭建自托管 AI 助手
  • Seedance 2.0 飞书机器人集成安全合规与零信任加固方案
  • Edge 边栏 Copilot 图标消失的修复方案
  • 两个月学习大语言模型(LLM)的详细学习计划与实战指南
  • 华为 OD 机试:员工派遣
  • AI 产品经理面试通关:100 道高频问题深度解析与核心知识点梳理
  • 命令行大模型工具交互实践:小巧的 MCPHost
  • CogVideoX-2b 视频生成 WebUI 使用指南:本地部署与操作
  • AI 毕业论文写作指令指南
  • PHP 语言简介:历史、特点及工作原理
  • 手机上也能运行Stable Diffusion?Github上开源且完全免费的AI生图软件!斩获1.4K Stars

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online