#ifndef (#ifdef)... #def ... #endif用法

在C++文件中我们常常看到文件中有#ifndef… #def…#endif (或者#ifdef … #def…)这些代码,它们属于预处理中的条件编译,主要有以下两个作用,防止头文件被重复引用和按条件对代码进行编译或者不编译。

1.防止头文件被重复引用

C++在预处理阶段会处理#include预编译指令,将被包含的头文件插入到该预编译指令所在的位置,该过程是递归进行的,包含的文件可能还包含其他文件。

一般防止头文件重复引用会有如下的格式:

#ifndef _X_H  //如果没有包含x.h头文件
#define _X_H  //则引入x.h头文件,并执行以下的函数代码
	/*code*/ //代码段
#endif  //结束标志

举例如下:如果有头文件a.h包含了头文件c.h,并且c.h中只有变量num的声明,那么当main.cpp同时包含头文件a.h和c.h时,执行下main.cpp时,会发生变量重复定义的错误:

//file a.h
#include "c.h"
//file c.h
int num;
//file main.cpp
#include <iostream>
#include "a.h"
#include "c.h"
using namespace std;
int main()
{
    num=5;
    cout<<num<<endl;//报错,num重复定义。
}

报错截图如下:
变量重定义

解决这个问题可以加入条件编译处理,只要在头文件c.h中加入以下三行即可,就不会产生变量的重复定义。

//file c.h
#ifndef _C_H  //如果没有包含c.h头文件
#define _C_H  //则引入c.h头文件,并执行以下的函数代码
	int num; //代码段
#endif  //结束标志

原因是main.cpp在处理第一行预处理语句#include “a.h”时首先会展开头文件a.h,由于a.h包含了头文件c.h,此时迭代引入头文件c.h,由于此时是第一次包含c.h,会执行c.h中的int num语句,声明变量num;接着处理第二行预处理语句#include “c.h”,由于此时已经包含了头文件c.h,就不会执行int num语句,因此不会发生重定义的错误。

2.按条件对代码进行编译或者不编译

除了防止头文件重复包含这一功能之外,还可以进行有条件的编译部分代码,代码格式如下,主要有两种例子:

#ifndef XXX //如果没有宏定义XXX,则执行代码
	/*code*/
#endif
#ifdef XXX  //如果宏定义了XXX,则执行代码
	/*code*/
#endif

下面是一个具体的例子,我们可以利用条件编译对代码进行debug,输出想要的内容或者忽略部分代码,实际项目中,经常利用条件编译实现特定的代码模块的功能。

#include <iostream>
#define DEBUG1
#define DEBUG2
using namespace std;
int main()
{
    #ifndef DEBUG1//如果没有定义 DEBUG1,则执行以下代码
    	cout<<"NOT DEBUG1"<<endl;//代码不满足条件编译的条件,不进行编译
    #endif
    #ifdef DEBUG2//如果定义了 DEBUG2,则执行以下代码
    	cout<<"DEBUG2"<<endl;
    #endif
    #ifdef DEBUG1//如果定义了 DEBUG1,则执行以下代码
    	cout<<"DEBUG1"<<endl;
    #endif
}

因为定义了DEBUG2和DEBUG1,程序会忽略第一个条件编译,编译最后两个条件编译语句,输出DEBUG2和DEBUG1,输出截图如下:
程序输出截图

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值