问题
In Chapter 22 of "C Programming: A Modern Approach", the basics of the <stdio.h>
header are explained.
One detail that has me a little confused is the difference between a pointer to a buffer and a pointer to a file (denoted as FILE *
).
Consider the following (through which the confusion is derived):
fopen
is prototyped as: FILE *fopen(const char * restrict filename, const char * restrict mode)
.
fflush
is prototyped as int fflush (FILE *stream)
. fflush
is described as a function the flushes a file's buffer.
setvbuf
is prototyped as int setvbuf (FILE * restrict stream, char * restrict buf, int mode, size_t size)
. When the author describes this function, he refers to the second parameter (buf
) as the address of the buffer...which presumably is the same idea as pointer to buffer.
Firstly, from what I understand (especially given the name choice of the first parameter in fflush
and setvbuf
), a stream is semantically equivalent to a pointer to a file. Importantly, therefore, a stream IS NOT the file itself. A stream is the location of the file, at least as is represented through virtual memory (please correct if this is off base).
Secondly, when one opens a file, this amounts to creating a corresponding buffer (that is also represented in virtual memory).
At first, because of fflush
's prototype, I was under the impression that the pointer to a file was in practice the pointer to a buffer; this is clearly wrong given the prototype of setvbuf
(which has distinct parameters for the pointer to a file and the address of the buffer). So what exactly is the pointer to file pointing to?
Further, how does one acquire the address associated with a given file's buffer (the author has not shown a function yet the returns the address of a buffer associated with the file that was opened).
Any insight is greatly appreciated. Cheers~
回答1:
The terms “stream” and “file” are a bit muddled in C. A file is something outside the program, and it may be a physical device, a file on disk, or some other thing provided by the operating system.
A stream is, roughly, an interface to a file. It is largely constructed in the C environment by using various data structures to remember information about the file it is connected to, to hold data being written to or read from the file, and so on.
For historic reasons, a stream is managed through a data structure type called FILE
. A FILE *
is actually a pointer to a stream (or, more technically, a pointer to the data used to control a stream). The data in a FILE
includes a file position indicator, a pointer to its associated internal buffer (not anything you should use), and information about errors that have occurred or whether the end of the file has been reached. It would be better if the name were STREAM
instead of FILE
, but we are stuck with FILE
due to history.
A buffer is often an array of char
or unsigned char
used to hold data being moved between various things, although there can be buffers of other types. The buf
argument to setvbuf
is used to provide a buffer to be used with the stream. This is not a commonly used routine. Passing an array to setvbuf
gives the array to the C library to use for that stream. The program should stop using the array for any other purpose until it closes that stream. This is different from an array you use to read or write characters using the other functions like getchar
or fputc
.
来源:https://stackoverflow.com/questions/64094346/what-is-the-difference-between-a-pointer-to-a-buffer-and-a-pointer-to-a-file