C语言入门 – 缓冲区

LongGuan_admin 发布于 7 天前 25 次阅读


概述

程序在内存空间中预留的一定的存储空间,用作缓冲输入或输出的数据,这部分预留的空间叫做缓冲区。

缓冲区根据对应的输入设备或者输出设备,分为输入缓冲区输出缓冲区

为什么要有缓冲区

  • 减少IO设备的操作
  • 提高计算机运行速度

比如从磁盘内读取信息,先将读出的数据放在缓冲区,计算机再从缓冲区中读取数据,等到缓冲区的数据取完后再去磁盘中读取,可以有效减少磁盘的读写次数。因为计算机对于缓冲区的操作远快于磁盘的操作,所以可以很大程度上提高计算机的运行速度。

缓冲区的类型

  • 全缓冲 Linux -- 1024字节
    • 缓冲区填满后才会进行实际的IO操作
    • 刷新方法
      • 缓冲区满刷新
      • 程序正常结束释放内存
  • 行缓冲
    • 在输入和输出中遇到换行符时才会执行真正的IO操作
    • 刷新方法
      • 遇到\n换行符刷新缓冲区数据
      • 缓冲区满刷新
      • fflush()手动强制刷新缓冲区 //只对输出缓冲区有用
        • stdout标准输出 -- 屏幕
        • stdin标准输入 -- 键盘
        • stderr标准错误 -- 屏幕
  • 无缓冲 perror()
    • 将错误信息输出到屏幕上
  • 缓冲区在程序正常退出后也会被释放,导致缓冲区中的数据刷新出来
  • 文件IO中输入缓冲区和输出缓冲区公用同一段内存,这段缓存即被用作输入,也被用作输出
    • 输入方法scanf()
    • 输出方法printf()
//在Linux中实验
int main(){
  for (int i = 1; i <= 1025; i++){
    printf("X");
  }
  printf("@");
  sleep(3);
  return 0;
}

可以看到在打印了1024个x(缓冲区满)后,多出的一个x会放入缓冲区中等待刷新,等待3秒程序结束后’x@‘刷新出来。由此得到缓冲区在程序正常结束后也会被释放刷新数据。

缓冲区的切换

在缓冲区的类型中我们得知,在文件IO中,输入缓冲区和输出缓冲区公用一段内存,这会导致一些缓冲区刷新上的冲突

  • 如果输入缓冲区在前
    • scanf()函数等待用户输入,会阻塞后续的程序进行,只有当用户将数据输入输入缓冲区后,才能执行到后面的程序(缓冲区清空),所以数据不会被强制刷新
int num;
scanf("%d",&num);
printf("hello");
  • 如果输出缓冲区在前
    • printf()函数如果先调用,在输出缓冲区没有换行符的情况下,使用scanf()函数调用输入缓冲区,数据会被强制刷新,进入输入缓冲区中等待。
int num;
printf("hello");
scanf("%d",&num);

printf函数的使用

按照指定的字符串模板格式输出数据

%s字符串格式
%d整型(int)
%c字符型(char)
%hd短整型(short)
%hhd字符型的ASCII码 char数据对应的ASCII
%f单精度浮点型(float)
%lf双精度浮点型(double)
%ld长整型(long int)
%lld长长整型(long long int)
%x十六进制
%#x带前缀的十六进制
%#o带前缀的八进制
#o八进制
%p打印内存地址
%e以科学计数法的方式将浮点数打印出来

字段宽度

  • 输出的字符所占的终端的列数
    • 用户可以指定宽度
      • 如果指定宽度为10,但是实际输出字符只有四个,那么剩余的6列用空格补齐
int a=10,b=30;  
float f = 3.141566;
printf("a:%#x\n",a);          //结果为0xa
printf("b:%10#x\n", x);       //结果为      0x14
printf("f=%f\n", f);          //结果为3.141566
printf("f=%.2f\n", f);        //结果为3.14

//输出多个数据
printf("a:%d, b:%d\n", a, b);
printf("a:%d, b:%d, f:%f\n", a, b, f);

scanf函数的使用

按照指定的字符串模板格式输入数据(与printf使用相同的格式控制符)

传入需要写入变量地址 & + 变量名

变量不作为左值时,一般都是读取其值的行为

目的是把数据写入到指定变量的内存中,而不是读取他的值

所以必须把变量的地址给scanf,此时就能通过变量的地址来找到这段内存并写入

scanf("%d, %d",&year, &month);

scanf中存在的问题

  • scanf()中%d会自动识别空格 \n 回车并跳过
  • 如果前面的输入中1输入了字符,会填入缓冲区传给下一个scanf
  • 实际开发中,每次输入后,都要清空缓冲区中刷新出来的残留
int a,b;
int ret = scanf("%d%d",&a,&b); //输入12 13 或12   13 scanf可以正常识别,但是只能识别空格
printf("a == %d  b == %d 成功给%d个成员写入了数据" a, b ,ret);

char c;
scanf("%c",&c);
  • 读取到了换行符
  • 字符串格式控制符只能接受一个单词而不是一个完整的句子
char str[100];
scanf("%s",str); //数组比较特殊,不需要写取地址符
printf("%s\n", str);
  • 解决方法
char str[100];
scanf("%[^\n]",str); //除了换行全都要
printf("%s\n", str);

getchar函数

从标准输入中读取一个字符,并返回一个int类型的值。这个返回值是读取字符的ASCII码值

    int num = getchar();
    printf("%c \n", num);
    num = getchar();
    printf("%c \n", num);
    num = getchar();
    printf("%c \n", num);
    num = getchar();
    printf("%c \n", num);

此作者没有提供个人介绍。
最后更新于 2026-01-09