2

Summary

1)'#'用于在预处理期宏参数转换为字符串只在宏定义中有效编译器不知道'#'的存在

2)可以使用#+函数名,在调用时打印函数名

3)'##'用于在预处理期 拼接两个标识符只在宏定义中有效编译器不知道'##'的存在

4)可以使用'##'快速定义结构体、使用结构体,快速定义类等。

·#和##运算符分析

1、'#'

  • '#'运算符用于在预处理期宏参数转换为字符串(给参数加上双引号);
  • '#'的转换是在预处理期完成的,所以只在宏定义中有效编译器不知道'#'的转换作用
  • 用法:

    #define STRING(s) #s
    printf("%s\n", STRING(hello world));
    
    单步编译:gcc -E test.c -o test.i
    中间结果:printf("%s\n", "hello world");

可以使用#+函数名,在调用时把函数名打印出来

#define CALL(f, p) (printf("call function: %s\n", #f), f(p))

void func()
{
    printf("function output");
}

int main()
{
    CALL(f, 1);        // C语言中如果不写参数列表,则接受任意多参数
    return 0;
}

2、'##'

  • '##'运算符用于在预处理期粘连两个字符(拼接字符
  • '##'的拼接作用是在预处理期完成的,因此只在宏定义中有效编译器不知道'##'的拼接作用
  • 用法:

    #define CONNECT(a, b) a##b
    
    int CONNECR(a, 1);    // int a1;
    a1 = 2;

工程中可以用'##'快速定义结构体(定义不同的类等)

// 在C语言中使用结构体必须带上struct关键字,就可以用下面的宏封装下typedef,
// 然后就可以把struct当成一个类型来用

#define STRUCT(type) typedef strtuct __tag_##type type; \
                        struct __tag_##type
STRTUCT(Student)
{
    char* name;
    int id;
};

int main()
{
    Student s;
    s.name = "ss";
    s.id = 1;

    printf("name: %s, id: %d\n"), s.name, s.id);
    retrun 0;
}

本文总结自“狄泰软件学院”唐佐林老师《C语言进阶课程》。
如有错漏之处,恳请指正。


bryson
169 声望12 粉丝