ifndef详解

article/2025/9/6 7:56:43

ifndef详解

#ifndef 是"if not defined"的简写,是预处理功能(宏定义、文件包含、条件编译)当中的条件编译,在实际开发中可以用于做test或者不同版本的不同适配。
在vscode中可以通过json脚本的define来定义ifndef 的值,或者在通过gcc编译的时候添加上宏来进行条件编译。

ifndef 可以根据是否已经定义了一个变量来进行分支选择,其作用是:

  1. 防止头文件的重复包含和编译;
  2. 便于程序的调试和移植;

下面分别举例描述。

一、防止头文件的重复包含和编译
下面是错误示范:

headfile_1.h

 1 #include <iostream>2 class CTest_1 {3     CTest_1() {4         //do something,eg:init;5     }6     ~CTest_1() {7         //do something ,eg:free;8     }9     void PrintScreen()
10     {
11         std::cout << "this is Class CTest_1!" << std::endl;
12     }
13 };

headfile_2.h

 1 #include "headfile_1.h"2 class CTest_2 {3     CTest_2() {4         //do something,eg:init;5     }6     ~CTest_2() {7         //do something,eg:free;8     }9     void PrintScreen()
10     {
11         std::cout << "this is Class CTest_2!" << std::endl;
12     }
13 };

sourcefile.cpp

1 #include <iostream>
2 #include "headfile_1.h"
3 #include "headfile_2.h"
4 
5 int main()
6 {
7     return 0;
8 }

编译时提示重定义错误:
在这里插入图片描述

以上显示headfile_1.h中的类CTest_1重定义了。

一般地,假如有一个C源文件(如sourcefile.cpp),它包含两个头文件(如headfile_1.h和headfile_2.h),而头文件headfile_2.h又包含了headfile_1.h,则最终的效果是该源文件包含了两次headfile_1.h。如果你在头文件里定义了结构体或者类类型,那么问题来了,编译时将会报重复定义的错误。

加上条件编译"ifndef"则问题可解决。在headfile_1.h中加上条件编译,如下:

headfile_1.h

 1 #ifndef _HEADFILE_1_H2 #define _HEADFILE_1_H3 #include <iostream>4 class CTest_1 {5     CTest_1() {6         //do something,eg:init;7     }8     ~CTest_1() {9         //do something ,eg:free;
10     }
11     void PrintScreen()
12     {
13         std::cout << "this is Class CTest_1!" << std::endl;
14     }
15 };
16 
17 #endif    //end of _HEADFILE_1_H

编译通过!

分析:当第一次包含headfile_1.h时,由于没有定义_HEADFILE_1_H,条件为真,这样就会执行#ifndef _HEADFILE_1_H和#endif之间的代码;当第二次包含headfile_1.h时,前面一次已经定义了_HEADFILE_1_H,条件为假,#ifndef _HEADFILE_1_H和#endif之间的代码也就不会再次被包含,这样就避免了重定义。

小结:还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你最好都加上这个。一般格式是这样的:

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

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

#ifndef _STDIO_H
#define _STDIO_H............#endif

注意:#ifndef起到的效果是防止一个源文件多次包含同一个头文件,而不是防止两个源文件包含同一个头文件。事实上,防止同一头文件被两个不同的源文件包含这种要求本身就是不合理的,头文件存在的价值就是被不同的源文件包含。

二、便于程序的调试和移植
  在调试程序时,常常需要对程序中的内容进行选择性地编译,即可以根据一定的条件选择是否编译。

主要分以下几种:

1、

#ifndef 标识符程序段 1#else程序段 2#endif

它的作用是当“标识符”没有由#define定义过,则编译“程序段1”,否则编译“程序段2”。

2、

#ifndef 标识符#define 标识符程序段 1#else程序段 2#endif

它的作用是当“标识符”没有由#define定义过,则编译“程序段1”,否则编译“程序段2”。

3、

#if 表达式程序段 1#else程序段 2#endif

它的作用是当“表达式”值为真时,编译“程序段1”,否则编译“程序段2”。

