想必很多人都看过“头文件中用到的 #ifndef/#define/#endif 来防止该头文件被重复引用”。但是是否能理解“被重复引用”是什么意思?头文件被重复引用了,会产生什么后果?是不是所有的头文件中都要加入#ifndef/#define/#endif 这些代码?

1、 其实“被重复引用”是指一个头文件在同一个cpp文件中被include了多次,这种错误常常是由于include嵌套造成的。如:存在a.h文件#include "c.h"而此时b.cpp文件导入了#include "a.h" 和#include "c.h"此时就会造成c.h重复包含。

2、头文件被重复引用引起的后果:

(1)有些头文件重复引用,只是增加了编译工作的工作量,不会引起太大的问题,仅仅是编译效率低一些,但是对于大工程而言编译效率就是很重要的了。

(2)有些头文件重复包含,会引起编译错误,比如在头文件中定义了全局变量或写了函数的实现而不是声明(虽然这种方式不被推荐,但确实是C规范允许的),这种会引起重复定义。

3、 是不是所有的头文件中都要加入这些代码?

不是一定要加,但是不管怎样,用#ifndef/#define/#endif或者其他方式避免头文件重复包含,只有好处没有坏处。培养一个好的编程习惯是学习编程的一个重要分支。所以在写头文件时,最好是把内容都写在#ifndef和#endif之间。

4、以add.h为例

#ifndef  _ADD_H_
#define _ADD_H_ //在这里包含add.h的类定义及变量和函数的声明
比如函数声明:int add(int a ,int b); //分号是必须加上的 #endif //_ADD_H_

编写add.cpp文件

#include"add.h"
int add(int a , int b)
{
return a+b;
}

主函数main.cpp文件

#include <iostream>
#include "add.h"
using namespace std; int main()
{
int a ;
a = add(,);
cout<<a<<endl;
return ;
}

1)程序中_ADD_H_为预处理器变量,书写格式一般是头文件名大写,前后加下划线,“.”用下划线代替。比如stdio.h表示为_STDIO_H_.

2)预处理器变量一般有两种状态:已定义或未定义。

  #ifndef 指示检测指定的预处理器变量是否未定义,如果未定义,那么跟在后面的所有指示被处理,直到出现#endif;如果已定义,那么#ifndef测试为假,该指示和#endif指示间的代码都被忽略。

  #define 指示接受一个名字并定义该名字为预处理器变量。

3)在调用该头文件时一般用#include "add.h"。

4)但是,必须记住的是预处理器仍将整个头文件读入,即使这个头文件所有内容将被忽略。由于这种处理将减慢编译速度,所以如果可能,应该避免出现多重包含。

5、#pragma的用法

#pragma once     

...  //此处放头文件中本来应该写的代码

#pragma once 是个预处理指令,在头文件的最开始加入这条指令表示:这个头文件只被编译一次,是由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。

6、总结: 

#ifndef,#define,#endif是C/C++语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的,移植性好,所以如果写的程序要跨平台,最好使用这种方式。但缺点是宏名字不能冲突。

#pragma 可以避免名字冲突,缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。且不是所有编译器都支持这种方式。

[C++] 头文件中的#ifndef,#define,#endif以及#pragma用法的更多相关文章

  1. 头文件中的#ifndef/#define/#endif 的作用

    在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误.在头文件中实用#ifndef #define #endif能避免头文件的重定 ...

  2. 头文件里面的ifndef /define/endif的作用

    c,c++里面,头文件里面的ifndef /define/endif的作用 今天和宿舍同学讨论一个小程序,发现有点地方不大懂······ 是关于头文件里面的一些地方: 例如:要编写头文件test.h ...

  3. 头文件种的ifndef/define/endif 是干什么用的

    头文件种的ifndef/define/endif 是干什么用的? 答:防止头文件被重复包含.

  4. ifndef/define/endif作用和用法

    问题:ifndef/define/endif”主要目的是防止头文件的重复包含和编译,偶只知道这个概念不懂的是怎么个用法,和为什么要用它~~高手请指点一下~~谢谢~~~!!! ------------- ...

  5. C++ ifndef /define/ endif 作用和用法

    ifndef/define/endif”主要目的是防止头文件的重复包含和编译 比如你有两个C文件,这两个C文件都include了同一个头文件.而编译时,这两个C文件要一同编译成一个可运行文件,于是问题 ...

  6. ifndef /define/ endif 作用和用法

    问题:ifndef/define/endif"主要目的是防止头文件的重复包含和编译====================================================== ...

  7. C++头文件为什么要加#ifndef #define #endif

    #ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...

  8. 头文件为什么要加#ifndef #define #endif

    #ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...

  9. #ifndef #define #endif 防止头文件被重复引用

    想必很多人都看过“头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?是不能在不同的两个文件中使用include来包含这个头文件 ...

随机推荐

  1. Windows Server 2008 R2服务器内存使用率过高,但与任务管理器中进程占用内存和不一致

    系统环境: Windows Server 2008 R2 + Sql Server 2008 R2   问题描述: Windows Server 2008 R2系统内存占用率过大,而在任务管理器中各进 ...

  2. java多线程----悲观锁与乐观锁

    java多线程中悲观锁与乐观锁思想 一.悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线 ...

  3. 通过 Channel 实现 Goroutine Pool

    最近用到了 Go 从 Excel 导数据到服务器内部 用的是 http 请求 但是发现一个问题 从文件读取之后 新开 Goroutine 会无限制新增 导致全部卡在初始化请求 于是乎就卡死了 问题模拟 ...

  4. Windows上快捷登陆应用程序

    在Windows上有些程序双击后,还需要输入用户名密码等,填写很多信息后才开始使用. 有些程序本身实现了保存信息,或者可以自动登陆. 但也有些程序无信息保存和自动登陆功能,如果经常使用,每次都填写觉得 ...

  5. GIT和SVN教程

    各种版本控制工具的简单比较 特性 CVS SVN GIT 并发修改 支持 支持 支持 并发提交 不支持 支持 支持 历史轨迹 不支持更名 支持更名 支持更名 分布式 不支持 不支持 支持 SVN SV ...

  6. Windows Server - SVN 服务器搭建与项目配置、客户端安装与配置

    本教程以Windows Server 2012 R12 为例搭建SVN服务器,安装部署完成后,客户端可通过SVN客户端访问SVN服务器上的项目,也可以访问网上其他SVN服务器上的项目. 一.首先准备三 ...

  7. IDEA maven使用tomcat7插件启动报错:A child container failed during start

    使用maven的tomcat7插件启动项目时出现上面的错误:A child container failed during start, 出现这个问题的原因是导入了servlet-api包,与tomc ...

  8. iframe中使用模态框提交表单后,iframe加载父页面的解决方法

    在iframe中使用模态框提交表单后,会出现iframe加载整个父页面的问题,如下图: 解决方法: 在form表单中添加target属性 _parent 这个属性会使目标文档载入父窗口或者包含来超链接 ...

  9. Elasticsearch(5)--- 基本命令(集群相关命令、索引CRUD命令、文档CRUD命令)

    Elasticsearch(5)--- 基本命令 这篇博客的命令分为ES集群相关命令,索引CRUD命令,文档CRUD命令.这里不包括Query查询命令,它单独写一篇博客. 一.ES集群相关命令 ES集 ...

  10. openSession 与 getCurrentSession的区别

    1.openSession 每一次获得的是一个全新的session对象,而getCurrentSession获得的是与当前线程绑定的session对象 package cn.kiwifly.view; ...