宏
C语言程序中广泛使用宏,通过关键字define来定义,宏是一种简单的字符串替换,可带参数。
- 宏中包含特殊符号:#、##、#@
- 可变参数宏如__VA_ARGS__
- 预定义宏如__FILE__、LINE
- 宏定义用do{}while(0)
1、使用特殊符号。使用#,预处理器会把这个参数转换为一个字符数组;使用##,预处理器会进行一个类似字符连接的操作;使用#@,预处理器会将参数转换为一个字符。
// 将s转化为字符数组
#define STR(s) #s
// 将参数连接起来
#define LINK(s) Test##s##demo
// 将参数转化为字符
#define CHAR(c) #@c
int main()
{
printf("#特殊符:%s\n", STR(123456));
printf("##特殊符:%s\n", LINK(123456));
printf("#@特殊符:%s\n", CHAR(1));
}
2、可变参数宏。
// __VA_ARGS__ 可变参数宏
#define PRT(...) printf(__VA_ARGS__)
int main()
{
PRT("%d\n", 1); //2个参数传给宏
PRT("%d %s\n", 1, "hello");//3个参数传给宏
}
3、预定义宏。ANSI标准说明了C中的预定义宏,一般用于日志输出。
int main()
{
printf("__LINE__:%d\n", __LINE__);//行号
printf("__FUNCTION__:%s\n", __FUNCTION__);//函数名
printf("__FILE__:%s\n", __FILE__);//文件名
printf("__DATE__:%s\n", __DATE__);//日期
printf("__TIME__:%s\n", __TIME__);//时间
}
4、do{}while(0)。使用do{}while(0)将要执行的逻辑包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能识别do{}while(0)这种无用的循环并进行优化,所以使用这种方法不会降低程序的性能。
#define fun2() do{printf("1");printf("2");}while(0)
int main()
{
fun2();
}
条件编译
一般情况下,源程序中所有的代码都会参加编译。但有时希望对一部分内容进行条件判断,符合条件的才进行编译,这就是“条件编译”。
//#define A
int main()
{
//条件编译1
#ifdef A
printf("定义了符号A\n");
#endif
//条件编译2
#ifdef A
printf("定义了符号A\n");
#else
printf("没有定义符号A\n");
#endif
//条件编译3
#ifndef A
printf("没有定义符号A\n");
#else
printf("定义了符号A\n");
#endif
//条件编译4
#if true
printf("条件为真\n");
#else
printf("条件为假\n");
#endif
//条件编译4
#if false
printf("第一种情况\n");
#elif true
printf("第二种情况\n");
#else
printf("其他情况\n");
#endif
//#error指令
#define B 2
#if B>3
#error B is larger then 3!
#endif
printf("%d, %s\n", __LINE__, __FILE__);
#line 123 "1.txt"
printf("%d, %s\n", __LINE__, __FILE__);
return 0;
}