根据我对 C 中宏的理解,它们是预定义的常量,将在整个程序中以其常量值使用,因此我们继续定义它们以避免进一步的复杂性并使代码更具可读性,因此阅读它的人会明白什么应该保持不变,什么不是。
我在这里和那里读过(C 编程一种现代方法,KN King),我们可以将这两个函数定义为宏。
由于我对 C 有点陌生,所以我无法理解如何将这两个定义为宏?
根据我对 C 中宏的理解,它们是预定义的常量,将在整个程序中以其常量值使用,因此我们继续定义它们以避免进一步的复杂性并使代码更具可读性,因此阅读它的人会明白什么应该保持不变,什么不是。
我在这里和那里读过(C 编程一种现代方法,KN 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));
在 和 的情况下getchar
,putchar
它们可以定义如下:
#define getchar() getc(stdin)
#define putchar(c) putc(c, stdout)
完全取决于实施。它们也可以起作用。
标准不要求任何明确的实现类型。但是你可以在这里查看它的点Any function declared in a header may be additionally implemented...
。正如 Eugene.Sh 所指出的
更清楚地说,库中可能有一个函数,也可以是一个宏(for getchar
)。经典地,宏getchar()
将是#define getchar() getc(stdin)
,也getc()
可能是宏。
标准说getc 函数等价于 fgetc,只是如果它被实现为宏,它可能会多次计算流,因此参数永远不应该是具有副作用的表达式。
现在归结为fgetc
在这种情况下我们知道它保证是一个函数。线程安全使它更有可能成为一个函数。
基本上有三种类型的预处理器宏:
简单定义,没有任何价值。例如
#define THIS_IS_A_MACRO
这种宏用于条件编译。
符号常数。例如
#define SOME_SYMBOLIC_CONSTANT 123
这些宏就是你所想的。
类似函数的宏。敌人的例子
#define SOME_MACRO(a_macro_argument) printf("Macro invoked with argument %d\n", a_macro_argument)
这种宏的使用与函数非常相似,但在编译器解析器看到代码之前由源代码中的预处理器替换,宏参数替换为它们的实际值。
让我们来看看类似函数的宏以及预处理器将如何扩展它:
SOME_MACRO(123);
以上将被替换为
printf("Macro invoked with argument %d\n", 123);