问题描述
在“ C编程:一种现代方法”的第22章中,介绍了<stdio.h>
标头的基本知识。
一个让我有些困惑的细节是指向缓冲区的指针和指向文件的指针(表示为FILE *
)之间的区别。
请考虑以下内容(通过其得出混淆):
fopen
的原型为:FILE *fopen(const char * restrict filename,const char * restrict mode)
。
fflush
的原型为int fflush (FILE *stream)
。 fflush
被描述为刷新文件缓冲区的函数。
setvbuf
的原型为int setvbuf (FILE * restrict stream,char * restrict buf,int mode,size_t size)
。当作者描述此功能时,他将第二个参数(buf
)称为缓冲区的地址 ...这大概与指向缓冲区的指针。
首先,据我了解(尤其是在fflush
和setvbuf
中选择了第一个参数的名称),流在语义上等效于指向文件的指针。因此,重要的是,流不是文件本身。流是文件的位置,至少是通过虚拟内存表示的(如果不正确,请更正)。
第二,当打开文件时,这相当于创建了一个相应的缓冲区(也在虚拟内存中表示)。
起初,由于fflush
的原型,给人的印象是,实际上,文件指针是 缓冲区。鉴于setvbuf
的原型(对于文件的指针和缓冲区的地址具有不同的参数),这显然是错误的。那么指向文件指向的指针到底是什么?
此外,如何获取与给定文件的缓冲区关联的地址(作者尚未显示函数,但返回与打开的文件关联的缓冲区的地址)。
任何见识都将不胜感激。干杯〜
解决方法
术语“流”和“文件”在C语言中有点混乱。文件是程序之外的东西,它可能是物理设备,磁盘上的文件或操作系统提供的其他东西。
从本质上讲,流是文件的接口。它主要是在C环境中构造的,方法是使用各种数据结构来记住有关所连接文件的信息,保存要写入文件或从文件读取的数据等等。
出于历史原因,流通过称为FILE
的数据结构类型进行管理。 FILE *
实际上是指向流的指针(或更确切地说,是指向用于控制流的数据的指针)。 FILE
中的数据包括文件位置指示符,指向与其关联的内部缓冲区的指针(不是您应该使用的任何指针),以及有关已发生的错误或是否已到达文件末尾的信息。如果名称是STREAM
而不是FILE
会更好,但是由于历史原因,我们坚持使用FILE
。
缓冲区通常是char
或unsigned char
的数组,用于保存在各种事物之间移动的数据,尽管可以存在其他类型的缓冲区。 buf
的{{1}}自变量用于提供要与流一起使用的缓冲区。这不是常用的例程。将数组传递给setvbuf
给予该数组到C库以用于该流。程序应停止将数组用于其他目的,直到关闭该流。这不同于您使用setvbuf
或getchar
之类的其他函数读取或写入字符的数组。