1、宏定义
(1)、宏定义语法:
1)、#define 宏名称 (宏的展开)。
宏定义的名称使用大写,最后末尾不加分号。宏定义在预编译阶段替换(作用范围定义到文件末尾)
(不带参数宏)例如:#define PI(使用大写方便区别) 3.1415926(没有分号)
这样定义宏的好处是后续的3.1415926会被PI代替,并且这个操作实在头文件展开也就是与编译阶段执行,只要修改宏其他地方都会修改。
2)、终止宏定义#undef PI(一般不用终止宏定义,想要改变宏可以直接修改宏的名称)。
3)、带参宏:#define S(a,b) a*b(没有分号),在预处理阶段会将S(a,b)替换成a*b,并且宏定义阶段是没有参数的。
4)、定义宏的优缺点是浪费了空间但是节省了时间。
2、选择性编译:
1)、选择性编译也是预处理的一部分,在预处理阶段先执行。
2)、代码部分:#ifdef AAA //(如果上面定义了AAA则执行代码块1)
代码块1
#elif BBB //(如果上面定义了BBB则执行代码块2)
代码块2
#endif //(作为一个结束,无论执行哪一个都得有endif)
3)、为了防止头文件重复定义,导致代码编译冗余:
#ifndef AAA
代码段1
#elif
代码段2
#endif
4)、例如防止fun.h重复编译代码:
#ifndef _FUN_H_ //如果没定义_FUN_H_则执行。
#define_FUN_H_ //定义_FUN_H_。
代码块(声明)
#endif //保证了只能编译一次,
常用于多文件编程的.h文件中
5)、#if 表达式1
程序1
#else
程序2
#endif
(类似于if else语句,都是预处理阶段执行)
3、宏定义的#和##操作符:
(1)、#操作符(字符串化操作符): # 可以将宏参数转换为字符串常量。当在宏定义中使用 #
将参数包围起来时,参数将被视为字符串常量,并在预处理阶段进行替换。这对于将参数值作为字符串打印或传递给其他函数非常有用(简单来说将参数变成字符串常量方便传递)。
(2)、代码:
#define PRINT_VALUE(x) printf("The value of " #x " is %d\n", x)
int main()
{
int num = 10;
PRINT_VALUE(num);
return 0;
}
将num =10视为字符串操作数,浪费了空间但是节省空间,在定义宏的时候防止出现太多#,导致代码可读性太差。
(3)、##操作符: ##可以将两个片段连接在一起,产生一个新的标识符。这对于将多个标识符组合成一个复杂的标识符非常有用(简单来说变量太多可以使用##结合)。
(4)、代码:
#define c(a,b) a##b
int main()
{
int xy = 100;
printf("%d\n",c(a,b));
return 0;
}
a##b 宏定义展开把xy作为一个整体。