C语言之预处理器

预处理器在源代码编译前对其进行一些文本性质的操作, 主要任务包括删除注释, 插入被 #include 指令包含的文件的内容, 定义和替换由 #define 指令定义的符号以及确定代码的部分内容是否应该根据一些条件编译指令进行编译.

  • #define指令
    #define 指令主要有两种用法:
    • 定义常量: #define name stuff
      当源代码中出现 name 符号时都会被原封不动的替换为 stuff.
    • 宏: #define name(parameter1, parameter2, ...) stuff
      当源代码中出现 name(parameter1, parameter2, …) 时都会被替换为 stuff, 并且 stuff 中出现的 parameter 符号都被替换为括号内的值.
      比如:
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 MAX(2, 4); // 等价与((2) > (4) ? (2) : (b)) 

使用 #define 指令有以下几点需要注意:
(1) 不要在定义或宏的最后加 ; 来表示语句的结束.
(2) 在宏定义时为每一个宏参数以及 stuff 的最外围加上括号.
(3) #define 内部可以嵌套 #define, 但是不能递归嵌套.
(4) 当宏参数在宏定义中出现次数超过一次时要格外注意每次出现是宏参数的值有没有发生潜在的变化.
(4) #define 的名字统一要大写.

  • #undef 指令
    #undef 指令用于解除 #define 指令定义的符号或宏.
#define PI 3.1415 // 定义PI
#undef PI // 使PI定义失效
  • #include 指令
    #include 用于将某个文件包含到当前文件. 主要用法有三种:
#include  // 到系统目录搜索headfile.h
#include "headfile.h" // 先到当前工作目录搜索headfile.h, 未找到的话再去系统目录
#include "/use/test/headfile.h" // 直接去指定的目录搜索headfile.h
  • 条件编译指令: #ifdef #ifndef #else #elif #endif
    • #ifdef 表示如果已经定义了 #ifdef 后的符号, 则执行 #ifdef 后的命令语句直到遇到 #else#endif. 注意: #ifdef name 等价与 #if defined(name)
    • #ifndef 表示如果没有定义了 #ifndef 后的符号, 则执行 #ifndef 后的命令语句直到遇到 #else#endif. 注意: #ifndef name 等价与 #if !defined(name)
    • #else #elif#endif 用于组合使用.
      常用的结构有:
// 组合1
#ifdef name // 等价与 #if define(name)
...
#else
...
#endif

// 组合2
#ifdef name
...
#elif
...
#else
...
#endif

// 组合3
#ifndef name // 等价与 #if !define(name)
...
#else
...
#endif

// 组合4
#ifndef name
...
#endif
  • #error 指令
    #error 用于使预处理器发出一条错误信息, 比如:
#define PI 3.1415
#ifndef PI
    #error Not define PI
#endif

当未定义PI时, 预处理器会发出Not define PI信息, 并停止预处理.

  • #line 指令
    #line 用于重置当前行号和文件名.
#line 50 // 重置当前行号为50
#line 100 "test.c" // 重置当前文件名为test.c
  • # 运算符
    # 用于将字符串中的参数名视为宏参数. 比如:
// 字符串中参数名a被视为字符
#define PRINTSQUARE(a) printf("The square of a is: %d\n", ((a) * (a)))
PRINTSQUARE(3); // 输出:The square of a is: 9

// 字符串中参数名a被视为宏参数
#define PRINTSQUARE(a) printf("The square of "#a" is: %d\n", ((a) * (a)))
PRINTSQUARE(3); // 输出:The square of 3 is: 9
  • ## 运算符
    ## 用于将两个符号合成一个符号. 比如:
#define XNAME(n) x##n
int XNAME(1) = 0; // 等价于: int x1 = 0;
int XNAME(2) = 1; // 等价于: int x2 = 1;
  • \ 连接符
    \ 用于连接多行预处理语句. 比如
 #define MAX(a, b) ((a) > (b) ? \
                   (a) : (b))
  • 预定义宏
    • __DATE__ 预定义器处理时的日期
    • __FILE__ 当前源代码文件名
    • __LINE__ 当前行号
    • __TIME__ 预定义器处理的时间
    • __STDC__ 如果编译器遵循ANSIC, 其值为1, 否则为定义

你可能感兴趣的:(C语言)