#ifndef, #define, #endif作用

条件指示符#ifndef 的最主要目的是防止头文件的重复包含和编译

参考以下两个链接:

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


几个重要的问题:

  • #ifndef后面内容有什么要求吗?

其实在#ifndef后面加什么都都可以,只要保证其唯一性就可以了,用文件名只是为了好区分。它只是用来定义一个预处理器变量。


  • 如果出现两个头文件#ifndef后面的内容相同怎么办?

通过“#ifndef/#define/#endif”结构产生预处理块,虽然能够避免同一个头文件被多次包含和重复引用,但也存在一个致命的缺点,那就是一旦一不小心在不同头文件中定义了相同的宏名,问题就比较麻烦了。比如,可能会导致明明看到存在头文件,而编译器却硬说找不到声明等问题。为了避免这种情况,保证宏名的唯一性,建议按照 Google 公司的建议,头文件基于其所在项目源代码树的全路径进行命名。命名格式为:
<PROJECT>_<PATH>_<FILE>_H_
其中,PROJECT 表示项目名称,PATH 表示头文件相对路径,FILE 表示文件名,再以“H”作为后缀。比如,在项目 CashRegister 中,现在该项目所在目录下的一个名为 xml 的子文件夹下的一个 parser 头文件,则宏定义如下:

#ifndef CASHREGISTER_XML_PARSER_H_
#define CASHREGISTER_XML_PARSER_H_
/*声明、定义语句*/
#endif

参考自条件编译指令(符号),C语言条件编译指令完全攻略


  • 是不是所有的头文件中都要加入#ifndef, #define, #endif这些代码?

不是一定要加,但是不管怎样,用#ifnde xxx #define xxx #endif或者其他方式避免头文件重复包含,只有好处没有坏处。个人觉得培养一个好的编程习惯是学习编程的一个重要分支。


  • 为什么#ifndef后面的内容都是大写?

因为#ifndef本质上是一种宏定义,习惯大写。


  • 有时可以写成#ifndef _HEADER_H_,下划线怎么理解?

下划线“__”属于编程风格的内容,对程序没有影响。不用下划线也可以,用几个下划线也由个人习惯;甚至可以写成#ifndef HEADER.H,因为#ifndef 后面的字符串,不管是HEADER.H还是__HEADER_H和头文件的名字没有半毛钱关系。只不过是为了读程序的时候方便而已。其实那个字符串只要合法的就行了
Note: ___开头的函数一般都是专用的函数,一般都是于特定系统相关的,如果要想有更好的移植性,应该避免使用。一般只有已经广泛使用的系统库函数和宏才有资格使用_甚至__打头,为的是不与用户定义的名字冲突,所以B.Stroustup在《The C++ Programming Language》中告诫我们一般不要使用_或__打头的标志符,这也是一个编程风格的问题吧。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
#ifndef,#define和#endifC++中用于避免头文件重复引用的预处理指令。它们一般是成对出现的。当一个头文件被多个文件引用时,为了防止重复定义和冲突,可以使用这些指令。 #ifndef是一个条件编译指令,用于判断某个标识符是否已经定义。如果这个标识符未定义,那么条件成立,可以继续执行下面的代码。如果已经定义了这个标识符,那么条件不成立,下面的代码将被跳过。 #define是用于定义一个标识符,并给定一个值。一般情况下,我们使用它来定义一个宏。在这个宏定义中,我们可以将标识符定义为一个值,或者直接定义为一段代码。 #endif是用于结束条件编译块的指令。它与#ifndef配合使用,用于标记条件编译的结束点。 举个例子,首先我们可以在头文件中使用#ifndef来判断某个标识符是否已经定义,如果没有定义,就使用#define来定义这个标识符,并编写相应的代码。然后,在其他的源文件中,我们可以使用#include来包含这个头文件。当源文件被编译时,预处理器会根据#ifndef和#define的判断来决定是否编译这部分代码。如果这个头文件已经被引用过了,预处理器会跳过这部分代码,从而避免重复定义和冲突的问题。 总的来说,使用#ifndef,#define和#endif指令可以有效地避免头文件的重复引用问题,确保代码的正确性和可维护性。需要注意的是,并不是所有的头文件都需要加入这些指令,只有在可能被多个文件引用的情况下才需要使用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++ 头文件 #ifndef #define #endif 作用及用法](https://blog.csdn.net/qq_37581730/article/details/127770758)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [#ifndef/#define/#endif使用详解](https://blog.csdn.net/m0_48990191/article/details/115007141)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lyh458

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值