目录
前言:
1. 预定义符号
2. #define定义常量
3. #define定义宏
4. 带有副作用的宏参数
5. 宏替换的规则
6. 宏函数的对比
7. #和##
7.1 #运算符
7.2 ##运算符
8. 命名约定
9. #undef
10. 命令行定义
11. 条件编译
12. 头文件的包含
12.1 头文件被包含的方式:
12.1.1 本地文件包含
12.1.2 库文件包含
12.2 嵌套文件包含
13. 其他预处理指令
正文开始
__FILE__ //进行编译的源文件
__LINE__ //文件当前的行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为 1 ,否则未定义:如在VS编译器中使用 会报错:说明 VS不遵循ANSI C标准
举个例子:
printf("file:%s line:%d\n", __FILE__, __LINE__);
#define name stuff
1、 定义 数值
#define MAX 1000
2、为关键字重命名:为 register这个关键字,创建一个简短的名字
#define reg register
3、 代替 一段代码直接 : define定义一个 符号 代替 一段代码
#define DEBUG_PRINT printf(" file:%s\n line:%d\n date:%s\n time:%s\n" ,__FILE__,__LINE__ , __DATE__,__TIME__ )
4、(代码若过长可以使用 续行符: 一个 斜杠 + 换行本质是将 换行符“\n”变成 “\\n” 使换行符失效,不再换行,则代码就判定为同一行)
#define DEBUG_PRINT printf(" file:%s\n \
line:%d\n date:%s\n time:%s\n" ,\
__FILE__,__LINE__ , \
__DATE__,__TIME__ )
思考:在定义定义标识符的时候,要不要在最后加上 分号: ; ? 比如:
#define MAX 1000;
#define MAX 1000
建议不要加上 ; ,这样容易导致问题。 比如下面的场景:
if (condition)
max = MAX; (替换后 max = 1000;; 一个分逗号 算做一个语句)
else
max = 0;
如果是加了分号的情况,等替换后,if 和 else 之间就是 2 条语句,而没有大括号的时候,if后边只能有一条语句。这里会出现语法错误。
#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。 下面是宏的申明方式:
#define name( parament-list ) stuff
其中的 parament - list 是一个由逗号隔开的符号表,它们可能出现在stuff中。 注意: 参数列表的左括号必须与name紧邻,如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。
举例:
1 #define SQUARE( x ) x * x
这个宏接收一个参数x.如果在上述声明之后,你把SQUARE( 5 );
置于程序中,预处理器就会用 下面这个表达式替换上面的表达式:5 * 5
#include
#define SQUARE(x) x*x
int main()
{
int a = 5;
printf("%d\n", Square(a)); // 在预处理后的 程序中 这一句话变成 printf("%d\n", a * a);
return 0;
}
警告: 这个宏存在一个问题: 观察下面的代码段:
int a = 5;
printf("%d\n" ,SQUARE( a + 1 ) );
乍一看,你可能觉得这段代码将打印 36 ,事实上它将打印 11 ,为什么呢? 替换文本时,参数 x 被替换成 a+1, 所以这条语句实际上变成了
printf ( "%d\n",a + 1 * a + 1 );
#define SQUARE(x) (x) * (x)