IO进程day01(标准IO、缓存区)

目录

【1】标准IO

1》概念:

2》特点

【2】缓存区

1》全缓存:和文件相关

2》行缓存:和终端有关

3》不缓存:也就是没有缓存区,标准错误。


【1】标准IO

1》概念:

标准IO: 是在C库中定义的一组专门用于输入输出的函数。

2》特点

(1)通过缓冲机制减少系统调用,提高效率

例如:从硬盘中读1KB文件,每次只能读1B,循环读1024次。

在这个例子中,正常情况下用户通过app->系统调用接口-> 驱动程序-> 硬盘,最终进入硬盘读取数据,这样需要重复该操作1024次,效率非常低。

但通过缓冲机制,就可以在第一次进入硬盘的时候,在硬盘中拿取一个缓冲区大小的数据(可能大于要读取数据,有可能小于要读取数据),放入缓存区中,从缓存区中读取此次数据,而且剩下的1023次也都可以直接在缓存区中读取数据,相较之前,效率大大提高。

(2)围绕流进行操作,流用FILE*来表示

建立ctags索引

vi 的 ctags 使用:

(1)vi -t 查找名称

输入对应序号,回车查找

(2)继续追踪

将光标定位到要追踪的内容上,按ctrl + ],即可追踪查询

回退:ctrl + t

(3)跳转到上次的位置:ctrl + o

跳转到下次的位置:ctrl + i

vscode的ctags使用
鼠标定位到要追踪的内容上:ctrl 左键

前后跳转:

跳转到上次的位置:ctrl alt -

跳转到下次的位置:ctrl shift -

(3)标准IO默认打开三个流 stdin(标准输入)、stdout(标准输出) 和 stderr(标准错误)。

【2】缓存区

1》全缓存:和文件相关

刷新全缓存:

  • 程序正常退出
  • 强制刷新:fflush(NULL);
  • 缓存区满

2》行缓存:和终端有关

刷新标准输出缓存的条件:

  • \n
  • 程序正常退出
  • 强制刷新:fflush(NULL);
  • 缓存区满

例:

cs 复制代码
#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("hello world");
    while(1);//死循环,程序无法结束,printf语句无法打印
    return 0;
}

解决方法1: \n

cs 复制代码
#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("hello world\n");//\n刷新缓存区
    while(1);
    return 0;
}

解决方法2:去掉while循环,让程序正常结束

cs 复制代码
#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("hello world");
    //while(1);
    return 0;
}

解决方法3:fflush(NULL) 强制刷新

cs 复制代码
#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("hello world");
    fflush(NULL);//强制刷新
    while(1);
    return 0;
}

解决方法4:当缓存区满时也会打印

例:一个缓冲区大小是1024个字节
利用循环输出打印展示 一次打印4个字节 %4d

cs 复制代码
#include <stdio.h>

int main(int argc, char const *argv[])
{
for(int i = 0;i <= 256;i++)
    printf("%4d",i);

    while(1);
    return 0;
}

3》不缓存:也就是没有缓存区,标准错误。

perror:标准错误 会直接打印,printf :缓存区未满不会打印

cs 复制代码
#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("hello world");
    perror("error");//标准错误,会直接打印
    while(1);
    return 0;
}

练习:计算标准输出缓存区大小 KB
利用结构体指针stdout

cs 复制代码
#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("buf:");
    printf("%ld\n",stdout->_IO_buf_end - stdout->_IO_buf_base);

return 0;
}

综上:当我们每次要在终端打印数据时,并不是将数据直接发送给标准输出设备,也就是并直接发送给显示器,而是将要打印的数据先存放到缓存区,当缓冲存数据满时,或者遇到\n,或者程序结束时,或者手动刷新缓存区时,缓冲区才会把数据传输到标准输出设备中,也就是显示器中进行输出。但是全缓存不能用\n刷新缓存。


今天的分享就到这里结束啦,如果有哪里写的不好的地方,请指正。

如果觉得不错并且对你有帮助的话请给个三连支持一下吧!

相关推荐
YuMiao1 小时前
gstatic连接问题导致Google Gemini / Studio页面乱码或图标缺失问题
服务器·网络协议
chlk1231 天前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑1 天前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件1 天前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
碳基沙盒1 天前
OpenClaw 多 Agent 配置实战指南
运维
深紫色的三北六号1 天前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash2 天前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI2 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行3 天前
Linux和window共享文件夹
linux
Sinclair3 天前
简单几步,安卓手机秒变服务器,安装 CMS 程序
android·服务器