\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 <unistd.h>
void test(){
int i = 10;
while(i)
{printf("%2d\r",i); //%2d 示意显示两个字符
fflush(stdout); //fflush 是一个库函数,用来立刻刷新缓冲区输入到显示器中
sleep(1);
i--;
}
}
全缓冲与无缓冲示例一
#include <stdio.h>
#include <unistd.h>
#include <string.h>
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 提供文件描述符和用户缓冲区。