建设银行信用卡中心网站,电商网站设计思维导图,视频app开发制作多少钱,电子商务网站建设的平台学习标准输入输出#xff0c;我们都会遇到一个概念#xff0c;流和缓冲区#xff0c;但到底什么是流#xff0c;什么是缓冲区呢#xff1f; 书《C Primer Plus》上说#xff0c;C程序处理一个流而不是直接处理文件。后面的解释十分抽象#xff1a;『流#xff08;strea… 学习标准输入输出我们都会遇到一个概念流和缓冲区但到底什么是流什么是缓冲区呢 书《C Primer Plus》上说C程序处理一个流而不是直接处理文件。后面的解释十分抽象『流stream是一个理想化的数据流实际输入或输出映射到这个数据流』。这个流具体是一个怎么样的东西呢
流这个定义非常的形象。我们可以这样理解 你声明一个FILE *fp 并把fopen(某个文件)返回的值赋予fp这两个动作就相当于建立了一个水龙头当你用getc(fp)之类的输入函数读取文件字符时就相当于拧开了水龙头每读取一个字符这个文件就像水一样的流动一下fp所指的地址自然就向后移动了一位。[cpp] view plaincopy int ch; while(chgetc(fp))!EOF putchar(ch); 你看这个循环可以读取一个文件的所有字符。如果不是流的话ch永远是第一个字符不会更新。也可以理解为fp自动一个字符的大小。但流的概念意味着什么呢 --流是独立于设备之外而操纵外设一种逻辑手段。 --大多数外设都是互异的所以操纵它们需要专门的编程技术。 --流对程序员隐藏这些不同点而准许他们以同样的方式来处理大多数外设。 --考虑到一连串的字符需要一次读一个流相当于是具有缓冲作用的接口。 --个人计算机都是基于流架构的。 各大权威对流的说法有些不一致我认为流既是数据的源或目的地的抽象也是源和目的地之间流动信息的表示。但流起码都暗含以下的几个方面 1、流是一个抽象的概念是对信息的一种表达在程序中流就是对某个对象输入输出信息的抽象。就像运输工具是对一切运动载体的抽象一样。 2、流是一种“动”的概念静止存储在介质上的信息只有当它按一定的序列准备“运动”时才称为流。“从程序移进或移出字节”就是“动”的表现。静止的信息具有流的潜力但不一定是流就像没有汽油不能行走的汽车一样它具有运输工具的潜力但它还不是运输工具因为它很有可能被当作房子来用了我就在大街上看见有精明的商人用火车车厢来做酒吧。 3、流有源头也有目的地程序中各种移动的信息都有其源和目的记得编程特别是汇编时老是要确定好某个操作的源操作数和目的操作数。借用佛教一言也即是“万物皆有因果”这也就像长江一样西自唐古拉而东去太平洋。在高速公路上飞跑的汽车它必有其出发地和目的地。 4、流一定带有某种信息没有任何内容的流带着自身来表达“空”信息。就像运输工具一样它不运货的时候就运着自己这一身的零件包括驾驶员并把一样东西运到目的地那就是它自己和一个“跑空车”的信息。流有最小的信息单元就是二进制位含有最小的信息包就是字节C标准库提供两种类型的流二进制流binary stream和文本流text stream。二进制流是有未经处理的字节构成的序列文本流是由文本行组成的序列。而在著名的UNIX系统中文本流和二进制流是相同的identical。 5、流有源头也有目的地那么它必定与源头和目的地相关联。但人们操作流的时候最关心的还是其目的地也就是一个定向orientation的意思就像司机运货一样它首要关心的问题是目的地而非起点操作者都知道。在C语言中通过打开流来关联流及其目的地使用的函数是fopen()该函数返回一个指向文件的指针FILE *该指针包含了足够的可以控制流准确地到达目的地的信息。 FILE是一个结构体摘自TC2.0中stdio.h文件[cpp] view plaincopy /* Definition of the control structure for streams */ typedef struct { short level; /* fill/empty level of buffer */ unsigned flags; /* File status flags */ char fd; /* File descriptor */ unsigned char hold; /* Ungetc char if no buffer */ short bsize; /* Buffer size */ unsigned char *buffer; /* Data transfer buffer */ unsigned char *curp; /* Current active pointer */ unsigned istemp; /* Temporary file indicator */ short token; /* Used for validity checking */ } FILE; /* This is the FILE object */ 将它称为流控制结构体control structure for streams真好表现出其功能来。举个例子就好像一卡车司机要把货物运到X公司公司主管就会给他一张地图及X公司的基本信息这些材料所提供的信息如果足够的话那么它就能指导着司机准确地将货物送达了。C中FILE这个结构体所起的作用就好像是运输公司把一切有用的指导信息封装起来的档案袋一样。而已有关联的流要终止这种关联就必须关闭流使用的函数是fclose()就像运货公司若不再给X公司运货了那么他们就必须要终止合作协议了。 这里要注意的是C语言中stdin、stdout、stderr分别是标准输入流、标准输出流及标准出错流的逻辑目的他们都默认对应相应的物理终端。在程序运行伊始不需要进行open()操作流自动打开。 那缓冲区又是什么意思呢缓冲区Buffer 为了匹配计算机快速设备和慢速设备间的通信步伐计算机中大量使用硬件缓冲区如CPU中的Cache内存相对于硬盘和CPU流是传输信息的一种逻辑表示对流的各种不同操作也可能存在使用缓冲的需求。但是这里的buffer只是一种逻辑概念不是物理设备。缓冲区存在于流与具体的设备终端或者存储介质上的文件之间。就好像运货到一个公司里一样合同上的要求是运到X公司但是实际上是真的把货物运到X公司的总部大楼吗不是。应该是运到X公司的仓库中。这里的仓库就有点像我们所说的缓冲区了。也可以这么说流运动到目的先经过的是缓存区。以scanf() printf()为例 • 缓冲区流负责在输入/输出设备和程序之间建立联系。 –输入设备-内存缓冲区(stdin)-程序 –程序-内存缓冲区(stdout)-输出设备 • 是一块临时的存储区域或在内存中或在设备的控制卡上 . 缓冲类型。 标准库提供缓冲是为了减少对read和write的调用。提供的缓冲有三种类型(整理自APUE): 全缓冲。 在这种情况下,实际的I/O操作只有在缓冲区被填满了之后才会进行。对驻留在磁盘上的文件的操作一般是有标准I/O库提供全缓冲。缓冲区一般是在第一次对流进行I/O操作时,由标准I/O函数调用malloc函数分配得到的。 术语flush描述了标准I/O缓冲的写操作。缓冲区可以由标准I/O函数自动flush(例如缓冲区满的时候);或者我们对流调用fflush函数。 行缓冲 在这种情况下,只有在输入/输出中遇到换行符的时候,才会执行实际的I/O操作。这允许我们一次写一个字符,但是只有在写完一行之后才做I/O操作。一般的,涉及到终端的流--例如标注输入(stdin)和标准输出(stdout)--是行缓冲的。 无缓冲 标准I/O库不缓存字符。需要注意的是,标准库不缓存并不意味着操作系统或者设备驱动不缓存。 当然我们常用的scanf() 与 printf() 属于行缓冲下面我们来看个例子可以帮助我们理解缓冲区在标准输入输出中的作用 [cpp] view plaincopy pre classcpp namecode#include stdio.h int main() while(1); { printf(hello world); while(1); } 我们看看输出结果 [cpp] view plaincopy fsubuntu:~/qiang/char1$ gcc -o 1 1.c fsubuntu:~/qiang/char1$ ./1 打出是个空的为什么呢 我们上面提到标准输入输出是行缓冲即一行满了才会刷新那什么是刷新呢刷新就是将数据从缓冲区取出来真正能刷新要满足什么条件呢 1、满刷新即一行满了1024个字节才会刷新 2、遇到\n会刷新 3、调用fflush()函数 4、程序结束 fclose(); 我们可以看到上面的程序应为有while(1),程序一直没有结束没有\n没有满行没有fflush(),所以并不会输出 这样理解的话我们可以改动一下了就写一个吧加\n: [cpp] view plaincopy #include stdio.h int main() { printf(helloworld\n); while(1); } 执行结果如下 [cpp] view plaincopy fsubuntu:~/qiang/char1$ gcc -o 1 1.c fsubuntu:~/qiang/char1$ ./1 helloworld