#pragma once与#ifndef两种防止头文件二次编译的区别

来源:互联网 发布:淘宝联盟2016旧版 编辑:程序博客网 时间:2024/05/18 00:24

#pragma once与#ifndef两种防止头文件二次编译的区别

标签: c++C++编译器语言
27942人阅读 评论(3)收藏举报
分类:
作者同类文章X

    在最开始接触到C语言的时候,看到很多大牛们写的代码里面就有#ifndef  #define #endif 这三条语句,当时不明白什么意思,慢慢的后来自己也开始用了,也知道了他们合起来使用时为了防止头文件被二次编译,因为我们曾经写代码的过程中一定遇到过<.......重复定义或是重复包含>等类似的错误吧。

    到了学习C++的时候,我们老师给我们看他的代码的时候发现他的头文件里用的是#pragma once,就奇怪这是什么呢?然后私下百度了后才知道,这也是防止头文件二次编译的,然后就开始用#pragma once了,这一用就是一个学期了,后来发现用着很好,再也没有重复编译或是重复包含的错误了,当时写C++代码的时候习惯了单个类放在独立的头文件里,这样子好纠错,也好扩展,调理更清晰。

    最近一段时间为了给学弟学妹们讲C语言的知识,又回过头来看宏定义的方法。就想写这么一篇博客来说明一下这两者之间的区别,过程中也百度了很多,也看了很多别人是怎么写的,怎么认识的。这里面肯定有他人文章中的影子,但是这绝对不是简单的复制粘贴,而是自己看了那么多之后的思考,总结之作。


    #ifndef这种是最早期使用的方法,是基于语言的宏定义名字不能冲突的前提下的。这种方法不仅能保证同一个头文件不会被包含两次,也可以保证内容完全相同的两个文件也只能被包含一次。但是他优缺点,就是你的#ifndef 后面跟的宏名字和你程序中的其他宏名字发生了”撞车“,那么会出现以下两种后果

    第一种:file1头文件中有一个宏

    //file1.h

    #define BOOK_H   //宏名

    现在又有一个文件 book.h 里面使用了宏定义方式防止头文件二次编译

    #ifndef BOOK_H

    #define BOOK_H

    //  program codes

    #endif

    下面是你的主函数所在文件内容

    #include"fil1.h"

    #include"book.h"   //这两个都是你自己的头文件

    #include<........>

    ..................

    预编译阶段把file1文件展开,就得到了宏 BOOK_H,在处理book.h文件时就发现BOOK_H这个宏已经存在了,就不会包含book.h头文件了,这就是弊端所在了。

    第二种就是:

    两者顺序反过来了,弊端类似。


    #pragma once这种方式,是微软编译器独有的,也是后来才有的,所以知道的人并不是很多,用的人也不是很多,因为他不支持跨平台。如果你想写跨平台的代码,最好使用上一种。这是一种由编译器提供支持的方式,防止同一文件的二次编译,这里的同一文件指的是物理文件。

    他也是有弊端的:

    假如你的某一个头文件有多份拷贝,那么这些文件虽然在逻辑上都是一样的,但是在物理上他们却是不同的,所以当你把这些文件包含的时候,就会发现真的都包含进来了,然后就是编译错误了。还有,当物理上的同一文件被嵌套包含的时候,使用第一种方法预处理会每一次打开该文件做判断的,但是第二种方法则不会,所以在此#pragma once 会更快些。下面举例说明

        // Test1.h
        #ifndefine  TEST1_H
        #defineTEST1_H
        ...
        #endif
        
        // Test2.h
        #pragma once        
        ...
        
        // Test.cpp
        #include "Test1.h"      // line 1
        #include "Test1.h"      // line 2
        #include "Test2.h"      // line 3
        #include "Test2.h"      // line 4 这里的Test2.h是同一物理文件

    预处理器在执行这四句的时候,先打开Test1.h然后发现里面的宏TEST1_H没有被定义,所以会包含这个文件,第二句的时候,同样还是会打开Test1.h的发现宏已定义,就不包含该文件按了。第三句时,发现之前没有包含Test2,h则会把该文件包含进来,执行第四句的时候,发现该文件已经被包含了,所以不用打开就直接跳过了。



      阅读全文
      0 0