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

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

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

?


1

2

3

4

5

6

7

8

9

10

11

#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为当前头文件名。 
  
举例:常常在一些头中可以看到 

?


1

2

3

4

#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://pppboy.blog.163.com/blog/static/3020379620106130528324/

时间: 2025-01-19 13:48:05

【转载】#pragma once与#ifndef #define #endif的区别的相关文章

[Windows编程] #pragma once 和#ifndef ... #define ... #endif 比较

C++中防止头文件被多次include 的常见方式有: 1) 用#ifndef ...  #define ... #endif  宏 #ifndef __MYHEADER_H__#define __MYHEADER_H__ // Here is my class ... #endif 2) 用 #pragma once #pragma once // Here is my class ... 建议使用 #pragma once ,原因: 1)  代码简洁,维护性比较好. #pragma once

解析php中static,const与define的使用区别_php技巧

define部分:宏不仅可以用来代替常数值,还可以用来代替表达式,甚至是代码段.(宏的功能很强大,但也容易出错,所以其利弊大小颇有争议.)宏的语法为:#define 宏名称 宏值作为一种建议和一种广大程序员共同的习惯,宏名称经常使用全部大写的字母.利用宏的优点:1)让代码更简洁明了当然,这有赖于你为宏取一个适当的名字.一般来说,宏的名字更要注重有明确直观的意义,有时宁可让它长点.2)方便代码维护对宏的处理,在编译过程中称为"预处理".也就是说在正式编译前,编译器必须先将代码出现的宏,用

#pragma once与 #ifndef的区别

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

全面了解#pragma once与 #ifndef的区别_C 语言

为了避免同一个文件被include多次 1   #ifndef方式 2   #pragma once方式 在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别. 方式一: #ifndef __SOMEFILE_H__ #define __SOMEFILE_H__ ... ... // 一些声明语句 #endif 方式二: #pragma once ... ... // 一些声明语句 #ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次

#if #ifdef和#ifndef的用法和区别

#if #ifdef和#ifndef用法 移位运算符的优先级高于条件运算符,重载是不能改变运算符优先级的,这点要注意,所以代码应当像下面这样调整,写宏的时候一定要注意优先级,尽量用括号来屏蔽运算符优先级. #define MAXIMUM(x,y) ((x)>(y)?(x):(y)) #define MINIMUM.... 实例  代码如下 复制代码 #include<stdio.h>    #define MAX    #define MAXIMUM(x,y) x>y?x:y  #

解析php中const与define的应用区别_php技巧

1.const用于类成员变量定义,一旦定义且不能改变其值.define定义全局常量,在任何地方都可以访问.2.define不能在类中定义而const可以.3.const不能在条件语句中定义常量 复制代码 代码如下: if (...) {     const FOO = 'BAR';    // invalid } but if (...) {     define('FOO', 'BAR'); // valid } 4.const采用一个普通的常量名称,define可以采用表达式作为名称. 复制

【转载】MSVCR100.dll和MSVCP100.dll的区别

MSVCR100.dll This msvcr100.dll is the Microsoft Visual C++ Redistributable dll that is needed for projects built with Visual Studio 2010. The dll letters spell this out. MS = MicrosoftV = VisualC = C program languageR = Run-time100 = Version If you c

#ifndef用法总结 .

[转] #ifndef#define#endif的用法(整理)    原作者:icwk  文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都include了同一个头文件.而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突. 还是把头文件的内容都放在#ifndef和#endif中吧.不管你的头文件会不会被多个文件引用,你都要加上这个.一般格式是这样的: #ifndef <标识> #define <标识>

文件重定义冲突的分析与解决

引言 有时候看到论坛上有人问编译时重定义现象的问题.这个问题与头文件包含冲突有关,改一改相关头文件包含就会让问题消失.我在这里要以 <windows.h> <winsock.h> <winsock2.h>这3个头文件为例分析为什么会产生这种原因:然后给出一种不会产生冲突的做法:最后就此例的分析给出结论.本文对于已经知道冲突原因的读者是多余的,但对于一时没有时间去解的人还是有一定的参考价值的. 一个重命名的例子 先写一个socket基本操作类: // SocketBase