我试图找出getc
和fgetc
之间的区别。那时我看到了一个声明:
getc和fgetc之间的区别在于getc可以实现为宏,而fgetc不能实现为宏。
那么,getc
真的是一个函数还是一个宏?如果它是宏,它会调用其他一些功能。那么,getc
是否在C中实现?
答案 0 :(得分:6)
getc和fgetc之间的区别在于getc可以实现为宏,而fgetc不能实现为宏。
这是不正确的。
除了少数例外,任何 C标准库函数可能还可以作为宏实现,但是对于如何编写宏有一些限制(这样宏仍然可以用作如果它是一个功能)。
引用N1570第7.1.4节:
标头中声明的任何函数都可以另外实现为a 标题中定义的类似函数的宏,[...]任何a的调用 作为宏实现的库函数应扩展为代码 它只准确地评估它的每个参数一次,完全受到 必要时用括号括起来,所以通常可以安全使用 表达式作为参数。
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
的情况下,将它实现为宏而不仅仅是作为一个函数可能没有多大优势。重点是标准明确允许它。
那么,是否在C中实现
getc
?
也许。 任何 C库函数都不需要在C中实现。某些函数可能以汇编程序或任何其他语言实现 - 或者它们可能是编译器内在函数。通常,大多数或所有C标准库函数都在中实现,但标准只规定了它们的工作方式,而不是它们的编写方式。
答案 1 :(得分:1)
getc
是C99 standard section 7.21.7.5
中所述的功能,可能会也可能不会被macro
实施。
7.21.7.5 -
2 getc函数等效于fgetc,除非它是作为宏实现的,它可能会多次评估流,因此参数永远不应该是带有副作用的表达式。
对于具有副作用的参数(流参数)值,它无法正常工作。例如 -
int c=getc(*f++);