预处理:
系统自动自动调用预处理程序对程序中"#"号开头的预处理部分进行处理,处理完毕后可以进城源程序的编译阶段。
预定义:
一些预定义符号(常用于调试)
_FILE_
正在预编译的源文件名
_LINE_
当前行号(只有这个是整数常量,其他是字符串常量)
_FUNCTION_
当前所在函数名
_DATE_
当前日期
_TIME_
当前时间
宏定义:
无参
#define 标识符 字符串
在对源程序做编译时,先由预处理程序进行宏替换,用字符串替换标识符。
注意:
1、只是简单的替换,预处理对它不做任何检查,如果有错误,只能在替换后在编译时发现。
2、行末不加分号
3、宏定义的作用域包括从宏定义开始到源程序结束,如果要终止作用域,额可以用#undef
示例:
#define MUMU wangzhibin
fun1()
{
.....
.....
}
#undef MUMU
fun2()
{
.....
.....
}
- //MUMU这个宏定义只在fun1函数内生效,在fun2函数中无效
4、引号内的内容不进行宏替换
5、宏定义可以嵌套
带参
在调用中不仅要宏展开,而且要用实参去替换形参。
宏定义中的参数:形式参数 宏调用中的参数:实际参数
宏定义:#define
宏名(形参表) 字符串
宏调用:宏名(实参表)
示例:
#define M(y) y+3 //宏定义
int main()
{
int a=M(3);
//宏调用,M(3)被替换成3+3,即a=6printf("a=%d\n",a);
return 0;
}
PS:在一定情况下,可以用宏定义和宏调用代替函数定义和函数调用,因为宏的执行速度比函数的速度要快。
但要注意会宏可能带来的一些副作用,比如宏名和形参表之间不能有空格,形参要适当加括号。
总之,使用宏时,记住一点,只是替换,要考虑替换到源程序后来的影响,注意上下文。
条件编译:
形式1:
#ifdef 标识符
程序段1
#else
程序段2
#endif
如果标识符被#define语句定义过,则编译程序段1,否则编译程序段2。(#else可以没有)
形式2:
#ifndef 标识符
程序段1
#else
程序段2
#endif
如果标识符未被#define语句定义过,则编译程序段1,否则编译程序段2。(#else可以没有)
形式3:
#if
常量表达式
程序段1
#else
程序段2
#endif
如果常量表达式为真
,编译程序段1,否则编译程序段2。
(#else可以没有)