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

时间:2013-08-28 06:40:43

标签: c fgetc getc

无处不在,我看到“它实际上是相同的”,或类似的......

来自The GNU C Programming Tutorial

  

GNU C库中还有另一个名为fgetc的函数。它在大多数方面与getc相同,除了getc通常作为宏函数实现并且高度优化,因此在大多数情况下是优选的。 (在您从标准输入读取的情况下,getc与fgetc一样快,因为与计算机读取输入的速度相比,人类输入速度较慢,但​​是当您从不是由人工交互生成的流中读取时, fgetc可能更好。)

其他差异是什么?我听说他们每个都有不同的实现(一个可以用作宏),但是,是什么让它们与标准C库(或规范)中的它们完全不同(或不同)?

3 个答案:

答案 0 :(得分:40)

来自Advanced Programming in Unix Environment

  

...

     

getcfgetc之间的区别在于getc可以   实现为宏,而fgetc不能实现为   宏。这意味着三件事:

     
      
  • getc的参数不应该是带有副作用的表达式。
  •   
  • 由于保证fgetc是一个函数,我们可以获取其地址。这允许我们将fgetc的地址作为参数传递   到另一个功能。
  •   
  • 对fgetc的调用可能比调用getc的时间更长,因为调用函数通常需要更长的时间。
  •   
     

...

答案 1 :(得分:16)

似乎差异在99.9%的案例中毫无意义。

可能有所作为的一点 - The man pagegetc() 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++,则每次迭代将超过f次。相比之下,fgetc在这种情况下是安全的。

答案 2 :(得分:2)

基本上相同(或类似不足以打扰)。您应该查看它们的实现:GNU libcMUSL libc是免费软件实现。现在它们可以实现为内联函数(与宏一样快)。

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