浅谈#ifndef,#define,#endif的作用和用法

 更新时间:2016年12月23日 09:14:42   投稿:jingxian  
下面小编就为大家带来一篇浅谈#ifndef,#define,#endif的作用和用法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

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

========================================================

用法:

.h文件,如下:
#ifndef XX_H
#define XX_H
...
#endif

这样如果有两个地方都包含这个头文件,就不会出现两次包含的情况 。。

因为在第二次包含时 XX_H 已经有定义了,所以就不再 include了
-------------------------------------------------------

#ifndef GRAPHICS_H // 防止graphics.h被重复引用
#define GRAPHICS_H

#include <math.h> // 引用标准库的头文件
…
#include “myheader.h” // 引用非标准库的头文件
…
void Function1(…); // 全局函数声明
…
class Box // 类结构声明
{
…
};
#endif

-----------------------------------------------------

那是指你建立多个文件时,多个文件里都包含这个头文件
-----------------------------------------------------

给你举个例子,再顺便分析一下:

假设你的工程里面有4个文件,分别是a.cpp,b.h,c.h,d.h

a.cpp的头部是:
#include "b.h "
#include "c.h "

b.h和c.h的头部都是:
#include "d.h "

而d.h里面有class D的定义。

这样一来,

编译器编译a.cpp的时候,先根据#include "b.h "去编译b.h这个问题,再根据b.h里面的#include "d.h ",去编译d.h的这个文件,这样就把d.h里面的class D编译了;

然后再根据a.cpp的第二句#include "c.h ",去编译c.h,最终还是会找到的d.h里面的class D,但是class D之前已经编译过了,所以就会报重定义错误。

加上ifndef/define/endif,就可以防止这种重定义错误。
--------------------------------------------------
-------------------------------------------------

1.比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。 还是把头文件的内容都放在#ifndef和#endif中吧。

不管你的头文件会不会被多个文件引用,你都要加上这个。

一般格式是这样的:

#ifndef <标识>
#define <标识>
......
......
#endif <标识>

在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h

#ifndef _STDIO_H_
#define _STDIO_H_
......
#endif

2.在#ifndef中定义变量出现的问题(一般不定义在#ifndef中)。

#ifndef AAA
#define AAA
...
int i;
...
#endif

里面有一个变量定义在vc中链接时就出现了i重复定义的错误,而在c中成功编译。

原因:

(1).当你第一个使用这个头的.cpp文件生成.obj的时候,int i 在里面定义了当另外一个使用这个的.cpp再次[单独]生成.obj的时候,int i 又被定义然后两个obj被另外一个.cpp也include 这个头的,连接在一起,就会出现重复定义.

(2).把源程序文件扩展名改成.c后,VC按照C语言的语法对源程序进行编译,而不是C++。在C语言中,若是遇到多个int i,则自动认为其中一个是定义,其他的是声明。

(3).C语言和C++语言连接结果不同,可能(猜测)在进行编译的时候,C++语言将全局变量默认为强符号,所以连接出错。C语言则依照是否初始化进行强弱的判断的。

参考解决方法:

(1).把源程序文件扩展名改成.c。

(2).推荐解决方案: .h中只声明 extern int i;

在.cpp中定义

#ifndef __X_H__
#define __X_H__
extern int i;
#endif //__X_H__ int i;
注意问题:变量一般不要定义在.h文件中。

以上就是小编为大家带来的浅谈#ifndef,#define,#endif的作用和用法全部内容了,希望大家多多支持脚本之家~

相关文章

  • C++编译错误variable-sized object may not be initiali问题

    C++编译错误variable-sized object may not be initiali问题

    这篇文章主要介绍了C++编译错误variable-sized object may not be initiali问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • C++中LibCurl库使用流程及配置详解

    C++中LibCurl库使用流程及配置详解

    libcurl是一个跨平台的开源网络传输库,它支持许多协议,包括HTTP、HTTPS、FTP、FTPS以及许多其他协议和文件传输方式,本文给大家详细介绍了C++中LibCurl库使用流程及配置,需要的朋友可以参考下
    2024-02-02
  • C++指针与引用的区别案例详解

    C++指针与引用的区别案例详解

    这篇文章主要介绍了C++指针与引用的区别案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • C语言中实现自定义数据类型的输入输出的方法和技巧

    C语言中实现自定义数据类型的输入输出的方法和技巧

    在 C 语言中,除了基本的数据类型(如整型、浮点型、字符型等),我们还经常需要自定义数据类型来满足特定的编程需求,所以本文给大家介绍了C语言中实现自定义数据类型的输入输出的方法和技巧,需要的朋友可以参考下
    2024-07-07
  • C++如何调用简单的python程序

    C++如何调用简单的python程序

    这篇文章主要介绍了C++如何调用简单的python程序问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C++面向对象多级菜单向Arduino的移植问题小结

    C++面向对象多级菜单向Arduino的移植问题小结

    这篇文章主要介绍了C++面向对象多级菜单向Arduino的移植问题及实现思路,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-06-06
  • C++中vector容器的注意事项总结

    C++中vector容器的注意事项总结

    在c++中,vector是一个十分有用的容器,下面这篇文章主要给大家介绍了关于C++中vector容器的注意事项,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2021-12-12
  • OpenCV实现图像轮廓检测以及外接矩形

    OpenCV实现图像轮廓检测以及外接矩形

    这篇文章主要为大家详细介绍了OpenCV实现图像轮廓检测以及外接矩形,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • 利用C语言实现猜数字小游戏

    利用C语言实现猜数字小游戏

    这篇文章主要为大家详细介绍了利用C语言实现猜数字小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • C++计数排序详解

    C++计数排序详解

    计数排序的思想我们之前接触过的例如:插入排序,归并排序,快速排序,堆排序等都是基于集合元素之间的比较这一基本的思想,它们执行的时间复杂度最优是趋于O(nlgn),而计数排序的运行机制不是基于集合元素之间的大小比较
    2016-04-04

最新评论