井号和双井号在宏定义中的用法

井号和双井号在宏定义中的用法

Content #

使用“gcc -E”命令对以下程序进行预处理,并解释预处理的结果,以此来掌握井号和双井号在宏定义中的作用。

#include <stdio.h>

#define TYPE_Apple 1
#define TYPE_Pear  2

struct Fruit {
    int _type;
    char* _name;
};

#define DECLARE(x) \
struct Fruit x = {      \
    TYPE_##x,           \
    #x,                 \
};

DECLARE(Apple)
DECLARE(Pear)

int main() {
    printf("%d, %s\n", Apple._type, Apple._name);
    printf("%d, %s\n", Pear._type, Pear._name);
    return 0;
}

预处理的核心工作就是对宏定义进行展开,展开的时候主要是进行字符串的直接替换,尤其是对于宏函数,不能把它真的当成函数进行处理。

拼接的结果:

struct Fruit Apple = { 1, "Apple", };
struct Fruit Pear = { 2, "Pear", };

Viewpoint #

From #

大咖助阵|海纳:C 语言是如何编译执行的?(一)