What

以#开头的命令,称为预处理命令
预处理:
在编译之前就先处理的过程
需要放在函数之外,且一般在源文件的前面
预处理是由预处理程序完成的,系统自动调用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入编译
如:
宏定义 文件包含 条件编译等

Why

根据这个预处理特性就可以做很多事情了。

How

1.判断平台

windows和Linux中的延迟函数的头文件和函数名都不一样,就需要预处理的时候判断出平台,引入对应的头文件和使用对应的函数

  1. #if _WIN32 //预处理指令 先通过预处理程序 判断平台 如果是windows
  2. #include <windows.h>//就执行这个
  3. #elif __linux__ // 否则判断 如果是linux
  4. #include <unistd.h>//就执行这个
  5. #endif//结束预处理判断
  6. void main()
  7. {
  8. #if _WIN32
  9. Sleep(3000);//windows中延迟 是 Sleep 参数是毫秒
  10. #elif __linux__
  11. sleep(3);//linux 中 延迟 是 sleep 参数是秒
  12. #endif
  13. printf("hello world");
  14. getchar();
  15. }

2.宏定义

用一个标识符来表示一个字符串(宏所表示的字符串,可以是数字 表达式 if语句 函数等 这里的字符是字符序列,不等同于字符串数据类型)。预处理阶段,对程序中出现的宏名,预处理器都会用对应的宏定义的字符串替换,称为宏替换或宏展开。

该过程由**#define**预处理指令完成
通过#undef指令终止指定的宏定义的作用域

  1. void main()
  2. {
  3. int sum = 1 + N;
  4. printf("%d\n", sum);
  5. sum = M;
  6. printf("%d", sum);
  7. getchar();
  8. };
  9. #undef N//终止宏定义的作用域 N的作用域在这个预处理命令 上面
  10. void test()
  11. {
  12. // printf("%d",N); 这里就不能使用N了
  13. }

3.带参数的宏定义

似函数非函数。把传入的参数给到宏内容,一同替换。

#define MAX(a,b) (a>b)?a:b 形参和宏名不能有空格。宏内容可以使用形参。

  1. /*
  2. 在预处理阶段,把程序中出现MAX()的都替换成
  3. (a > b) ? a : b。其中a b是使用宏名时传递的参数。
  4. */
  5. #define MAX(a, b) (a > b) ? a : b
  6. void main()
  7. {
  8. int x = 1, y = 2;
  9. int rs = MAX(x, y);
  10. printf("%d",rs);
  11. getchar();
  12. }

注意:

  1. 带参宏定义不会为形参分配内存(因为这只是个名字,只是把程序中出现的宏名替换中宏内容而已),所以形参不用指明数据类型.
  2. 与函数的区别:

函数的形参是会分配内存的,相当于局部作用域变量
函数是在栈中执行的,每次执行完,所分配的内存空间都会被释放
而带参宏定义,只是把程序中出现的宏名 替换成宏内容,是不会改变参数的作用域的。