【C语言底层】预处理 超详解

目录

         前言:

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. 其他预处理指令



前言:
预处理指令 都是在 程序 的预处理阶段 执行完毕,在 .i 后缀预处理文件 中 可以发现预处理指令的处理结果

正文开始

1. 预定义符号

C语言设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的。

__FILE__ //进行编译的源文件  
__LINE__ //文件当前的行号  
__DATE__ //文件被编译的日期  
__TIME__ //文件被编译的时间  
__STDC__ //如果编译器遵循ANSI C,其值为 1 ,否则未定义:如在VS编译器中使用 会报错:说明 VS不遵循ANSI C标准

举个例子:

printf("file:%s line:%d\n", __FILE__, __LINE__);

【C语言底层】预处理 超详解_第1张图片

2. #define定义常量

基本语法:
#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__ )
【C语言底层】预处理 超详解_第2张图片

思考:在定义定义标识符的时候,要不要在最后加上 分号: ? 比如:

#define MAX 1000;
#define MAX 1000

建议不要加上 ; ,这样容易导致问题。 比如下面的场景:

if (condition)
   max = MAX;     (替换后 max = 1000;;   一个分逗号 算做一个语句)
 else
   max = 0;

       如果是加了分号的情况,等替换后,if 和 else 之间就是 2 条语句,而没有大括号的时候,if后边只能有一条语句。这里会出现语法错误。

3. #define定义宏

#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; 
 }

【C语言底层】预处理 超详解_第3张图片

警告 这个宏存在一个问题: 观察下面的代码段:

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)

你可能感兴趣的:(windows,c语言,visual,studio,学习)