想必很多人都看过“头文件中用到的 #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(2,3);cout<<a<<endl;return 0;
}

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

转载于:https://www.cnblogs.com/zhizhiyu/p/10134044.html

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

  1. #ifndef #define #endif 和#pragma once的区别

    相同点:#ifndef #define #endif 和 #pragma once 都是用来保证一个.h文件只被编译一次. 不同点: 1. #ifndef #define #endif 用来防止一个宏 ...

  2. 头文件中加 #ifndef

    在开发大型应用程序的时候,都是(非常有必要)将程序按照单元功能(模块)分开,即程序的模块化.然而有时因为模块功能函数划分太多,难以避免导致当前的头文件被重复#include的情况,这时便会出现重复定义 ...

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

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

  4. C++ 头文件 #ifndef #define #endif 作用及用法

    为什么要加定义 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都include了同一个头文件.而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声 ...

  5. ifndef/define/endif——主要目的是防止头文件的重复包含和编译

    原文:http://www.jb51.net/article/100939.htm 原文:https://blog.csdn.net/abc5382334/article/details/180527 ...

  6. #ifndef/#define/#endif 防止该头文件被重复引用

       转载自:http://blog.csdn.net/abc5382334/article/details/18052757    想必很多人都看过"头文件中的 #ifndef/#defi ...

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

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

  8. #ifndef 在头文件中的作用

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

  9. C++中#ifndef/#define/#endif使用详解

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

最新文章

  1. 一文教会你什么线程安全以及如何实现线程安全
  2. 如何编译ReactNative示例程序Examples
  3. 好东西和大家分享阿!
  4. DB Query Analyzer 中断SQL语句的执行
  5. mysql开启perform sch_MySQL Performance schema设置的一些建议选项
  6. 计算机基础ABCDEF,计算机应用基础_在线作业ABCDEF.docx
  7. 常数时间插入、删除和获取随机元素
  8. testlink配置修改
  9. python求解非递减排序的数组的一个旋转的最小元素
  10. android auto凯迪拉克,凯迪拉克支持Apple CarPlay及Android Auto
  11. hashmap java 排序_Java HashMap 默认排序
  12. 常用的项目管理工具有哪些?
  13. 简单好听的id_简单好听的贴吧id名-网名搜索
  14. Android Car - 开机画面
  15. kotlin expecting a top leveleclaration
  16. 医院公厕智能化管理需要实现哪些功能
  17. 美国达高特DAKOTA超声波测厚仪检测仪维修
  18. 数据结构与算法(基于<algorithm>)
  19. 如何使用CSS和JavaScript构建简单的甘特图
  20. 计算机专业工作要求,计算机专业毕业后部分工作的工作要求

热门文章

  1. vue引入id3_使用决策树ID3算法,预测收入是否大于50k
  2. 线程通信:生产者消费者问题
  3. 5G是什么?5G能做什么?5G在未来将带来什么?
  4. 越来越多优秀的老员工辞职,怎么办?
  5. 7805急剧发热,可能是什么原因?
  6. 怎样和处在“叛逆”阶段的孩子交流沟通?
  7. 有房贷的房子怎么卖?
  8. 郭麒麟、宋轶主演的《赘婿》1-8集拍得怎么样?
  9. 网抑云了是什么意思,网抑云语录有哪些,网抑云网抑云梗表情包
  10. 为什么农产品电商不好做