ifndef 详解

ifndef 详解原博文 https www cnblogs com codingmengme p 7221295 html ifndef 是 ifnotdefined 的简写 是预处理功能 宏定义 文件包含 条件编译 当中的条件编译 可以根据是否已经定义了一个变量来进行分支选择 其作用是 1 防止头文件的重复包含和编译 2 便于程序的调试和移植 下面分别举例描述 一 防止头文件的重复包含和编译下面是错误示范 headfile 1 h include

原博文:https://www.cnblogs.com/codingmengmeng/p/7221295.html

#ifndef 是”if not defined”的简写,是预处理功能(宏定义、文件包含、条件编译)当中的条件编译,可以根据是否已经定义了一个变量来进行分支选择,其作用是:

  1、防止头文件的重复包含和编译;

  2、便于程序的调试和移植;

  下面分别举例描述。

一、防止头文件的重复包含和编译

下面是错误示范:


headfile_1.h

#include 
   
     class CTest_1 { CTest_1() { //do something,eg:init; } ~CTest_1() { //do something ,eg:free; } void PrintScreen() { std::cout << "this is Class CTest_1!" << std::endl; } }; 
   

headfile_2.h

#include "headfile_1.h" class CTest_2 { CTest_2() { //do something,eg:init; } ~CTest_2() { //do something,eg:free; } void PrintScreen() { std::cout << "this is Class CTest_2!" << std::endl; } };

sourcefile.cpp

#include 
   
     #include "headfile_1.h" #include "headfile_2.h" int main() { return 0; } 
   

编译时提示重定义错误:

ifndef 详解


  以上显示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

#ifndef _HEADFILE_1_H #define _HEADFILE_1_H #include 
    
      class CTest_1 { CTest_1() { //do something,eg:init; } ~CTest_1() { //do something ,eg:free; } void PrintScreen() { std::cout << "this is Class CTest_1!" << std::endl; } }; #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://javaforall.net/208336.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 上午11:49
下一篇 2026年3月19日 上午11:49


相关推荐

  • android psd预览图软件,来自psd的Android Vector drawable具有空预览

    android psd预览图软件,来自psd的Android Vector drawable具有空预览在屏幕截图中,文件中没有pathdata.因此,屏幕上没有任何内容.我正在显示VectorDrawablexml文件的内容.将内容复制到androidstudio中的空白xml文件中,并在屏幕上看到蓝色绘制的形状.android:width=”600dp”android:height=”600dp”android:viewportWidth=”800.0″android:viewportHei…

    2022年5月3日
    49
  • A股30年历史的拐点和暗示(大盘篇)

    A股30年历史的拐点和暗示(大盘篇)转A股30年,历史的拐点和暗示(大盘篇)来源:主动型量化   作者:刘帅路————————————————————————————–拓展阅读:1.集合竞价选股2.七种量化选股模型…

    2022年6月23日
    52
  • rabbitMQ与activeMQ区别

    rabbitMQ与activeMQ区别rabbitMQ 与 activeMQ 区别之前的项目中都用到了这两个消息队列 因此总结一下它们的不同之处 做一个笔记 下次需要的时候再行参考 概念为什么使用消息队列六个字 异步 解耦 削峰 使用了消息队列会有什么缺点一个使用了 MQ 的项目 如果连这个问题都没有考虑过 就把 MQ 引进去了 那就给自己的项目带来了风险 我们引入一个技术 要对这个技术的弊端有充分的认识 才能做好预防 要记住 不要给公司挖坑 从以下两个个角度来考虑 系统可用性降低 你想啊 本来其他系统只要运行好好的 那你的系统就是正常的 现

    2025年7月8日
    6
  • uva 10825 – Anagram and Multiplication(暴力)

    uva 10825 – Anagram and Multiplication(暴力)

    2022年1月9日
    57
  • Windows系统CUDA10.2+CUDNN安装教程

    Windows系统CUDA10.2+CUDNN安装教程Win10系统下如何安装CUDA10.2已经对应的CUDNN。

    2022年5月2日
    38
  • linux下gdb调试方法与技巧整理「建议收藏」

    linux下gdb调试方法与技巧整理「建议收藏」目录一、gdb简介二、gdb使用流程1、启动gdb2、查看源码3、运行程序4、设置断点5、单步执行6、查看变量7、退出gdb三、gdb基本使用命令1、运行命令2、设置断点3、查看源码4、打印表达式5、查看运行信息6、分割窗口7、cgdb强大工具四、总结一、gdb简介GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。对于一名Linux下…

    2022年5月25日
    74

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号