What
以#开头的命令,称为预处理命令
预处理:
在编译之前就先处理的过程
需要放在函数之外,且一般在源文件的前面
预处理是由预处理程序完成的,系统自动调用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入编译
如:
宏定义 文件包含 条件编译等
Why
How
1.判断平台
windows和Linux中的延迟函数的头文件和函数名都不一样,就需要预处理的时候判断出平台,引入对应的头文件和使用对应的函数
#if _WIN32 //预处理指令 先通过预处理程序 判断平台 如果是windows
#include <windows.h>//就执行这个
#elif __linux__ // 否则判断 如果是linux
#include <unistd.h>//就执行这个
#endif//结束预处理判断
void main()
{
#if _WIN32
Sleep(3000);//windows中延迟 是 Sleep 参数是毫秒
#elif __linux__
sleep(3);//linux 中 延迟 是 sleep 参数是秒
#endif
printf("hello world");
getchar();
}
2.宏定义
用一个标识符来表示一个字符串(宏所表示的字符串,可以是数字 表达式 if语句 函数等 这里的字符是字符序列,不等同于字符串数据类型)。预处理阶段,对程序中出现的宏名,预处理器都会用对应的宏定义的字符串替换,称为宏替换或宏展开。
该过程由**#define**
预处理指令完成
通过#undef
指令终止指定的宏定义的作用域
void main()
{
int sum = 1 + N;
printf("%d\n", sum);
sum = M;
printf("%d", sum);
getchar();
};
#undef N//终止宏定义的作用域 N的作用域在这个预处理命令 上面
void test()
{
// printf("%d",N); 这里就不能使用N了
}
3.带参数的宏定义
似函数非函数。把传入的参数给到宏内容,一同替换。
#define MAX(a,b) (a>b)?a:b
形参和宏名不能有空格。宏内容可以使用形参。
/*
在预处理阶段,把程序中出现MAX()的都替换成
(a > b) ? a : b。其中a b是使用宏名时传递的参数。
*/
#define MAX(a, b) (a > b) ? a : b
void main()
{
int x = 1, y = 2;
int rs = MAX(x, y);
printf("%d",rs);
getchar();
}
注意:
- 带参宏定义不会为形参分配内存(因为这只是个名字,只是把程序中出现的宏名替换中宏内容而已),所以形参不用指明数据类型.
- 与函数的区别:
函数的形参是会分配内存的,相当于局部作用域变量
函数是在栈中执行的,每次执行完,所分配的内存空间都会被释放
而带参宏定义,只是把程序中出现的宏名 替换成宏内容,是不会改变参数的作用域的。