发布时间:2023-04-04 18:00
目录
1、条件编译
1.1 条件编译如何使用?
1.2 用 #if 模拟 #ifdef
1.3 为何要有条件编译?
2、文件包含
2.1 #include 究竟干了什么?
2.2 防止头文件重复包含的条件编译是如何做到的?
3、选学内容
3.1 #error 预处理
3.2 #line 预处理
3.3 #pragma 预处理
3.3.1 #pragma message
3.3.2 #pragma once
3.3.3 #pragma warning
3.3.4 #pragma pack
3.4 # 和 ##
C语言提供的条件编译的功能可以让我们按照不同的条件去编译不同的程序部分,从而产生不同目标代码文件。
第一种形式:
#ifdef 标识符
程序段1
#else
程序段2
#endif
它的功能是,如果标识符已经被 #define 定义了,则只会对程序段1进行编译,不会对程序段2进行编译,如果没有被定义则反之,如果我们不需要程序段2,也可以省去 #else 和他对应的程序段。
第二种形式:
#ifndef 标识符
程序段1
#else
程序段2
#endif
第二种形式与第一种形式的区别是将 ifdef 改为 ifndef,它的功能是,如果标识符没有被 #dfine 定义,则对程序段1进行编译,不会对程序段2进行编译,如果被定义了则反之, 如果我们不需要程序段2,也可以省去 #else 和他对应的程序段。
第三种形式:
#if 常量表达式
程序段1
#else
程序段2
#endif
第三种形式的功能是:如果常量表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译,因此可以使程序在不同条件下,完成不同的功能。
至于里面还可以添加 #elif 命令,意义与 else if 相同,形成一个 if else 阶梯状语句,可进行多种编译选择。
注意:如果定义空宏则会报错,因为 #if 后面必须要更常量表达式!
此代码的意思是,如果 PRINT 宏被定义了,则执行第一个打印函数,否则执行第二个打印函数,同时我们也可以模拟 #ifndef,只需前面加个逻辑非就可以 ' ! ',例如:#if !defined(PRINT)
就这样完了吗?其实并没有,在更复杂的项目中,往往会出现两个或多个宏需要同时定义才能满足需求,我举一个很简单的例子,如果我定义了 C 宏和 CPP 宏,我才可以编译所对应的代码:
如上代码就需要两个宏都被定义才能编译下面的程序段,相信学习过逻辑与的小伙伴应该很容易理解吧,那么我们如果需要两个都未定义才能编译下面的程序段呢?如何写?
两个都未定义才编译: #if !(defined(C) && defined(CPP)) 加个逻辑非就可以 ' ! '
至于最后用不用大括号给括起来,我的建议是括起来,这样我们阅读代码会更直观!
既然出现了逻辑与,是不是也可以出现逻辑或呢?当然是可以的,但是这里我就不一一演示了,感兴趣的可以下来自己去尝试一下。
条件编译支持嵌套:
这里其实和我们平常用的 if 嵌套式是似的,也很容易理解,这里我们就不细说,有一点要注意的就是,条件编译每个 #if 都需要有对应的 #endif 来结束
我们先对我们上面2小节的内容做一个总结:条件编译本质上是让编译器对代码进行裁剪!
本质认识:条件编译,其实就是编译器根据实际情况,对代码进行裁剪,而这里 “实际情况” ,取决于代码平台,代码本身的业务逻辑。
- 可以只保留当前最需要的代码逻辑,其他去掉,可以减少生成代码的大小
- 可以写出跨平台的代码,让一个具体业务,在不同平台编译的时候,可以有同样的表现