我试图找出getc和fgetc之间的区别。当时我看到了这样一种说法:
getc和fgetc之间的区别是getc可以实现为宏,而fgetc不能实现为宏。
那么,getc真的是一个函数还是一个宏?如果是宏,则调用其他函数。那么,getc是用C实现的吗?
发布于 2015-09-23 15:10:03
getc和fgetc之间的区别是getc可以实现为宏,而fgetc不能实现为宏。
那是不正确的。
除了少数例外,任何C标准库函数都可以另外作为宏实现,但对于如何编写该宏有一些限制(这样宏仍然可以像函数一样使用)。
引用N1570第7.1.4节:
在报头中声明的任何函数都可以另外实现为在标头中定义的类似函数的宏.对作为宏实现的库函数的任何调用都应扩展到计算每个参数精确一次的代码,必要时完全由括号保护,因此使用任意表达式作为参数通常是安全的。
getc的特别之处在于,其中一个限制可能会被放松(7.21.7.5):
getc函数与fgetc,等价,只是如果它是作为宏实现的,它可能会多次计算stream,因此参数不应该是一个具有副作用的表达式。
fgetc和getc的声明如下:
int fgetc(FILE *stream);
int getc(FILE *stream);stream参数(例如,在fgetc(stdin)或getc(file)这样的调用中,几乎总是一个没有副作用的表达式,但规则仍然禁止将fgetc定义为一个宏,该宏多次计算其参数,以防程序员编写类似fgetc(file_list[i++])的东西。对于getc来说,规则是宽松的,这样就可以将其定义为宏(在某些情况下,宏可以大大提高效率),同时可能破坏类似getc(file_list[i++])之类的东西。
在fgetc的例子中,将其作为宏而不是函数来实现可能没有多大的优势。关键是标准明确地允许这样做。
那么,
getc是用C实现的吗?
也许吧。不需要在C中实现任何C库函数,有些函数可以用汇编程序实现,或者用任何其他语言实现--或者它们可能是编译器的本质。通常,大多数或所有C标准库函数都是用C实现的,但标准只指定它们的工作方式,而不是它们的编写方式。
发布于 2015-09-23 14:48:36
getc是C99标准7.21.7.5节所述的函数,可以或不作为宏实现:
getc函数与fgetc等价,只不过如果它是作为宏实现的,它可能会多次计算stream,因此参数不应该是一个具有副作用的表达式。
对于有副作用的参数,它不能正确工作。例如--
int c = getc(*fpp++);https://stackoverflow.com/questions/32742430
复制相似问题