#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 ...
随机推荐
- [WPF系列] window自定义
效果图: 源码下载 SourceCode 参考 Disabling or hiding the minimize, maximize or close button of a WPF ...
- Ural 1011. Conductors
1011. Conductors Time limit: 2.0 secondMemory limit: 64 MB Background Everyone making translations f ...
- UVA11021 Tribles[离散概率 DP]
UVA - 11021 Tribles GRAVITATION, n. “The tendency of all bodies to approach one another with a stren ...
- apache服务器启动时提示httpd: apr_sockaddr_info_get() failed for
apache服务器启动时提示httpd: apr_sockaddr_info_get() failed for 在RedHat Linux 5 与 CentOS 5服务器上配置好apache后,启动或 ...
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 角色权限的配置页面改进优化
往往开发的人不是维护的人,开发的单位不是维护的单位.信息的畅通沟通交流很多时候会有打折.扭曲.甚至是容易得到歪解.配置错业务操作权限.为了防止发生没必要的麻烦,甚至是发生重大错误,我们的软件需要不断换 ...
- C#.NET 大型企业信息化系统集成快速开发平台 4.1 版本 - 如何才能成为全国知名软件组件
往往我们看到一个好用的工具.就能知道制作这个工具有多少不容易,使用好这个工具也有多少不容易? 通用快速开发框架同样也是经过多年的完善改进才到了今天的稳定成熟度,知名程度,为什么能成为全国有名的软件组件 ...
- ES5基础之正则表达式02:范围类、预定义类和边界字符
1.范围类 //元字符 /* * 正则表达式由两种基本字符类型组成 * 1.原义文本字符:例如123abc * 2.元字符:元字符是在正则表达式中有特殊含义的非字母字符 */ //常见特殊符号:. * ...
- 利用Highcharts插件制作动态图表
向大家推荐一款js插件,用于绘制图表Highcharts,具体操作可参考官方网站:http://www.hcharts.cn/ 1.如下为本人制作的图形效果如下,当然其效果远不止这些,大家还可以深入研 ...
- 浅谈js命名空间管理
在C# 和 Java里面我们如果想使用哪一个功能类就要引用相应的命名空间. 如C#里面有个System.Web.UI库,我们就要用using System.Web.UI;,之后我们就可以用到Scr ...
- 链队列java实现
public class LinkHeap<T> { class Node<T> { T data; Node<T> next; Node(T data) { th ...