C语言 getc() 与 fgetc() - 主要区别是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18480982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
getc() vs fgetc() - What are the major differences?
提问by Joe DF
Everywhere I see "it is practically identical", or something similar...
我到处都看到“它实际上是相同的”,或者类似的东西......
From The GNU C Programming Tutorial:
来自GNU C 编程教程:
There is another function in the GNU C Library called fgetc. It is identical to getc in most respects, except that getc is usually implemented as a macro function and is highly optimised, so is preferable in most situations. (In situations where you are reading from standard input, getc is about as fast as fgetc, since humans type slowly compared to how fast computers can read their input, but when you are reading from a stream that is not interactively produced by a human, fgetc is probably better.)
GNU C 库中有另一个函数,称为 fgetc。它在大多数方面与 getc 相同,除了 getc 通常作为宏函数实现并且经过高度优化,因此在大多数情况下更可取。(在您从标准输入读取的情况下,getc 大约与 fgetc 一样快,因为与计算机读取输入的速度相比,人类输入的速度较慢,但是当您从非人类交互产生的流中读取时, fgetc 可能更好。)
What are the other differences? I have heard that they each have a different implementation (and one can be used as a macro) but, what makes them soo different (or different enough) for them to be both in the Standard C library (or specification)?
其他区别是什么?我听说它们每个都有不同的实现(并且一个可以用作宏)但是,是什么让它们如此不同(或足够不同)以至于它们都在标准 C 库(或规范)中?
采纳答案by mohit
From the Advanced Programming in Unix Environment:
来自Advanced Programming in Unix Environment:
...
The difference between
getcandfgetcis thatgetccan be implemented as a macro, whereasfgetccannot be implemented as a macro. This means three things:
- The argument to
getcshould not be an expression with side effects.- Since
fgetcis guaranteed to be a function, we can take its address. This allows us to pass the address offgetcas an argument to another function.- Calls to fgetc probably take longer than calls to
getc, as it usually takes more time to call a function....
...
getc和之间的区别fgetc是getc可以作为宏来实现,而fgetc不能作为宏来实现。这意味着三件事:
- 的参数
getc不应是具有副作用的表达式。- 由于
fgetc保证是一个函数,我们可以取它的地址。这允许我们将 的地址fgetc作为参数传递给另一个函数。- 调用 fgetc 可能比调用 花费更长的时间
getc,因为调用函数通常需要更多时间。...
回答by ugoren
Seems like the differences are, in 99.9% of the cases, meaningless.
在 99.9% 的情况下,这些差异似乎毫无意义。
One point which may make a difference - The man pagesays getc() may be implemented as a macro which evaluates stream more than once.
一点可能会有所作为 -手册页说getc() may be implemented as a macro which evaluates stream more than once。
It could lead to strange behavior in some (not very useful) cases, e.g.:
在某些(不是很有用)的情况下,它可能会导致奇怪的行为,例如:
FILE *my_files[10] = {...}, *f=&my_files[0];
for (i=0; i<10; i++) {
int c = getc(f++); // Parameter to getc has side effects!
}
If getcevaluates f++more than once, it will advance fmore than once per iteration. In comparison, fgetcis safe in such situations.
如果getc求值f++不止一次,则f每次迭代将推进不止一次。相比之下,fgetc在这种情况下是安全的。
回答by Basile Starynkevitch
There are essentially the same (or similar enough to not bother). You should look at their implementation: GNU libcand MUSL libcare free software implementations. And they now could be implemented as inline functions (which are as fast as macros).
本质上是相同的(或相似到足以不打扰)。您应该查看它们的实现:GNU libc和MUSL libc是自由软件实现。它们现在可以实现为内联函数(与宏一样快)。
And I won't bother that much. In real life, I/O is mostly constrained by hardware (e.g. the time to access the disk).
而且我不会打扰那么多。在现实生活中,I/O 主要受硬件限制(例如访问磁盘的时间)。

