C语言 getchar() 和 putchar() 宏如何?



根据我对 C 中宏的理解,它们是预定义的常量,将在整个程序中使用它们的常量值,因此我们继续定义它们以避免进一步的复杂性并使代码更具可读性,因此阅读它的人将了解什么应该保持不变,什么不应该。

我在这里和那里读到(C programming A Modern Approach,K.N King(,我们可以将这两个函数定义为宏函数。

由于我对 C 有点陌生,所以我无法理解如何将这两个定义为宏?

有两种类型的宏:简单替换宏和类似函数的宏。

替换宏将符号的一个实例替换为另一个实例。 例如:

#define LEN 10
char str[LEN];

预处理后,这将变为:

char str[10];

类似函数的宏可以采用参数,这些参数可以插入到被替换的任何内容中:

#define MAX(a,b) ((a) > (b) ? (a) : (b))
int x = MAX(2,3);

预处理后:

int x = ((2) > (3) ? (2) : (3));

getcharputchar的情况下,它们可以定义如下:

#define getchar() getc(stdin)
#define putchar(c) putc(c, stdout)

基本上有三种类型的预处理器宏:

  1. 简单定义,没有任何值。例如

    #define THIS_IS_A_MACRO
    

    这种宏用于条件编译

  2. 符号常量。例如

    #define SOME_SYMBOLIC_CONSTANT  123
    

    这些宏就是您正在考虑的。

  3. 类似函数的宏。敌人示例

    #define SOME_MACRO(a_macro_argument)  printf("Macro invoked with argument %dn", a_macro_argument)
    

    这种宏的使用方式与函数非常相似,但在编译器解析器看到代码之前,在源代码中被预处理器替换,宏参数替换为它们的实际值。

让我们来看看类似函数的宏以及预处理器将如何扩展它:

SOME_MACRO(123);

以上将被替换,例如

printf("Macro invoked with argument %dn", 123);

完全取决于实现。它们也可以发挥作用。

标准不要求任何关于实现类型的明确要求。但是你可以在这里检查它指向Any function declared in a header may be additionally implemented....正如 Eugene.Sh 所指出的

更清楚地说,库中可能有一个函数,也可以是一个宏(对于getchar(。传统上,getchar()的宏是#define getchar() getc(stdin)的,getc()也可能是宏。

标准说getc 函数等效于 fgetc,除了如果它作为宏实现,它可能会多次评估流,所以参数永远不应该是有副作用的表达式

现在它归结为fgetc在这种情况下,我们知道它保证是一个函数。线程安全使它更有可能成为一种功能。

因此,在C++中,永远不要将 getchar 和 putchar 定义为类的成员函数。如果它们在 stdio.h 文件中被定义为宏,编译器会抛出各种奇怪的错误。

#include <stdio.h>
class My_IO_Device
{
int putchar (int c); // seemingly innocent
};

我不知道<cstdio>是否保证将它们作为函数实现。

最新更新