#ifndef #define #endif

fatal error C1020: 意外的 #endif 初学openCV,试着网上的例程在本机跑一遍,遇到问题种种,于是乎记录下来以备翻阅。对于VS2008,一个解决方案下可以建立多个工程,但不爽之处在于——1. 宽字节的处理    修改工程属性中->配置属性->常规中“字符集”选项中默认为“使用UNICODE 字符集”,每个工程都需手动修改为“使用多字节字符集”2. linker附加依赖项 (外部库)    每个工程手动设置属性- 阅读详情

       今天开始看了一下林锐博士的《高质量C++/C编程指南》,感觉自己的这点东西什么都不是,要学的东西太多了,不禁感叹!哎,没办法,好好学吧!

       这本书开始提到了为了防止头文件被重复引用,应当用ifndef/define/endif 结构产生预处理块。于是搜了一下相关内容,发现整理得不错,就转了过来!感谢作者!

#ifndef#define#endif的用法

 

文件中的#ifndef

    头件的中的#ifndef,这是一个很关键的东西。比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。

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

    #ifndef <标识>

    #define <标识>

    ......

    ......

    #endif

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

    #ifndef _STDIO_H_

    #define _STDIO_H_

    ......

    #endif

在#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中定义

    <x.h>

    #ifndef __X_H__

    #define __X_H__

    extern int i;

    #endif //__X_H__

    <x.c>

    int i;

    注意问题:

    变量一般不要定义在.h文件中。

    一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。

条件编译命令最常见的形式为:

    #ifdef 标识符

    程序段1

    #else

    程序段2

    #endif

    

    它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。

    其中#else部分也可以没有,即:

    #ifdef

    程序段1

    #denif

    

    这里的“程序段”可以是语句组,也可以是命令行。这种条件编译可以提高C源程序的通用性。如果一个C源程序在不同计算机系统上系统上运行,而不同的计算机又有一定的差异。例如,我们有一个数据类型,在Windows平台中,应该使用long类型表示,而在其他平台应该使用float表示,这样往往需要对源程序作必要的修改,这就降低了程序的通用性。可以用以下的条件编译:

    #ifdef WINDOWS

    #define MYTYPE long

    #else

    #define MYTYPE float

    #endif

    

    如果在Windows上编译程序,则可以在程序的开始加上

    #define WINDOWS

    

    这样则编译下面的命令行:

    #define MYTYPE long

    

    如果在这组条件编译命令之前曾出现以下命令行:

    #define WINDOWS 0

    

    则预编译后程序中的MYTYPE都用float代替。这样,源程序可以不必作任何修改就可以用于不同类型的计算机系统。当然以上介绍的只是一种简单的情况,可以根据此思路设瞥?a href="javascript:;" onClick="tagshow(event, '%C6%E4%CB%FC');return false;">其它的条件编译?

    例如,在调试程序时,常常希望输出一些所需的信息,而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段:

    #ifdef DEBUG

    print ("device_open(%p) ", file);

    #endif

    

    如果在它的前面有以下命令行:

    #define DEBUG

    

    则在程序运行时输出file指针的值,以便调试分析。调试完成后只需将这个define命令行删除即可。有人可能觉得不用条件编译也可达此目的,即在调试时加一批printf语句,调试后一一将printf语句删除去。的确,这是可以的。但是,当调试时加的printf语句比较多时,修改的工作量是很大的。用条件编译,则不必一一删改printf语句,只需删除前面的一条“#define DEBUG”命令即可,这时所有的用DEBUG作标识符的条件编译段都使其中的printf语句不起作用,即起统一控制的作用,如同一个“开关”一样。

    有时也采用下面的形式:

    #ifndef 标识符

    程序段1

    #else

    程序段2

    #endif

    

    只是第一行与第一种形式不同:将“ifdef”改为“ifndef”。它的作用是:若标识符未被定义则编译程序段1,否则编译程序段2。这种形式与第一种形式的作用相反。

    以上两种形式用法差不多,根据需要任选一种,视方便而定。

    还有一种形式,就是#if后面的是一个表达式,而不是一个简单的标识符:

    #if 表达式

    程序段1

    #else

    程序段2

    #endif

    

    它的作用是:当指定的表达式值为真(非零)时就编译程序段1,否则编译程序段2。可以事先给定一定条件,使程序在不同的条件下执行不同的功能。

    作用范围就是当前文件啊。因为编译是以cpp或c文件位单位的嘛。还以这个为例:

    //正常代码

    #ifdef _DEBUG

         TRACE("Some infomation");

    #else

         //Now is release version,so do nothing

    #endif

    //正常代码

    编译时是先把所有的预编译处理展开(比如宏)再编译,所以Debug模式下,编译时的代码是:

    //正常代码

    TRACE("Some infomation");

    //正常代码

    Release模式下的代码是:

    //正常代码

    //正常代码