注:以上三种形式中#else不是强制的,可省略;当然,当#else后需要嵌套#if时,可以使用预处理命令#elif,它相当于#else#if。

小结:在程序中使用条件编译主要是为了方便程序的调试和移植。

转载自:https://www.cnblogs.com/codingmengmeng/p/7221295.html


http://chatgpt.dhexx.cn/article/aSsgOuiX.shtml

相关文章

禁用swap分区

禁用swap分区 1.进入系统右击鼠标点击“在终端中打开” 2.输入命令 sudo vim /etc/fstab 编辑fstab文件 3.键盘输入 i 进入插入模式就可以对文件进行编辑了 4.将UUIDxxx… swap那一行的最前面添加 # 把这行注释 5.编辑好后按键盘 Esc 退出插入模式 6.键盘输入 :wq 来保存退…

Centos7 关闭swap分区

安装K8S需要关闭swap分区 注释/etc/fstab关于swap的配置 Esc键 :wq 退出。 reboot重启生效 开机后free -m校验

swap分区管理方法

swap分区管理方法 一、内存的认识二、SWAP分区作用&#xff08;内存暂存的地址-硬盘&#xff09;三、swap分区大小建议四、swap管理4.1创建swap分区4.2swap临时调整优先级4.2swap永久调整优先级 五、删除swap分区 一、内存的认识 内存很贵 内存与硬盘的差距 /dev/shm 就是内存…

如何修改swap分区大小

测试环境&#xff1a; 依赖组件版本cdh版本5.13操作系统版本centos 6.9 问题现象&#xff1a; 因为是在虚拟机中搭建cdh大数据平台&#xff0c;虚拟机内存大小为4G&#xff0c;性能不足&#xff0c;导致cloudera-manager 服务频繁挂掉。 解决思路&#xff1a; 通过增加交换…

SWAP分区的讲解与命令使用

swap分区&#xff08;交换分区&#xff09; &#xff1a;交替存换&#xff0c;映射关系&#xff0c;映射结束后&#xff0c;内核剪断映射&#xff0c;当下次再需要进入映射的时候&#xff0c;在重新指向新的映射。 虚拟内存 &#xff1a;物理内存无法满足需要&#xff0c;衍生…

linux swap交换分区

一、当我们用free -h命令&#xff0c;查看服务器内存情况时&#xff0c;可以看到mem和swap两行。 mem行是从系统角度看来内存使用的情况&#xff0c;total是系统可用的内存大小&#xff0c;数量上等于系统物理内存减去内核保留的内存。 buffers和cached是系统用做缓冲的内存。…

Centos7设置swap分区

前言 Swap分区&#xff0c;即交换区&#xff0c;系统在物理内存&#xff08;运行内存&#xff09;不够时&#xff0c;与Swap进行交换。 其实&#xff0c;Swap的调整对Linux服务器&#xff0c;特别是Web服务器的性能至关重要。通过调整Swap&#xff0c;有时可以越过系统性能瓶颈…

linux系统中swap分区的介绍以及处理swap分区被占满的情况

linux分区一般来说是较为灵活的&#xff0c;一般还会单独分出一个交换分区(也就是swap分区)&#xff0c;这个分区是用于在物理内存不够用的情况下来帮助承担存储程序所需内存的任务&#xff0c;现在很多的电脑或者服务器的内存都是较大的&#xff0c;所以一般swap分区都不会派上…

swap分区扩展的三种方法

1. 交换分区扩容方法&#xff1f; 1.1 三种方法 &#xff08;1&#xff09;扩展正在使用的swap分区的逻辑卷&#xff08;推荐&#xff09; &#xff08;2&#xff09;新建swap分区 &#xff08;3&#xff09;新建swap file 1.2 示例 准备工作&#xff1a; &#xff08;1…

Linux之使用SWAP分区

通常我们能够在各大服务器商的网站上能够看到服务器的租赁价格主要与带宽、CPU以及内存这三个参数关联度较高&#xff0c;因此初用Linux服务器的朋友们可能开始买的配置都不会很高。但如果你在服务器上部署了较多的服务导致内存不够该怎么办呢&#xff1f;这个时候SWAP该上场了…

