Summary
1)'#'用于在预处理期
将宏参数转换为字符串
;只在宏定义中无效
,编译器不晓得'#'
的存在
2)能够应用#+函数名
,在调用时打印函数名
3)'##'用于在预处理期 拼接两个标识符
;只在宏定义中无效
,编译器不晓得'##'
的存在
4)能够应用'##'疾速定义构造体
、应用构造体,疾速定义类
等。
·#和##运算符剖析
1、'#'
- '#'运算符用于在
预处理期
将宏参数转换为字符串
(给参数加上双引号
); - '#'的转换是在预处理期实现的,所以
只在宏定义中无效
;编译器不晓得'#'
的转换作用 用法:
#define STRING(s) #sprintf("%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##bint CONNECR(a, 1); // int a1;a1 = 2;
工程中能够用'##'疾速定义构造体
(定义不同的类
等)
// 在C语言中应用构造体必须带上struct关键字,就能够用上面的宏封装下typedef,// 而后就能够把struct当成一个类型来用#define STRUCT(type) typedef strtuct __tag_##type type; \ struct __tag_##typeSTRTUCT(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语言进阶课程》。
如有错漏之处,恳请斧正。