Qt开发实战:QWebEngineView缓存路径详解与自定义配置(Windows/Linux) 本文详细解析了Qt框架中QWebEngineView组件的缓存机制,提供了Windows和Linux系统下的默认缓存路径及自定义配置方案。通过实战代码示例,展示了如何实现跨平台缓存路径管理、权限设置以及企业级应用中的多用户隔离策略,帮助开发者有效管理Web内容缓存,提升应用性能和数据安全性。 阅读详情

相关推荐

AVEVA PDMS 二次开发之PML实战:从宏到自定义窗体的效率提升

本文详细介绍了AVEVA PDMS二次开发中PML语言的应用,从基础宏编写到高级窗体开发,全面提升工程设计效率。通过实战案例展示如何利用PML实现批量操作、流程自动化和交互优化,帮助工程师快速掌握这一强大工具。

weixin_42549451的博客 341

vs编译报错C1020: 意外的 #endif

      生成vs项目解决方案时出现了错误如下: C1020: 意外的 #endif 普遍解决方案       各种百度,给出的解决方案都是在.cpp文件第一条语句加:#include “stdafx.h”,       报错写法: #include "cv.h" #include "cxcore.h" #include "h

duiwangxiaomi的博客 5145

阿里云Windows服务器部署网站全流程:从IIS配置到安全上线

Web服务器是承载网站应用、处理HTTP请求的核心软件。其工作原理是监听特定网络端口,接收客户端请求,并返回相应的网页、文件或动态生成的内容。在Windows Server环境中,IIS(Internet Information Services)作为微软官方Web服务器,凭借其与操作系统深度集成、图形化管理界面和对ASP.NET等微软技术栈的良好支持,成为许多开发者和运维人员的首选。其技术价值在于提供了稳定、可扩展的托管平台,支持从简单的静态网站到复杂的企业级Web应用。在云服务器普及的今天,将IIS部署

weixin_33552698的博客 327

C1020: 意外的 #endif

对于“ fatal error C1020: 意外的 #endif ”错误,原因大致如下:   如果使用了预编译头,VC会在所有CPP文件里寻找 #include   "stdafx.h " 在找到这行代码之前,VC会忽略所有代码。 也就是说,下例中,VC 找到第二行 #include "stdafx.h" 之前,会将第一行#ifndef _EiC 忽略掉,因此出现“意外的 #end

dasgk的专栏 6301

动态对抗Zygisk-IL2CppDumper:Unity游戏安全新策略

本文深入探讨了对抗Zygisk-IL2CppDumper攻击的Unity游戏安全新策略。通过实时内存监控、动态混淆技术和异常行为检测体系,有效防止关键代码被动态提取。文章详细介绍了内存指纹系统、运行时混淆方案和五维特征模型等实用防御手段,帮助开发者提升游戏安全性。

weixin_29325955的博客 306

VHDL按键消抖(状态机版本)

检测下降沿:设置一个和,分别代表之前的之前和之前的信号状态,若两个信号key_in_d2=1,key_in_d1=0,他俩的not key_in_d2 and key_in_d1为1,则说明下降沿产生,把它设置为标志位key_flag。延时计数:50MHz的板子每次计数需要20ns,而抖动时间大约为5-10ms。所以取7ms,作为延时时间。可以看见当检测到下降沿时,开始计数计数计满再次检测,若为低电平则为按下按键,否则为抖动。通过检测下降沿来临,延时计数再次检测,如果为低电平则为按键按下。

qq_69639216的博客 1084

fatal error C1020: 意外的 #endif

由于项目需求使用条件编译(#ifdef,#ifndef)将整个cpp文件屏蔽: #ifdef _SWITCH_ON_ #include "stdafx.h" //具体代码省略 #endif 编译后报错: fatal error C1020: 意外的 #endif 导致这个原因是因为...

chihewanle2015的博客 707

车载网络测试实操源码_使用CAPL解析VBF文件

VBF(Versatile Binary Format)文件是一种二进制文件格式,被沃尔沃、福特、马自达、吉利等汽车制造商广泛采用。这种格式无法使用我们常规的烧录器进行刷写,通常需要进行解析转化。如果各位需要自己编写软件或脚本来刷写VBF文件,或者需要对刷写功能进行测试时,那么本篇文章就会对你非常有用。今天我们就来讲一下如何使用CAPL脚本对VBF文件进行数据解析。VBF文件包含三部分:VBF版本段、文件头段、数据段。前面的版本段和文件头段是ASCII码,包含版本、地址、校验码等信息

文章主要涉及嵌入式软件开发、测试、项目管理等,欢迎交流,共同进步。 2999

fatal error C1020:意外的#endif,意外的#else,LF/CRLF问题,与异常的编译错误

在正常的代码的情况下,出现上述的错误或者是奇怪的错误,或者是不应该报错的地方,基本上都可以认为是文件编码/换行符的问题

大全麦的博客 2024

Open3D 计算点云的倒角距离(Chamfer Distance)【2025最新版】

;Chamfer Distance距离可以计算生成点云数据与标签点云数据之间的平均最短点距离。Open3D可以直接用来计算点云的Chamfer Distance距离。博客长期更新,本文最近一次更新时间为:2025年2月18日。

点云侠的博客 3254

STM32实战开发(76):STM32开发无线传感器网络(WSN)完整实现

本文介绍了如何基于STM32开发无线传感器网络,包括硬件选择、通信协议、系统设计和编程实现。通过STM32的强大性能和低功耗特性,我们能够构建高效、可靠的无线传感器网络。无论是Zigbee、LoRa、Wi-Fi还是BLE协议,STM32都能够与多种通信模块进行兼容,满足不同应用的需求。希望这篇文章能帮助您了解无线传感器网络的构建流程,并为您的项目提供有价值的参考。

2201_76125393的博客 1059

【#ifndef, #define, 和 #endif】

ifndef它是i的简写,是宏定义的一种,确切的说是预处理功能(宏定义、文件包含、条件编译)三种中的一种——条件编译。使用#ifndef可以避免以下错误:如果在.h文件中定义了全局变量,一个C文件包含了.h文件多次,如果不加#ifndef宏定义,会出现变量重复定义的错误;如果加了#ifndef则不会出现这种错误。#ifndef:如果未定义)用于判断指定的标识符是否已经被定义。如果该标识符未定义,则执行下面的代码块,否则跳过。#define: 用于定义指定的标识符,通常用于定义宏。

weixin_61639290的博客 9217

华为OD机试双机位C卷-统计差异值大于相似值二元组个数(C/C++/Py/Java/Js/Go)

华为OD机试(机考)双机位C卷 【统计差异值大于相似值二元组个数】,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试 - 统计差异值大于相似值二元组个数

qq_45776114的博客 784

#ifndef/#define/#endif使用详解

https://blog.csdn.net/abc5382334/article/details/18052757     想必很多人都看过“头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用”。但是是否能理解“被重复引用”是什么意思?是不能在不同的两个文件中使用include来包含这个头文件吗?如果头文件被重复引用了,会产生什么后果?是不是所有的头文件中都要加入#ifndef/#define/#

她依然向往着长岛的雪 5575

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

#ifndef, #define, #endif作用

条件指示符#ifndef 的最主要目的是防止头文件的重复包含和编译 参考以下两个链接: #ifndef/#define/#endif使用详解 头文件为什么要加#ifndef #define #endif 其实“被重复引用”是指一个头文件在同一个cpp文件中被include了多次,这种错误常常是由于include嵌套造成的。比如:存在a.h文件#include "c.h"而此时b.cpp文件导入了#include "a.h"和#include "c.h"此时就会造成c.h重复引用。 几个重要.

lyh458的博客 1452

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

#ifndef #define #endif的用法 整理:shichenghua

  #ifndef#define#endif的用法

1万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

为什么.h文件里需要#ifndef、#define和#endif?

想必很多人都看过“头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用”。但是是否能理解“被重复引用”是什么意思?是不能在不同的两个文件中使用include来包含这个头文件吗?如果头文件被重复引用了,会产生什么后果?是不是所有的头文件中都要加入#ifndef/#define/#endif 这些代码? 其实“被重复引用”是指一个头文件在同一个cpp文件中被include了多次,这种错误常常是由于include嵌套造成的。比如:存在a.h文件#include "c.h"而此时b.cp

不畏将来,不念过往 2万+

#ifndef, #define, #endif 作用

@#ifndef, #define, #endif 作用 #ifndef   它是if not define 的简写,是宏定义的一种,实际上确切的说,这应该是预处理功能三种(宏定义、文件包含、条件编译)中的一种----条件编译。   在c语言中,对同一个变量或者函数进行多次声明是不会报错的。所以如果h文件里只是进行了声明工作,即使不使用# ifndef宏定义,多个c文件包含同一个h文件也不会报错。...

k751465326的博客 215

C++ #ifndef、#define、#endif作用

在C++项目中,#ifndef、#define、#endif非常常见,接下来就来简单说一下它们的作用。 作用:防止头文件被重复引用,防止被重复编译。 简介: #ifndef 它是if not define的简写,是宏定义的一种,确切的说是预处理功能(宏定义、文件包含、条件编译)三种中的一种——条件编译。 在C中,对同一个变量或函数多次声明是不会报错的。所以在.h文件中,即使不用#ifndef宏定义,多个文件包含同一.h文件也是不会报错的。 在C++中,#ifndef的作用域只是在单个文件中.所以如果

qq_37621623的博客 1613

C++宏:#ifndef, #define, #endif 作用

转载:https://www.cnblogs.com/challenger-vip/p/3386819.html #ifndef, #define, #endif 作用 #ifndef   它是if not define 的简写,是宏定义的一种,实际上确切的说,这应该是预处理功能三种(宏定义、文件包含、条件编译)中的一种----条件编译。   在c语言中,对同一个变量或者函数进行多次...

weixin_41516902的博客 921

C语言—#ifndef, #define, #endif

这个指令检查一个特定的宏(通常是一个标识符)是否未被定义。如果未定义,则执行紧随其后的代码。

xiaofeixia002X的博客 1660

#ifndef.#define, #endif 的用法

#ifndef.#define, #endif 的用法 文件中的#ifndef.#define, #endif 很关键,是为了避免多重包含,比如如果两个C文件同时包含同一头文件,那么就会出现问题,所以使用这种方法可以有效避免这种情况。 一般用法: 以add.h为例 1 #ifndef _ADD_H_ 2 #define _ADD_H_ 3 4 //在这里包含add.h的类定...

a1059682127的博客 324

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

C编程中#ifndef,#define,#endif的作用和用法笔记 **问题:**经常看到C中.h和.cpp等头文件中有ifndef/define/endif”标识,这是为何? **答:**主要目的是防止头文件的重复包含和编译 用法: .h文件,如下: #ifndef XX_H #define XX_H … #endif 这样如果有两个地方都包含这个头文件,就不会出现两次包含的情况 。。 因...

weixin_46254198的博客 709

C++中#ifndef, #define, #endif的作用和使用的注意事项

在C++语言编程中,我们经常会接触到头文件,比如说声明类,或者声明命名空间等,而每次在编写xxx.h的头文件时,编程书上都会让我们在代码的前后加上如下的三句代码: #ifndef XXX_H_ #define XXX_H_ …… #endif 其中……代表中间具体的功能语句。 那么这三句代码有什么作用呢?为什么每次自定义头文件时都要求加上呢? 其实这几句代码的主要作用的官方解释是:为了防...

清水河C罗——Leonardo-Liu 1万+

宏定义(#ifndef+#define+#endif)的作用

在头文件中,我们经常会在头文件中见到#ifndef、#define、#endif三者一起使用的宏定义。 例如,在头文件xxx.h中(此样式可参考): #ifndef __XXX_H__ #define __XXX_H__ #include <iostream> // 其他代码 #endif 使用#ifndef、#define、#endif组合宏定义的作用是:防止头文件的...

zpznba的博客 2393
上一篇: 家谱图-二叉树
下一篇: #ifndef#define#endif防止头文件重复包含, 你不是真的懂
Codelee1995
博客等级 码龄12年 3粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值