linux swap 内存交换分区 详细介绍

目录 1、什么是SWAP&#xff0c;到底是干嘛的&#xff1f; 为什么要进行内存回收&#xff1f; 会回收的两种内存 2、swappiness到底是用来调节什么的&#xff1f; 那么这个swappiness到底起到了什么作用呢&#xff1f; 3、kswapd什么时候会进行swap操作&#xff1f; 4、…

swap分区详解(创建swap分区,启用swap交换空间,关闭swap交换空间)

文章目录 swap分区什么是swap分区swap分区使用情况查看工具free案例 swapon 创建swap分区过程 swap分区 什么是swap分区 swap分区是指在Linux操作系统中为了提高系统运行效率而设置的一块特殊的硬盘空间&#xff0c;也称为虚拟内存。当系统内存不足时&#xff0c;会将一部分不…

Linux基础-Swap分区

博客主页&#xff1a;Passerby_Wang的博客_CSDN博客-系统运维,云计算,Git学习笔记领域博主 &#x1f310;所属专栏&#xff1a;『Linux基础』 &#x1f4f0;如觉得博主文章写的不错或对你有所帮助的话&#xff0c;还望大家多多支持呀&#xff01; 关注、点赞、收藏、评论。 目录…

保姆级swap分区详解!手把手带你创建swap分区(两种方式,建议收藏)涉及fdisk、gdisk、df、parted、partprobe、mkswap、swapon、free、dd、od等命令

Swap分区的详解 && 创建 什么是swap分区&#xff1f;方法一&#xff1a;使用物理分区创建Swap分区1. 利用fdisk / gdisk在磁盘上划出一个分区1.1 lsblk —— 查看本机的磁盘分区基本情况1.2 df 命令 —— 查看磁盘空间利用率1.3 parted命令 —— 列出磁盘的分区表类型与…

JAVA 类和对象的实例

JAVA 类和对象的实例 什么是类&#xff1f; 1. 类是具有相同的属性和功能的事物的抽象的集合&#xff0c;在面向对象程序设计中&#xff0c;人们把一类事物的静态属性和动态可以执行的操作组合在一起就得到类这个概念。 2. 类是个抽象的概念&#xff0c;用来模拟一类事物&…

c++类和对象(类的概念)

1.类和对象概念 类&#xff1a;用来对实体&#xff08;对象&#xff09;进行描述&#xff0c;对象有什么属性&#xff0c;以及对象具有什么功能是一种自定义类型 对象&#xff1a;现实生活中所存在的 &#xff0c;对象是对类的具体体现 用类类型创建出来的变量称为对象 2.类…

C++ 类和对象

类和对象 目录 类和对象 面向过程和面向对象的区别 类和对象 定义类的格式 定义类的方式 ​ 类的作用域 面向对象特性 封装 C程序设计中是如何体现封装性的 访问限定符 类的实例化 类的大小 this指针 this指针的特性 汇编角度来看this 函数参数调用约定 t…

【C++】类和对象(中)

类和对象是面向对象语言的一个重要部分&#xff0c;承接上一话&#xff0c;我们直接开始这一章的内容。 文章目录 一、类的6个默认成员函数二、构造函数三、析构函数四、拷贝构造函数五、赋值操作符重载六、 const成员函数七、取地址及const取地址操作符重载八、相关习题的练习…

类与对象的概述

一、 面向对象编程概述 类与对象的概念 类&#xff08;class&#xff09;与对象&#xff08;object&#xff09;是两种以计算机为载体的计算机语言的合称。类是对对象的抽象&#xff0c;对象是对客观事物的抽象。 它们二者的关系就是&#xff1a;类是对对象的抽象&#xff0c;…

strchr、strstr函数

二者都属于c的库函数 包含在<string.h>函数中 char msg_gps[100] {\0}; 不同的是 &#xff1a; strchr是查找单个字符在串中出现的位置 strstr查找的是字符串在串中出现的位置 看代码&#xff1a; //strchr 查找字符在串中第一次出现的位置 输出在此到最后的所有字符…