#define #include #undef的其中一个用法(目的)
一、背景
最近在跟一段系统级的代码,和原来单纯的下位机代码相比,真的是刘姥姥进大观园——看花了眼。相较于
之前所常见的各种下位机代码,系统级代码常常会出现深层次结构体嵌套,结构体内的各种回调函数导致对函数
指针的赋值调用也成为常态,以及各种各样的宏定义等等,均让人有一种眼前一亮、耳目一新的既视感。由于
对宏了解不多,也就对此处我在实际代码碰到过的#define,#include,#undef的使用的其中一个目的做个
记录。
二、正文
实际代码如下: #define _MCARO_1
#include "Myheadfile.h"
#undef _MACRO_1
紧接着的代码:
#define _MCARO_2
#include "Myheadfile.h"
#undef _MACRO_2 出现这段代码的作用即重复包含了两次头文件"Myheadfile.h",可意义在哪?接着跟头文件内的代码,
该头文件的作用是声明定义了一张类似于表格的变量,表格即是通过定义普通数组或者结构体数组来实现。而在
该头文件内出现了如下宏: #if defined (_MCARO_1)
···
对表格实际的各个变量的声明;
···
#elif defined (_MACRO_2)
···
对表格实际的各个变量的声明;
··· 从代码上来分析,重复包含两次头文件的意义就在于根据宏定义的不同来申请两种不同的变量。
以我碰到的实际代码来说,该工程实际上是要实现一个CANopen设备,CANopen设备通过对象字典来描述其功
能,以及通过对象字典来与外界交互,对象字典代码上实现就相当于一个表格,(关于CANopen对象字典以后会另外
开篇博客详述),在CANopen设备初始化的时候,CANopen设备会通过默认的对象字典来实现其预定义的功能,但在
CANopen设备实际运行起来时,又会按照不同的工业现场情况被CANopen主设备配置成适应当时需求的从设备,对象
字典内的参数也因此会被更改,但该设备被应用到其他场合时,它还是应该以默认的CANopen设备进行初始化。
上述代码既是实现了这种需求:
当其"define_MACRO_1"时,在该头文件内声明的变量空间为CANopen默认的对象字典参数。
当其"define_MACRO_2"时,在该头文件内声明的变量空间为CANopen实际运行的可被更改的对象字典参数。
两个对象字典参数并存于同一段代码中,而互不干涉。
因此,综上所述,#define,#include,#undef 在使用时,会在被包含的头文件内按照定义的宏进行特定的
操作,而同时再被包含时,由于宏的不同,其不会出现再次重复定义的错误。 再补充一个带参宏的用法: #define Test(par) Function(par);
void Function(int par);
int main(void) {
Test(par);
//中间若是加空格也可以调用Function(par);
Test (par);
}
也即是说,定义带参数的宏,在定义时,宏与参数之间不得有空格,但在调用时,则可以有空格。 至此,记录完毕。 记录时间:--
记录地点:深圳WZ
#define #include #undef的其中一个用法(目的)的更多相关文章
- block extends include三者的差别跟用法
block extends include三者的差别跟用法 一.定义基础模板,在html内容中定义多个block块,block由子模板引用同名block块,来决定是否替换这些部分{% block ti ...
- #define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined解释
#define.#undef.#ifdef.#ifndef.#if.#elif.#else.#endif.defined. #define 定义一个预处理宏#undef ...
- #include #import @class 的一些用法区别
从网上查了一些资料,整理了一下,发现很多都说的比较详尽,下面摘录自网络 说一下#import同class之间的区别 在ios中我们经常会在.h和.m中引入一些类啊等等一般用的是#import来进行声明 ...
- #define,#undef宏学习
1.预处理器 1.1预处理符号: __FILE__ :进行编译的源文件名字 __LINE__ :文件当前行的行号 __DATA__ :文件被编译的日期 __TIME__ :文件被编译的时间 __STD ...
- ThinkPHP第十天(_initialize方法,SESSION销毁,分组配置,include文件引入,JOIN用法)
1.Action类中的_initialize()函数,先于任何自定义操作函数运行,可认为是控制器的前置操作.可用于检测用户是否登录等检测. 如果多个模块(Action)需要相同_initialize( ...
- Android——ViewGroup的一个用法实例(转载)
找了很久,终于找到了. <?xml version="1.0" encoding="UTF-8" ?> <merge xmlns:androi ...
- 09_Android中ContentProvider和Sqllite混合操作,一个项目调用另外一个项目的ContentProvider
1. 编写ContentPrivider提供者的Android应用 清单文件 <?xml version="1.0" encoding="utf-8"? ...
- 常用代码之五:RequireJS, 一个Define需要且只能有一个返回值/对象,一个JS文件里只能放一个Define.
RequireJS 介绍说一个JS文件里只能放一个Define,这个众所周知,不提. 关于Define,它需要有一个返回值/对象,且只能有一个返回值/对象,这一点却是好多帖子没有提到的,但又非常重要的 ...
- 一个项目的Makefile编写及调试
父Makefile 在src目录下包含很多文件夹,那么需要遍历所有的目录执行Makefile,那么给一个在src目录下的Makefile. # 需要排除的目录 exclude_dirs := incl ...
随机推荐
- css3 选择器(三)
接css3选择器(一) 接css3 选择器(二) 这篇和前两篇内容相关性不大,主要是涉及到一些css3的状态选择器,所以标题从一开始. 一.[:enabled]选择器 一看这个属性就知道是专为表单元素 ...
- AngularJS笔记--自定义指令
在前端开发中, 我们会遇到很多地方都会用到同一种类型的控件.AngularJS提供了自定义指令功能,我们可以在指令里面定义特定的html模板.提供给前台html调用. 一. 指令的简单定义. 下面定 ...
- A book to recommend: The art of readable code
我最喜欢的一本书 - 教我如何写可读的代码 Two month fan of the book, from August - Oct. 2014; and then, started to pract ...
- @Autowired 与@Resource的区别
1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2 @Autowired默认按类型装配(这个注解是属业spring的),默认情况下 ...
- MVC4 自定义错误页面(转)
一.概述 MVC4框架自带了定义错误页,该页面位于Shared/Error,该页面能够显示系统未能捕获的异常,如何才能使用该页面: 二.使用步骤: 1.配置WebConfig文件,在System.We ...
- jquery获取父元素及祖先元素
parent是找当前元素的第一个父节点,parents是找当前元素的所有父节点 先说一下parent和parents的区别 从字面上不难看出 parent是指取得一个包含着所有匹配元素的唯一父元素的元 ...
- LeetCode:Word Ladder I II
其他LeetCode题目欢迎访问:LeetCode结题报告索引 LeetCode:Word Ladder Given two words (start and end), and a dictiona ...
- AD_TLC549采集模拟信号
AD_TLC549采集模拟信号 实验原理 芯片介绍 TLC549是 TI公司生产的一种低价位.高性能的8位A/D转换器,它以8位开关电容逐次逼近的方法实现 A/D转换,其转换速度小于 17us,最大转 ...
- Learning to rank 介绍
PS:文章主要转载自CSDN大神hguisu的文章"机器学习排序": http://blog.csdn.net/hguisu/article/details/79 ...
- sys
sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys.maxi ...