文档章节

【转载】#pragma once与#ifndef #define #endif的区别

摩云飞
 摩云飞
发布于 2012/12/15 23:12
字数 1091
阅读 298
收藏 2
VC
一、相同点
       两者的共同点都是为了避免同一个文件被 include 多次,但是 #ifndef #define #endif 不只有这个作用。
在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。
 
二、收集理解
1.#pragma once
       这个是编译器相关,就是说在这个编译系统上能用,在其他编译系统不一定行,即移植性差。不过现在基本上已经是每个编译器都有这个定义了。
       此方式由编译器保证同一个文件不会被包含多次。注意:这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。于是不必再费劲想个宏名了,当然也就可以避免宏的名字冲突问题了。

缺点:如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。
举例:在一般的 MFC 程序中可以看到
#if !defined(AFX_STDAFX_H__32722022_E372_4A5C_8EC5_BBB243CEDE1D__INCLUDED_)
#define AFX_STDAFX_H__32722022_E372_4A5C_8EC5_BBB243CEDE1D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__32722022_E372_4A5C_8EC5_BBB243CEDE1D__INCLUDED_)

其中 _MSC_VER 分解如下: 
MS:Microsoft(微软)的简写 
C:MSC 就是 Microsoft 出的 C 编译器 
VER:Version(版本)的简写

#if _MSC_VER > 1000 的意思就是如果编译器版本高于 1000(VC++5.0)
可以看到:在 _MSC_VER 小于 1000 时,它对 #pragma once 是不支持的。


2.#ifndef #define #endif
       该方法与 C++ 语言相关,是 C++ 语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持 C++ 语言的编译器上都是有效的。如果写的程序要跨平台,最好使用这种方式。该方式由于是 C++ 语言本身支持,所以移植性好。它依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。另外,为了保证不同头文件中的宏名不冲突,故采取类似于_ABC_H_的取名方式。其中,abc.h为当前头文件名。
 
举例:常常在一些头中可以看到
#ifndef __SOMEFILE_H__ 
#define __SOMEFILE_H__  
// 一些声明语句 
#endif

缺点:如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况。但这个缺点恰恰是我们可以利用的优点,#ifndef 方式可以通过前面介绍的特殊的宏的取名方式来避免名称冲突问题,于是其缺点也就不复存在了,进而 #ifndef 方式就更常用了。


三、相比之下
1.性能上的区别
       使用 #ifndef 的话,编译器每次看到 #include 这个文件都需要读入文件,解析代码; 而使用 #pragma once 编译器根本不会重复打开文件, 大大提高了效率。

2.编码风格上的区别
       使用 #pragma once 的代码简洁,显然比 #ifndef 要简短许多,重要的是它避免了头文件标号(如 __myheader_h__ )的重定义或者 #endif 包含范围错误的情况。

3.语意上的区别
#pragma once 是针对文件的,它告诉编译器,本文件只编译一次。
#ifndef #define #endif 只是针对文件中的某一个标号而言的,它能用于防止三个指令间所包含内容的重复性处理。就这一点而言,后者更灵活。

4.可移植性方面
#pragma once 是微软的开发工具中所使用的,如 .net,vc6 等工具可以完好的支持;
#ifndef #define #endif 是标准里面的一部分,所以对于任何完好支持 C/C++ 的编译器都能使用。显而易见,后者的可移植性更高。 


四、引用通告
在总结的过程中,看了一些网页,也引用到其中的一些内容,现给出链接,这里仅供本人学习,谢谢引用到的作者。

http://www.dnbcw.com/biancheng/c/dtox45497.html
http://zhidao.baidu.com/question/154510671.html?fr=ala0
http://zxjgoodboy.blog.sohu.com/87503141.html
http://hi.baidu.com/huqingshuye/blog/item/807a7c006f4a70044afb511a.html

本文转载自:http://pppboy.blog.163.com/blog/static/3020379620106130528324/

摩云飞
粉丝 376
博文 534
码字总数 952694
作品 0
徐汇
程序员
私信 提问
#pragma once #ifndef,#define,#endif

#pragma once这是一个比较常用的C/C++杂注,只要在头文件的最开始加入这条杂注,就能够保证头文件只被编译一次。 #pragma once是编译器相关的,有的编译器支持,有的编译器不支持,具体情况请...

Industryy
2015/01/17
61
0
#pragma once与 #ifndef的区别

为了避免同一个文件被include多次 1 #ifndef方式 2 #pragma once方式 在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。 方式一: #ifndef SOMEFI...

ryany
2011/11/05
292
1
使用VS2010在项目中编写C++头文现出"PCH 警告:标头停止点不能位于宏或#if块中"错...

以#pragma once作为头文件的第一句就可以避免出现文章标题所说的警告问题, 例子如下: //dcs.h #pragma once #ifndef DCSH_ #define DCSH_ class dcs { ........................... }; endif...

蓝叶菱
2012/07/25
4.2K
1
c 语言条件编译

指令 用途 # 空指令,无任何效果 #include 包含一个源代码文件 #define 定义宏 #undef 取消已定义的宏 #if 如果给定条件为真,则编译下面代码 #ifdef 如果宏已经定义,则编译下面代码 #ifnde...

双月通天
2015/12/02
72
0
C语言的预处理命令简介

参照C语言的预处理命令简介 :

SimonXun
2016/08/29
27
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 不要在领导修风扇的时候打开电扇

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :《Whats Up》 主唱妹子 Lina Perry 的嗓音实在太有力了,收放自如的自信才能唱出这么优秀的歌吧!#今日歌曲推荐# 《Whats Up》-...

小小编辑
今天
7
0
SpringBoot集成Elasticsearch并进行增删改查操作

一、创建工程 使用IntelliJ创建SpringBoot工程 SpringBoot版本为2.0.4 ElasticSearch为5.6.10 删掉蓝框中的文件(如上) 最后我们的目录结构(如下) 下面pom文件主要修改的是把spring boot从Int...

一字见心
今天
5
0
x001-版本介绍

python版本介绍 目前有2 和 3 有很多企业用的代码是2版本,随着技术的发展,以后用3的会成为大趋势 python3的安装 yum -y install wget gcc zlib-devel bzip2-devel openssl-devel ncurses-d...

侠客行之石头
今天
5
0
聊聊rocketmq的TransientStorePool

序 本文主要研究一下rocketmq的TransientStorePool TransientStorePool rocketmq-all-4.6.0-source-release/store/src/main/java/org/apache/rocketmq/store/TransientStorePool.java publi......

go4it
昨天
6
0
笔记

场外借贷, 质押 ,托管, 永续合约. 场外借贷,n签合同. 新功能 证券交易组负责中信证券机构及个人投资交易相关系统,服务机构及个人投资客户, 涉及到两融、期权、 期货、做市等境内境外创新业...

MtrS
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部