#pragram once 和 #ifndef 辨别

【转】http://www.cnblogs.com/Braveliu/archive/2012/12/29/2838726.html

【1】#pragma once这个宏有什么作用?

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

【2】两者的使用方式有何区别?

示例代码如下:

1 //方式一:
2 #ifndef   __SOMEFILE_H__
3 #define   __SOMEFILE_H__
4 ... ... // 声明、定义语句
5 #endif
6
7 //方式二:
8 #pragma once
9 ... ... // 声明、定义语句

【3】两者各有何特点?

(1)#ifndef

#ifndef的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。

当然,缺点就是如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,但编译器却硬说找不到声明的状况——这种情况有时非常让人郁闷。

  由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,ifndef会使得编译时间相对较

  长,因此一些编译器逐渐开始支持#pragma once的方式。

(2)#pragma once

#pragma once 一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。

你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。

好处是,你不必再担心宏名冲突了,当然也就不会出现宏名冲突引发的奇怪问题。大型项目的编译速度也因此提高了一些。

对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名冲突引发的“找不

  到声明”的问题,这种重复包含很容易被发现并修正。

【4】两者之间有什么联系?

#pragma once 方式产生于#ifndef之后,因此很多人可能甚至没有听说过。目前看来#ifndef更受到推崇。因为#ifndef受C/C++语言标准的支持,不受编译器的任何限制;

而#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。

一般而言,当程序员听到这样的话,都会选择#ifndef方式,为了努力使得自己的代码“存活”时间更久,通常宁愿降低一些编译性能,这是程序员的个性,当然这是题外话啦。

还看到一种用法是把两者放在一起的:

#pragma once
   #ifndef __SOMEFILE_H__
   #define __SOMEFILE_H__
   ... ... // 声明、定义语句
   #endif

看起来似乎是想兼有两者的优点。不过只要使用了#ifndef就会有宏名冲突的危险,也无法避免不支持#pragma once的编译器报错,所以混用两种方法似乎不能带来

更多的好处,倒是会让一些不熟悉的人感到困惑。

选择哪种方式,应该在了解两种方式的情况下,视具体情况而定。只要有一个合理的约定来避开缺点,我认为哪种方

式都是可以接受的。而这个已经不是标准或者编译器的责任了,应当由程序员自己或者小范围内的开发规范来搞定。

时间: 2024-10-18 18:48:32

#pragram once 和 #ifndef 辨别的相关文章

pragram once

#pragma once [1]#pragma once这个宏有什么作用? 为了避免同一个文件被include多次,C/C++中有两种宏实现方式:一种是#ifndef方式,一种是#pragma once方式. 在能够支持这两种方式的编译器上,二者并没有太大的区别,但两者仍然有一些细微的区别. [2]两者的使用方式有何区别? 示例代码如下: 1 //方式一: 2 #ifndef __SOMEFILE_H__ 3 #define __SOMEFILE_H__ 4 ... ... // 声明.定义语句

如何通过网络,辨别数字世界的真假

数字世界,电流涌动.有多少能量是一直被浪费的呢?如果说,现实生活中我们奢侈的吃喝丢弃粮食是一种浪费.那么,制造虚假数据的人,同样一直在浪费能量.如何充分利用网络?遇到的困境或许不是如何充分利用,或许是如何更新陈旧的法律. 那么,如何通过网络辨别数字世界真假?这可以转换一个角度,如何搜集真假事件的相关信息.真或者假不是终点,目的才是它的终点.那么,webspider就是一个good idea.以柴静事件为例,可以搜集所有相关方公开言论以及合法相关背景,用简单的时间为轴.把事件用时间来排序,或许可以

#ifdef、#ifndef、#else、#endif执行条件编译

我们开发的程序不只在pc端运行,也要在移动端运行.这时程序就要根据机器的环境来执行选择性的编译,如对PC端编译PC端的程序,对移动端编译移动端的程序,这里我们就可以用两组条件编译. #ifdef  #endif #ifndef #endif 我们先来了解下#ifdef ...#endif:语法格式是: #ifdef 宏名字           |#ifdef 宏名字 //任意代码             |//任意代码 #endif                       |#else |/

如何辨别锌钢护栏涂层的好坏

锌钢护栏型材在整体上看来,不只漂亮并且很是有气度,超卓,能够起到美化环保的浸染,还能够安全防盗,不单能够满意客户的请求,还使客户有更高的享用层次. 锌钢护栏是指选用锌合金资料制造的阳台护栏,因为其具有高强度.高硬度.外观精巧.色泽艳丽等长处,变成住所小区运用的主流商品.传统的阳台护栏运用铁条.铝合金资料,需要凭借电焊等技术技术,并且质地较软.简单生锈.色彩单一.锌钢阳台护栏完美地处理了传统护栏的缺陷,并且报价适中,变成传统阳台护栏资料的代替商品. 如今许多住所的花园都运用锌钢护栏来围护,看起来既

[C++]关于头文件中的防卫式声明(#ifndef...#pragma once)

大家知道,我们写.h文件时,通常会加上防卫式声明,有以下两种方式: 1. 宏定义 #ifndef _FILENAME_ #define _FILENAME_ //... #endif 2. 编译器指令 #pragma once 但是,为什么头文件中需要添加这种防卫式声明呢?如果没有这样的声明,会出现怎样的问题.这里,先看一个例子. -- "Car.h",代码如下(并没有添加防卫式声明): // Car.h class Car { // ... }; -- "Person.h&

#ifndef是什么意思????

看了网上别人的文章,以前对ifndef的含义一直有些困惑.现在终于明白了. 以下文件在"os_cpu.h"中. #ifndef __OS_CPU_H__#define __OS_CPU_H__ /* 中间有许多定义啦声明啦!:: */ #endif /*__OS_CPU_H__*/ 这样,在编译阶段(ifndef是在编译阶段起作用滴!)假设有两个文件同时include了这个文件(os_cpu.h),这两个文件如果一个先 编译了,那么__OS_CPU_H__就被定义了.当编译到第二个文件

C/C++预处理指令#define,#ifdef,#ifndef,#endif…

本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下面代码 #ifdef如果宏已经定义,则编译下面代码 #ifndef如果宏没有定义,则编译下面代码 #elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码 #endif结束一个#if……#else条件编译块 #error停止编译并显示错误信息 本来只是想了解一下#ifdef,#ifnd

如何正确辨别预科院校

在面对如此众多的预科院校,学生该如何选择呢?华中师范大学留学预科专家介绍如下. 目前国内的预科主要有两种,一是在国内读课程管理相对松散的预科,一种是读健全的预科. 第一种预科:在国内读课程管理相对松散的预科学制大多三个月到半年. 第二种预科:健全的预科. 在面对着两种与众不同的预科院校时,如何辨别呢­? 首先办学资质.教学设置健全.真正意义上的四川大学预科合作项目,是外方大学督导教学,学生通过半年以上的学习而达到中级以上的水平.这种预科,老师是专职的,校舍独立,学生全日寄宿制,一天学习要达到十个

#pragma once 与 #ifndef

#pragma once:保证头文件只被编译一次.这种方式,是微软编译器独有的,也是后来才有的,所以知道的人并不是很多,用的人也不是很多,因为他不支持跨平台.如果你想写跨平台的代码,最好使用上一种.这是一种由编译器提供支持的方式,防止同一文件的二次编译,这里的同一文件指的是物理文件. #ifndef #define //code #endif 这个是C++语言相关,这是C++语言中的宏定义,通过宏定义避免文件多次编译.所以在所有支持C++语言的编译器上都是有效的,如果写的程序要跨平台,最好使用这