关于两种头文件包含及其解决办法
来源:互联网 发布:苹果手机默认软件 编辑:程序博客网 时间:2024/06/04 08:43
1、C语言中用<>或者“”来包含头文件。
两种方式的区别:
(1)、使用< >表示按照标准方式搜索要嵌入的文件,该文件位于c++系统目录下的include子目录下,一般包含系统提供的标准文件时采用这样的方式;使用" "表示首先在当前目录下搜索要嵌入的文件,如果没有再按照标准方式搜索,对用户自己编写的文件一般采用这种方式。
(2)、用<>标示编译器会从C语言安装的根目录去搜寻头文件;用“ ”表示编译器会从C语言专用的头文件目录去搜寻的头文件。
(3)、C语言专用的头文件目录包含在C语言安装的根目录中,“ ”会先搜索你自己写的头文件再搜索系统文件,所以系统<>文件会比“ ”快一些,但是不影响代码的质量和速度,只是对编译的速度有所影响。
2、头文件包含问题及其解决:
首先我们来说一说重复包含的影响:
C/C++在预处理的时候,include相同的文件,预处理器会检查XXX是否有定义再决定要不要复制内容,重复包含会是编译器多检查几次而已。另外在使用增量编译的时候,这个文件变化,所有 include 这个文件的文件都需要重新编译,即使没有去使用里面的任何内容,所以重复包含最经常带来的错误就是重定义。
在制作C/C++项目的过程中,应该会遇到关于头文件被重复包含的问题,几乎每一个C/C++程序员都应该知道如何来解决这一问题。通常来说,我们通常可以用两种方式来解决这一问题。
第一种 ---- 利用以下形式:
#ifndef __XX_H__ #ifndef XX_H
#define __XX_H__ 写成这样也可以--> #define XX_H
<头文件定义正文> <头文件定义正文>
#endif #endif
__XX_H__ 其实就是一个标志,(这个标志本来可以随便自己定义,但是为了防止混乱,所以一般都会采用自己的文件名字:__XX_H__),而且 ifndef 也可以写成 if !defined 效果是一样的。(注:ifndef 不要错写成 ifdef)
当然还有第二种 ---- 在windows平台下,有一个很方便的宏: #pragma once
这个宏我们用MSDN打开查看一下可以得到以下解释内容:
"Specifies that the file will be included (opened) only once by thecompiler when compiling a source code file."
从字面上看这句英文的主要意思就是防止头文件被重复包含。于是我们就想,既然这两种方法都可以起到防止头文件被多次包含的作用,那么这两种方式有什么不同呢,或者说有什么相同之处呢?
在用VC6.0向导生成的头文件中,经常可以看见如下的代码段:
#if !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)
#define AFX_RESIZABLELAYOUT_H__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
...
#endif // !defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)
对于宏有基本了解的朋友应该都知道,头文件中如下的宏定义,是为了避免同样的头文件在同一个.C文件或者.CPP文件多次包含。
#if !defined(XXX)
#define XXX
#endif
由此可知这两种方式都可以很好的起到避免重复包含的作用,但是这两种有什么区别呢?
疑惑就此产生了,既然宏"#if !defined"已经有这个作用了,为何还要一个"#pragma once"呢?
其实虽然"#ifndef"和"#pragma once"都有避免重复包含的功能,但是在实现上还是有区别的。举一例如下:
// Test1.h
#ifndef __COMMENT_CONVERT_H__
#define __COMMENT_CONVERT_H__
...
#endif
// Test2.h
#pragma once
...
// Test.cpp
#include "Test1.h" //
#include "Test1.h" //
#include "Test2.h" //
#include "Test2.h" //
...
头文件Test1.h中用宏来避免重复,头文件Test2.h中用#pragma once来避免重复。编译Test.cpp,将需要打开Test1.h两次,第一次发现宏__COMMENT_CONVERT_H__没有定义,接着就处理宏定义;第二次打 开Test1.h时,发现宏__COMMENT_CONVERT_H__已经定义过了,编译器就会略过宏定义部分,直到处理完Test1.h末的#endif。
而由于头文件Test2.h使用#pragma once来避免重复定义的,在编译Test.cpp的过程中,Test2.h只会被打开一次,也就是处理到第3行的时候。因为Test2.h用的 是#pragma once,所以在处理完第3行后,编译器已经知道包含了一次Test2.h,在它(编译器)处理第4行代码时,发现Test2.h已经包含过了,忽略掉第 4行代码,也就不需要再次打开Test2.h进行判断了。
总结一下,除了#pragma once是微软编译器所特有的之外,用宏和#pragma once的办法来避免重复包含头文件,主要区别在于宏处理的方法会多次打开同一头文件,而#pragma once则不会重复打开,从而#pragma once能够更快速。
用更确切的语言总结一下就是:#pragma once指定当前文件在构建时只被包含(或打开)一次,这样就可以减少构建的时间,因为加入#pragma once后,编译器在打开或读取第一个#include 模块后,就不会再打开或读取随后出现的同#include 模块。
- 关于两种头文件包含及其解决办法
- 关于VS包含*view.h文件出现错误的解决办法
- 关于C++类中头文件相互包含时报错的解决办法
- 关于C++/C中防止头文件的重复包含的解决办法
- 关于C++/C中防止头文件的重复包含的解决办法 (转)
- 程序文件文件中包含中文解决办法
- 记一笔:关于文件包含
- 关于文件包含的顺序
- jsp包含html文件中文乱码解决办法
- 关于Session过期问题及其解决办法
- 关于头文件文件包含的问题
- C++编程常用头文件及其包含函数汇总
- 关于相互包含的头文件
- 关于#define #ifdef 与文件包含
- 关于C头文件包含include "**.h"
- 关于头包含头文件的问题
- 关于c++头文件的重复包含
- 关于PHP中的文件包含方法
- 欢迎使用CSDN-markdown编辑器
- 判断一个字符串里面是否有重复的字符
- Android自定义View的实现方法,带你一步步深入了解View(四)
- [BZOJ3643] phi的反函数 - 欧拉函数 - dfs
- 几何基础知识点
- 关于两种头文件包含及其解决办法
- Android --中间突出的底部导航栏布局简单实现
- 44.1+2+3+...+n
- 突出显示当日的c++日历代码
- Google学术上不去,几个替代网址
- C#网络编程 (二) 数据流的类型和应用
- /usr/texbin/pdflatex 不存在。
- leetcode No344.Reverse String Note
- Oracle忘记user密码操作 查询DBA权限