👉#pragma once
,早就看到过这个东西,还以为这就是个简简单单的摆件罢了,没想到深藏不漏!害~ 年少年少,可笑可笑。
在初学阶段大家对这个估计都习以为常,这不,最近在看别人代码的时候发现原来这么一个潜伏在角落的平平无奇的#pragma
竟然是大佬!于是便好好研究了一番。
话说咱写代码的时候啊,总会遇到头文件被多次包含的情况,刚开始时我们使用宏定义进行控制,之后发现有#pragma once
这样简单的东西,开心的不得了,以为#pragma就这一种用法。害,想起当时还真是年轻。
那么pragma
究竟是何方神圣呢,这咱还得从预处理讲起。
C程序在整个编译过程中要经过一下这几步:
步骤 | 过程 | 指令 |
---|---|---|
预处理 | 展开头文件/宏替换/去掉注释/条件编译 | (test.i main .i) |
编译 | 检查语法,生成汇编 | ( test.s main .s) |
汇编 | 汇编代码转换机器码 | (test.o main.o) |
链接 | 链接到一起生成可执行程序 | a.out |
在C/C++中共有以下预处理指令:
pragma
便是预处理指令的一种
除了以上呢,还有以下几种预处理宏👇
__LINE__表示正在编译的文件的行号
__FILE__表示正在编译的文件的名字
__DATE__表示编译时刻的日期字符串,例如: “25 Dec 2007”
__TIME __ 表示编译时刻的时间字符串,例如: “12:30:55”
__STDC __ 判断该文件是不是定义成标准 C 程序
那说了这么多,pragma是干啥的呢,又有啥作用呢?
在C++ API参考文档中是这样描述#pragma
指令的👇
事实上,在所有的预处理指令中,#pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。
#pragma 指令对每个编译器给出了一个方法,在保持与C 和C ++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。
其格式一般为:
#pragma para
其中para 为参数,
那接下来这篇文章咱就好好捋捋pragma的常用参数及其用法:
一、#pragma message(…)
使用方法: #pragma message(“消息文本”)
这个参数最厉害的就是能够将message包含的信息直接在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。
例如:
1、当我们在遇到的一个项目程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86 这个宏可以用下面的方法
#if _M_IX86 //检查有没有定义宏
#pragma message("_M_IX86 已定义")
#endif
当我们定义了_X86 这个宏以后,应用程序在编译时就会在编译输出窗口里显示“_X86 已定义”。我们就不会因为不记得自己是否有定义该宏而踌躇不决了。并且在这个过程中编译不会中断!
2、可以是扩展到字符串,通过任意组合将此类宏与字符串串联起来,例如:
#pragma message( "Compiling " __FILE__ ) //显示被编译的文件
#pragma message( "Last modified on " __TIMESTAMP__ ) //文件最后一次修改的日期和时间
二、#pragma once
大家应该都早已知道:指定该文件在编译源代码文件时仅由编译器包含(打开)一次。
使用 #pragma once 可减少生成次数,和使用预处理宏定义来避免多次包含文件的内容的效果是一样的,但是需要键入的代码少,可减少错误率,例如:
使用#progma once
#pragma once
// 此间代码只被编译一次
使用宏定义方式
#ifndef HEADER_H_
#define HEADER_H_
// 此间代码只被编译一次
#endif // HEADER_H_
这条指令实际上在Visual C++6.0 中就已经有了,但是考虑到兼容性并没有太多的使用它。
三、#pragma waring(…)
启用编译器警告消息的行为和选择性修改,语法为:
#pragma