数据缓冲区

\r 和 \n 的区别

  • \r 表示回车 (回车表示换到当前行的最开始)
  • \n 表示换行(换行只是换到下一行)
  • 注意:但是在实际使用时,\n 就直接表示了 \r\n 回车换行。
    数据缓冲区
    文章图片
缓冲区的概念
  • 行缓冲:常见的是对显示器进行刷新数据时
    • 即必须缓冲区中一行填满了或者遇到 \n 才会输出到显示器
  • 全缓冲:对文件进行写入时采用全缓冲
    • 即将整个缓冲区填满才会刷新到磁盘中。
  • 无缓冲:即刷新数据时没有缓冲区。
行缓冲示例一:
  • 下列代码执行后的结果是:停止5秒后才显示 hello world
    • printf 这行代码是先执行的
    • 但是 printf 中没有 \n ,并且缓冲区中的一行并没有填满,所以没有输出到显示器
    • 所以继续执行下面的 sleep 代码
    • 在程序结束后会刷新缓冲区,将缓冲区的内容输出到显示器,所以最后仍然会显示。
void test() { printf("hello world"); //加入 \n后就会立即输出到显示器了。 sleep(5); }

行缓冲示例二
  • 下列代码显示结果为:倒计时,并且下一次的数字会覆盖上一次的数字。
  • 因为 \r 只是回车,并未换行,所以依然会在之前那一行继续输出
  • 并且回车后,会回到这一行的起始位置,所以覆盖了上一次的值。
#include void test() { int i = 10; while(i) { printf("%2d\r",i); //%2d 表示显示两个字符 fflush(stdout); //fflush是一个库函数,用来立即刷新缓冲区输出到显示器中 sleep(1); i--; }}

全缓冲与无缓冲示例一
#include #include #include int main() { //C语言函数 printf("hello printf\n"); fprintf(stdout,"hello fprintf\n"); //系统函数 const char * msg = "hello write\n"; write(1,msg,strlen(msg)); fork(); return 0; }

【数据缓冲区】数据缓冲区
文章图片

  • 正常输出到显示器中时,是正常显示三行
  • 但是重定向输出到文件中时,会多打印2行
  • 当往显示器中打印时,系统采用的是行缓冲,即运行到 printf 等函数后,立马将数据刷新到显示器。
  • 但是当重定向打印到文件时,缓冲方式发生变化,变成全缓冲,全缓冲会等到程序结束时,一次性将缓冲区内容打印到文件中
  • 程序最后创建了子进程,子进程会继承父进程的缓冲区(子进程的缓冲区和父进程缓冲区内容相同,但是不是一个缓冲区,进程的独立性,发生写实拷贝)
  • 所以父进程刷新一次缓冲区后,子进程也会刷新缓冲区,所以会打印两次 C 函数的内容。
  • 因为系统函数(系统接口)没有缓冲区,所以 write函数只打印一次,并且是第一个被打印。
缓冲区位置
  • 缓冲区是由 C 语言本身自带的,所有的 C 函数接口都有缓冲区,而系统接口没有缓冲区。
  • 缓冲区是维护在文件结构体 files_struct 中,files_struct 提供文件描述符和用户缓冲区。

    推荐阅读