关于预编译指令

在看源码时经常会遇到很多“#”后面跟着的指令,而且在写代码的时候也会使用“#”来引入头文件,见的挺多的但是不知道“#”代表的的是什么含义,尤其是看源码时,“#”更是多的让人头疼,所以查了一下关于C/C++的预编译指令,自己总结了一下,后续的博客也会使用到这一部分的内容。

一、#include–引入头文件

这就是我们最常使用的形式了,用于引入头文件,不过也有两种用法,也啰嗦的说一下吧。

#include<csdn.h>//用于引入标准头文件,可以理解成编译器自己带的头文件
#include"mycsdn.h"//用于引入自己写的头文件

两种引入方法的差别就在于他们展开时查找的路径不同,第一种是在系统默认路径去查找,而第二种是先在当前路径下查找,若查找不到再去系统默认路径下查找。就像我们经常会在VS编译器下自己写一些声明,并且都把他们放在自己写的.h文件中,此时我们就会选用第二种方式引入,毕竟都在一个工程里,再大费周章的把自己的头文件塞到系统默认路径下就很麻烦了。

二、#define、#undef–对宏进行操作

这种形式也是比较常用,我们会使用#define来定义一个量,称作宏,或者可以定义一个所谓“函数”,不过使用宏来定义一个类似函数的东西涉及的问题很多,因为使用宏定义的量会在代码的预编译阶段直接替换宏所在的部分,一不小心就出错了,用的时候还是要慎重,下面是一个简单的例子:

#define MAX_SIZE 100//使用宏来定义一个量
#define MAX(a,b) (((a)>(b))?((a):(b)))//使用宏定义一个类似“函数”一样的东西

在使用宏定义时需要注意类型,否则引起的误会可能会很多,还有上面第二个定义,也是需要注意变量的格式,否则也会很麻烦。
undef命令用于解除一个宏定义,在宏解除后再使用则会出错。
另外在宏中有两个特殊的运算符:(1)#:用于将“#”后的参数转为一个字符串;(2)##:用于将两个字符串连接在一起。

三、#if、#elif、#else、#endif–条件编译指令

类似于if-else语句,而endif用于结束一个选择块,if和elif后面跟的也是判断语句,在源代码中经常可以看到,这个较为简单就不赘述。但需要注意的是,他们后面的判断语句是在编译时求值的,所以不能使用变量,也不能使用sizeof()。

四、#ifdef、#ifndef、#endif–条件编译指令

一般我们在编写程序时,会引入多个头文件,但有时候我们引入的多个头文件他们内部也会存在互相引用的情况,这样的话程序在预编译阶段就会把某个头文件多次展开,既浪费时间又浪费空间。此时我们可以使用上面的这个预编译指令,防止头文件被多次展开。我们自己也会经常用到的,例如我们自己编写一个工程的时候,就会在头文件上加上如下的代码:

#ifndef MY_SOURCE_H
#define MY_SOURCE_H

//头文件内容

#endif 

五、#pragma指令–指定编译器完成特定动作

pragma指令较为特殊,他有很多参数,具体如下:

1.#pragma once

功能和#ifndef相同,保证头文件只被编译一次;

2.#pragma message

此指令使编译时将消息打印到编译输出窗口,方便检查某个量,类似于检查哨;

3.#pragma warning

控制发出警告的方式;

扫描二维码关注公众号,回复: 13293694 查看本文章

4.#pragma comment

将注释记录保存在某个文件中;

5.#pragma hdrstop

告诉编译器预编译头文件到此为止,后面的部分不参加预编译;

6.#pragma resource

将指定的source加入到工程中;

7.pragma code_seg

开发驱动程序时会用到;

8.pragma data_seg

建立新的共享数据段,一般用于DLL文件中;

9.pragma pack

指定数据在内存中对齐的长度。

六、#error、#line

C语言中使用__FILE__和__LINE__来指定代码位置,见名知意一个显示所在文件,一个显示所在行号。而#line指令用于指定这两个变量的值。而error则用于在编译时输出错误信息。

猜你喜欢

转载自blog.csdn.net/qq_45132647/article/details/105696261