| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C/C++常用预编译指令介绍 -> 正文阅读 |
|
[C++知识库]C/C++常用预编译指令介绍 |
目录 3、#ifdef、#ifndef、#else、#elif和#endif指令 5、编译器预置宏__FILE__、__LINE__和__FUNCTION__ ? ? ? ?C/C++代码会使用到各式各样的预编译指令,预编译指令一般是以#号开头的,这些指令是在编译期间识别的,由编译器去负责解析这些指令并做出对应的处理。今天我们来介绍一下C/C++中常用的预编译指令。 VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931 1、#include指令? ? ? ?该指令用来包含头文件,头文件中可能有结构体、枚举体、类或函数的声明,使用到这些对象时需要包含声明这些对象的头文件,比如:
? ? ? ?包含头文件有#include <filename.h>和#include “filename.h”两种方式,两种方式是有区别的,决定了编译时搜索头文件的路径:
2、#define和#undef指令? ? ? ? #define通常用来定义一个宏,比如代码中多处使用的某个固定数值,我们可以用将固定值定义成宏,比如我们在用sqlite数据库存放数据时会设定单个数据库文件的大小:
? ? ? ?定义的宏可以是一个数值,也可以是个表达式,也可以是一段经常使用的代码。比如我们在delete指针时,可以封装成这样的宏:
对于上述宏,在编译器编译时,会将使用到这些宏的地方直接替换成宏的内容。 ? ? ? ?除了将一个数值、一个表达式或一段代码定义成宏,可以直接定义一个没有具体内容的宏,仅仅表示代码中定义了该宏。只是起到一个标识的作用,代码中可以使用#ifdef或#ifndef来判断有没有定义该宏。?
通过添加宏,去控制代码的逻辑和走向,也可以通过宏去确定当前模式是否支持某些功能。 ? ? ? ??#undef指令则用于取消之前定义的宏。 3、#ifdef、#ifndef、#else、#elif和#endif指令? ? ? ?这些是预编译指令中的条件判断指令,和C/C++代码中if、else、else if等是类似的。这些指令主要处理与宏相关的判断。比如我们经常在头文件中添加如下的一段预编译指令,防止头文件内容被多次包含:
? ? ? ?项目中肯定有多个头文件,这些头文件中用于被用来防止头文件被重复包含的宏名称是不能重复的,重复了会有问题的。在微软Visual Studio开发工具中,可以使用#pragma once指令来替代。 ? ? ? ? 为啥会出现头文件多次包含的问题呢?其实很好理解,比如头文件header2.h中包含header1.h头文件(假设头文件header1.h中没有添加防止被重复包含的预编译指令),test.cpp中既包含了header1.h头文件,也包含了header2.h头文件,这样就会出现两次包含header1.h的问题,就会出现头文件中的内容被定义两次的问题(包含头文件的地方可以想象成直接替换成头文件中的内容),所以要添加防止头文件中的内容被重复定义的问题。特别是再大型项目中,有多个头文件和cpp文件,很容易出现同一个头文件被包含多次的问题,所以必须要在头文件中添加防止头文件中的内容被重复定义的预编译指令。 ? ? ? ?再就是,根据是否定义个某个宏去做不同的处理:
4、#error指令 ??? ? ? ?使用该指令可以在编译器编译期间在IDE的输出窗口中打印出一段字符串。比如我在头文件中添加一条这样的指令:
编译时在输出窗口会输出上述字符串: ? ? ? ?该命令可以用在这样的场景下,比如一个项目代码的路径中有两个头文件都定义了同一个名字的宏(宏名称一样,宏值可能不一样),但不确定到底使用的是哪个头文件中定义的宏,就可以在一个头文件中添加:
在另一个头文件中添加:
然后重新编译代码,编译时就会在编译信息输出窗口中就会看到上述指令输出的字符串,输出了哪个字符串,就使用了对应的头文件。 5、编译器预置宏__FILE__、__LINE__和__FUNCTION__? ? ? ?__FILE__用于指示本行代码所在源文件的文件名(完整路径),__LINE__用于指示本行代码所在源文件中的位置(行数),__FUNCTION__用于指示本行代码所在函数(函数名)。这几个宏在编译期间编译器就将之替换成对应的内容了,在打印日志时比较有用。 ? ? ? ?使用这几个宏的测试代码如下:
6、#pragma指令? ? ? ? 该类指令用来设定编译器的状态或者指示编译器完成一些特定的动作,它支持不同的操作参数。注意该部分指令只有微软的C++编译器才支持,才能识别。 6.1、#pragma once指令? ? ? ?在头文件的开始处添加这条指令,是为了保证头文件只被编译一次,以解决头文件被多次包含时的问题。也可以使用#ifndef/#define/#endif实现同样的效果,如下:
6.2、#pragma message指令? ? ? ? 该指令能够让编译器在执行到该条指令时在编译信息输出窗口中输出一段信息,其使用方法为:#pragma message(“消息文本”)。通过这条指令我们可以方便地记录在是否在源代码中定义过某个宏,比如:
6.3、#pragma warning指令? ? ? ? 该指令可以将指定编号的警告信息屏蔽掉。比如我们编写了如下的代码:
使用Visual Studio编译,会报出如下警告: 提示strcpy函数不安全,建议使用安全版本的字符串拷贝函数strcpy_s。 ? ? ? ?如果我们代码写的没问题,我们就要使用strcpy,则可以将该类警告信息屏蔽掉,如下:
diasable后面跟的就是警告信息的类型编号。 6.4、#pragma comment指令? ? ? ?该指令将一个注释记录放入一个对象文件或可执行文件中,其使用方法为:
其中,comment-type 是一个预定义的标识符,指定注释的类型,包括compiler,exestr,lib,linker。比如我们在使用dll库之前需要将dll库对应的lib文件:(程序链接时使用)
6.5、#pragma hdrstop指令? ? ? ?该指令表示预编译头文件到此为止,后面的头文件不进行预编译。 6.6、#pragma resource指令? ? ? ?该指令表示把指定文件中的资源加入工程,如
6.7、#pragma code_seg指令? ? ? ? 该指令能够设置程序中函数代码存放的代码段,开发驱动程序的时候会使用到。使用方法为:
6.8、#pragma data_seg指令? ? ? ? 该指令建立一个新的数据段并定义共享数据。一般用于DLL中,在DLL中定义一个共享的有名字的数据段,这个数据段中的全局变量可以被多个进程共享,否则多个进程之间无法共享DLL中的全局变量。其使用方法为:
6.9、#pragma init_seg指令? ? ? ? ?该指令用于控制全局对象的初始化顺序,其使用方法为:
其中,init_seg后面括号中包含的参数有compiler编译器、 lib库、 user用户,和 user_defined_segment_name四种,前三个指令的初始化优先次序依次降低,但都先于普通的全局变量构造,如cout就是使用compiler级别构造的。比如:
? ? ? ?pragma init_seg(compiler)是保留给微软C/C++ 运行库使用的,我们不应该使用它!在我们的代码里,如果希望一些对象先于其他对象初始化,我们可以在对应的cpp文件中使用 #pragma init_seg(lib) 指令,比如:
但要注意,一个源文件只能出现一次init_seg 指令。 6.10、#pragma pack指令? ? ? ?该指令用来指定当前头文件中定义的结构体数据在内存中的对齐长度,比如:
上述代码是输出TestStruct结构体的长度,如果不使用#pragma pack指定对齐长度,则是8字节。此处添加了#pragma pack(1),则是1字节对齐,那结构体的长度就是5字节了。 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/11 10:43:34- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |