#ifndef#define#endif防止头文件重复包含, 你不是真的懂

STM32Cubemx+CanFestival:从零到一的CANopen移植实战 本文详细介绍了如何使用STM32CubeMX和CanFestival实现CANopen协议栈的移植,从开发环境搭建到核心配置步骤,再到调试与问题排查。通过实战经验分享,帮助开发者快速掌握STM32与CANopen的结合应用,提升嵌入式系统开发效率。 阅读详情

注:以下所用环境皆为VS2005, 由于本人编程能力及表达能力有限, 大家有看不懂的地方可以多看几遍,有错误地方请一定指出  

 

这里首先说明下几点基础知识, 相信大部分人对于以下几点大部分都已经知道了, 你也可以直接跳到最后部分看#ifndef#define#endif的真正作用

  1.预编译阶段把所有#include ”***.h“ (“”与<>的区别这里就不说了)用***.h的内容来替换了, 所以之后就没有.h了所有.h的内容都已经包含进了需要它们的.cpp中(注:该步个人认为是发生在预编译阶段) 

  2.生成最后的exe文件是由编译、链接两步完成的, 编译是源代码生成obj二进制目标文件的过程, 注意一个源代码文件(指.cpp, 而非.h, .h已经被包含进.cpp中了)生成一个obj文件, 在VS2005中单独编译一个obj的方法是选中该.cpp文件ctrl+f7, 文章中以下所说的编译皆按该方法执行而非F7, 由于编译是独立的, 所以在两个独立的编译单元里是可以有重名的函数的, 例如a.cpp中可以有一个void fun(); b.cpp中可同时有一个void fun(); 这点十分重要, 大家可以试一下并且理解清楚

  3.编译期间, 我们只要声明了的东西就能使用, 而无需它的定义, 声明可以重复, extern在编译时是告诉该编译单元该变量的定义在别的编译单元里, 相当于声明, 链接时, 定义在整个程序中有且仅有一份,  例如如下代码, 编译可通过, 但链接时失败

[cpp]  view plain copy
  1. extern int a;  
  2. //extern double a;//错误, a只能有一个类型  
  3. extern int a;  
  4. extern void fun1(int a, int b);  
  5. extern void fun1(int a, int b);  
  6. extern void fun1(int a, int b, int c);//函数重载  
  7. void fun2();  
  8. void fun2(int a);//函数重载  
  9. void fun2()  
  10. {  
  11. }  
  12. int main()  
  13. {  
  14.     a = 100;  
  15.     fun1(200, 300);  
  16.     fun2();  
  17.     fun2(100);  
  18.     return 0;  
  19. }  
  20. void fun2();  
 

 

 

  4.我们从语法上来分析下#ifndef#define#endif(这点相信地球人都知道了)

[cpp]  view plain copy
  1. //-----a.h-----  
  2. #ifndef A_H_  
  3. #define A_H_  
  4. void fun();  
  5. #endif  
 

预编译阶段, 当第一次执行该段代码(即#include "a.h",参见第一条)时, 由于我们并没有宏定义A_H_, 所以会执行#define A_H_以及void fun()两条语句, 第二次执行该段代码时因为#ifndef A_H_为假就直接走到#endif后面也就等于该次#include "a.h"什么也没做了

 

总结:

好了, 下面就我们以上所学的知识来总结一下, 来纠正大家一直以来对#ifndef#define#endif的误解

当我们一个简单的project中有三个文件main.cpp, a.cpp, a.h,而 main.cpp 和a.cpp分别包含了a.h, 在编译阶段, 两个编译单元是都会分别包含a.h的, 即使他们使用了#ifndef#define#endif, 这也是为什么当a.h被多个文件包含时我们不允许在a.h中定义变量及函数的原因, 因为在链接阶段会出现重定义。 但是在a.h中定义一个static变量却是允许的, 因为static变量是模块性作用域, 就这个例子来说, 若我们在a.h中写static int sss = 0;那么main.cpp与a.cpp使用的sss将为2个独立的sss.

那么是否#ifndef#define#endif就没用了呢, 大家可以想想, 当我们a.cpp中写了多个#include "a.h"时, 如果我们使用了#ifndef#define#endif那么预编译阶段就只会包含一个a.h中的内容到a.cpp中, 你也许会说, 有谁会傻到在a.cpp中写多个#include "a.h"呢, 那么请考虑稍微复杂点的情况, 当我们main.cpp中包含了a.h和b.h, 而a.h中我们又包含了b.h, 那么如果我们使用了#ifndef#define#endif则main.obj只会包含一份b.h

VisionPro开发实战:CogRecordDisplay控件显示与保存图片的完整流程(附C#代码示例) 本文详细解析了VisionPro开发中CogRecordDisplay控件的图像处理全流程,包括图像加载、显示优化、动态清屏及结果保存等关键操作。通过C#代码示例,展示了如何高效使用该控件进行工业视觉应用开发,特别适合自动化检测系统的开发者参考。 阅读详情

相关推荐

法兰克仿真软件FANUC CNC Guide v25.0 安装教程及中文设置

下载地址在文末。我们公司用新到一批FANUC 系统的设备,为方便使用就装了一个 FANUC 数控系统仿真软件FANUC CNC Guide v25.0 ,还是最新版不是市面上流传的老版本。模拟学习一下。

hakesashou的博客 1万+

#ifndef#define#endif

参考:http://blog.youkuaiyun.com/q191201771/article/details/6399820 这里首先说明下几点基础知识, 相信大部分人对于以下几点大部分都已经知道了, 你也可以直接跳到最后部分看#ifndef#define#endif的真正作用   1.预编译阶段把所有#include ”***.h“ (“”与替换了, 所以之后就没有.h了所有.h的内容都已经

行者 1236

别再只用LSTM了!用Temporal Fusion Transformer (TFT) 搞定多变量时序预测,附PyTorch实战代码

本文介绍了Temporal Fusion Transformer (TFT) 在多变量时序预测中的优势,并提供了PyTorch实战代码。TFT通过三重注意力机制解决了LSTM在特征交互、静态特征处理和解释性方面的不足,显著提升了预测精度和可解释性。文章详细讲解了TFT的核心组件构建、数据预处理、模型训练技巧及可解释性分析,帮助开发者快速掌握这一先进时序预测技术。

weixin_33712987的博客 279

#ifdef #define #endif (避免头文件被重复包含的真正含义)

条件编译,避免重复包含头文件。

安卓 高通 bsp ,同行欢迎交流 3310

【论文阅读笔记】One Shot 3D Photography

论文主页:https://facebookresearch.github.io/one_shot_3d_photography/ 代码地址:https://github.com/facebookresearch/one_shot_3d_photography   该3D照片方向,由于刚入门,所以会倾向于翻译文章。每个操作上的选择,及为什么不进行另外操作的原因都如数放上。 论文小结   本作的工作是从单张RGB图片生成一个移动视角的3D照片。   其管道大致如下: 由RGB图像通过单目深度估计网络估计深度图

时光机 °的博客 1840

组合导航、惯导、GNSS、INS、IMU的区别

‌:惯性导航系统(INS)是一种利用安装在运载体上的陀螺仪和加速度计来测定运载体位置的系统。它通过测量物体的加速度和角速度,结合算法计算出物体的位置、速度和姿态‌12。‌。

wynn1123的博客 8058

#ifndef详解

由于担心文章不见了,所以进行了转载: https://home.cnblogs.com/u/2454253 #ifndef 是"if not defined"的简写,是预处理功能(宏定义、文件包含、条件编译)当中的条件编译,可以根据是否已经定义了一个变量来进行分支选择,其作用是: 1、防止头文件的重复包含和编译; 2、便于程序的调试和移植; 下面分别举例描述。 一、防止头文件的重复包含和编译 下面是错误示范: headfile_1.h 复制代码 1 #include 2 class CTest_1 { 3

weixin_46721287的博客 1万+

ubuntu20.04安装UE4+Airsim环境

版本UE4.27+Airsim1.81

玖茸的博客 3380

ifndef详解

ifndef详解 #ifndef 是"if not defined"的简写,是预处理功能(宏定义、文件包含、条件编译)当中的条件编译,可以根据是否已经定义了一个变量来进行分支选择,其作用是: 防止头文件的重复包含和编译; 便于程序的调试和移植; 下面分别举例描述。 一、防止头文件的重复包含和编译 下面是错误示范: headfile_1.h 1 #include <iostream> 2 class CTest_1 { 3 CTest_1() { 4 //do

weixin_42692164的博客 5万+

cellranger安装以及使用

接受cellranger count的输出数据,将同一组的不同测序样本的表达矩阵整合在一起,比如tumor组原来有4个样本,PBMC组有两个样本,现在可以使用aggr生成最后的tumor和PBMC两个矩阵,并且进行标准化去掉测序深度的影响。但是由于病毒基因组太小了,且注释结果只有CDS没有exon,所以曲线救国,将CDS整体替换为exon,也不进行过滤了,直接下一步。虽然安装完毕,但是现在要运行cellranger的话需要在终端输入cellranger的整个路径。自动执行这个命令,需要将“

m0_59974475的博客 9397

C#与欧姆龙PLC 通信——Fins Tcp协议

该调试助手专门为了帮助大家学习以及测试Fins-Tcp通信,下面进行详细介绍。

qq_34059233的博客 2087

防止头文件重复包含之pragma once与#ifndef

在我们自己编写 C/C++的头文件时,可能会忽略一点:用一些处理机制来避免头文件的重复包含,因为头文件的内容在编译 #pragma once #ifndef #define #endif

ljx_5489464的博客 1002

使用自己的数据跑通mmsegmentation

使用自己的数据跑通mmsegmentation,解决以下报错:1)type object 'FileClient' has no attribute 'infer_client' 2)It is expected output_size equals to 2, but got size 3 3)训练测试结果报NAN 4)KeyError: 'MyDataset is not in the dataset registry' 5)预训练模型和加载的网络结构层名有差异,unexpected key .....

猫猫与橙子的博客 1657

#ifndef#define#endif防止头文件重复包含

#ifndef#define#endif防止头文件重复包含

huaweitman的专栏 843

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

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

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

防止头文件被重复包含

注:以下所用环境皆为VS2005, 由于本人编程能力及表达能力有限, 大家有看不懂的地方可以多看几遍,有错误地方请一定指出     这里首先说明下几点基础知识, 相信大部分人对于以下几点大部分都已经知道了, 你也可以直接跳到最后部分看#ifndef#define#endif的真正作用   1.预编译阶段把所有#include ”***.h“ (“”与替换了, 所以之后就没有.h了所有.h的内

bai_lu_sz的专栏 613

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

c语言调用头文件函数要定义吗,C语言中头文件是如何包含的?也说重定义

随着代码越写越长,一个源文件的体制越来越臃肿。于是提倡将代码写到不同的多个源文件中去。将代码写到多个源文件中去就会遇到各个源文件中函数与变量的调用规则问题。通常人们习惯性的把宏定义、结构体、联合体、枚举、外部变量和外部函数声明等写入到头文件.h中去,而把函数的声明、变量定义等写入到.c文件中去。当某一.c源文件需要调用某一函数的时候,只要将包含这个函数声明的头文件包含到本文件中来就可以了。如a.h...

weixin_39945789的博客 1614

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

c/c++头文件

对c/c++中头文件的作用以及头文件的内容进行阐述

qq_44905857的博客 7775

[C++] C++中避免头文件重复包含的方法

一、ifndef define endif 可能会有定义的宏名碰撞的情况 会检查内容 二、pragma once 如果相同文件存在两份,无法保证不重复 [1] http://blog.youkuaiyun.com/id19870510/article/details/5315772 转载于:https://www.cnblogs.com/deepblueme/p/4804206.html...

weixin_30249203的博客 117

#ifndef#define#endif的用法

#ifndef 标示1 //判断"标示1"是否定义,如果被定义则返回假,如果没有被定义则返回真。   /**********************************/   语句1 #ifndef 标示1     语句2 #define 标示1   语句3 #endif   语句4 ……   语句5 …… 该段代码意思是:如果标示1没有被定义,则重定义标示1,即执行语...

a53203556的博客 358

C语言重包含,C语言中头文件是如何包含的?也说重定义

随着代码越写越长,一个源文件的体制越来越臃肿。于是提倡将代码写到不同的多个源文件中去。将代码写到多个源文件中去就会遇到各个源文件中函数与变量的调用规则问题。通常人们习惯性的把宏定义、结构体、联合体、枚举、外部变量和外部函数声明等写入到头文件.h中去,而把函数的声明、变量定义等写入到.c文件中去。当某一.c源文件需要调用某一函数的时候,只要将包含这个函数声明的头文件包含到本文件中来就可以了。如a.h...

weixin_36196497的博客 455

头文件使用#ifndef#define #endif的好处及原因

宏定义 #ifndef #define #endif 最主要目的是防止头文件的重复声明和编译 #ifndef __TEST_H__ #denfine __TEST_H__ #endif __TEST_H__ ifndef 指示会发现TEST已经定义返回假,并且忽略该头文件的剩余部分。 引用宏定义 #ifndef 为了防止在执行时对头文件进行重复的编译和声明,...

HiMark 877
上一篇: #ifndef #define #endif
下一篇: perror
Codelee1995
博客等级 码龄12年 3粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值