getc()vs fgetc() – 主要区别是什么?

我到处看到“它几乎是相同的”,或类似的东西…

从GNU C编程教程 :

GNU C库中还有一个名为fgetc的函数。 除了getc通常作为一个macros函数实现并且高度优化之外,getc在大多数方面都是一样的,所以在大多数情况下是可取的。 (在从标准input读取的情况下,getc的速度与fgetc一样快,因为与计算机可以读取input的速度相比,人类input的速度较慢,但​​是当您从不是由人类交互式生成的数据stream读取时, fgetc可能会更好。)

其他的区别是什么? 我听说他们每个人都有一个不同的实现(其中一个可以用作macros),但是,他们在标准C库(或规范)中有什么不同(或不同)呢?

Advanced Programming in Unix EnvironmentAdvanced Programming in Unix Environment

getcfgetc的不同之处在于, getc可以被实现为一个macros,而fgetc不能被实现为一个macros。 这意味着三件事情:

  • getc的参数不应该是带有副作用的expression式。
  • 既然fgetc是保证是一个函数,我们可以把它的地址。 这允许我们将fgetc的地址作为parameter passing给另一个函数。
  • 调用fgetc的时间可能比调用getc时间要长,因为调用函数通常需要更多的时间。

似乎差异在99.9%的情况下是毫无意义的。

有一点可以有所作为 – 手册页上说, getc() may be implemented as a macro which evaluates stream more than once

这可能会导致一些(不是很有用)的情况下的奇怪行为,例如:

 FILE *my_files[10] = {...}, *f=&my_files[0]; for (i=0; i<10; i++) { int c = getc(f++); // Parameter to getc has side effects! } 

如果getc不止一次地评估f++ ,那么每次迭代都会超过一次。 相比之下, fgetc在这种情况下是安全的。

基本上是一样的(或者相似,不用打扰)。 你应该看看它们的实现: GNU libc和MUSL libc是免费的软件实现。 他们现在可以实现为内联函数(与macros一样快)。

我不会那么麻烦 在现实生活中,I / O主要受硬件约束(例如访问磁盘的时间)。