一直在嵌入式中混日子,很多知识点被遗忘的差不多了都,最近也是项目setting需要用宏定义来实现不同setting的区分,在makefile里倒是加好了宏,但是逻辑运算到着实有点手生就搜了搜资料,这里也给自己记录下宏的知识点吧。
不过呢先说一下我对宏定义的理解,宏定义就想象成为本替换,想了解清楚就文本替换还原回去就能明白了。
下面我们就开始进入主题,来进一步了解一下宏:

1. 宏简单实用演示:

1.1宏的简单使用说明

#define square(x) x*x
/*
*下面我们就来用一下这个宏
*/
printf("result = %d\n",square(5));
/*无可厚非,结果就是5*5=25*/
int a = 5;
printf("result1 = %d\n",square(a+1));
/*第一眼可能会脱口而出36,
*但是你文本替换一下就是这个样子x==a+1,所以x*x=a+1 * a+1=11
*/
//上面的可能不是你的本意,你的本意是要36这个值,就要用下面这个种方式
#undef square
#define square(x) (x)*(x)
printf("result1 = %d\n",square(a+1));
/*
*这样子我们重新替换一下就是x==a+1,(x)*(x)=(a+1)*(a+1)
*这也算是宏定义的一个误区,需要慎重,不确定的时候建议使用括号包起来
*/

1.2宏定义在我们code中颇受欢迎,会用了有很多便处也有很多技巧,比如宏定义可以用来禁止一些系统function的使用,如下:

#define x_malloc(type,size) ((type*)malloc(size))
#define malloc 

这样就无法直接在该函数里调用这个系统api了, 但是我们可以通过自己的新定义的万能api x_malloc来代替系统malloc函数,这样用起来就方便多了。
1.3其次呢 宏定义也是可以接收你的function parameter的,如下:

#define  Printf(argc,argv) printf("%s,%d",argc,argv)int main(char* argc[], int argv){Printf(argc,argv);return 0;}

1.4宏还可以代替结构体来定义一个结构体变量:

#ifdef MEMBER
#undef MEMBER
#endif
#define MEMBER(type,member) (type member;)
#define STRUCT \
MEMBER(int, u4Size)\
MEMBER(char, u1Ch)\
MEMBER(bool, bFlag)\

int main(void)
{STRUCT A;A.u4Size=10;A.u1Ch='a';A.bFlag=true;return 0;
}

2. 宏定义的条件展示:

/*
*同样宏定义也是有逻辑操作的,比如我们判断是否有定义过这个宏可以这样子:
*/#if define symbol//#ifdef symbol#endif#if !define symbol//ifndef symbol#endif/** 有些时候我们迫不得已要用到下面这种逻辑来隔开不同的code setting*/#ifdef Option1//implement code for option1#elif (define option2)//implement code for option2#else//implement code for default setting#endif/**还有下面这种同时判断两个宏定义的**/#if (define Option1)&&(define option2)//implement common code for both of option1 and option2#elif Option1//implement code only for option1#elif (define option2)//implement code only for option2#else//implement code for default setting#endif

3. 宏和函数

在代码中我们经常会用到宏来定义一个简单的函数来供我们使用,但是这两个有什么区别呢?
我们来简单列一下宏和函数区别:
3.1 宏定义的代码较为简短且都是在预处理的时候就会插入到整个代码中,他的生存期和程序一样;函数适合代码较长的使用,每次调用会需要重新load同一个地方的代码
3.2宏因为一直在程序中所以执行速度快,函数每次执行需要重新load相比比较慢
3.3宏的参数不care类型,甚至可以吧类型当做宏的参数传递,但是函数就不行了(还记得最前面我们举例的时候有展示一个malloc的替换嘛,哪里我们可以直接把类型当做宏的参数来使用)
3.4宏对操作符优先级如果不加括号结果不可预期,但是函数是可以预期
3.5结果返回,宏的结果返回也有可能不预期,如下面我们的求最大值,但是函数的返回不会造成那种特殊的效果

宏定义还有一个副作用就是它有“持续效果”,这个就是它可以再原来的base上持续进行会改变你的初衷,具体的我们举个例子来看下:

int x=5, y=6;
int u4MAx(int a, int b)
{return (a>b:a,b);
}
#define Max(a,b) ((a)>(b)?(a):(b))
/*
*我们不管调用多少次u4Max(x++,y++),x和y的增长都是一样的,第一次调用后x=6,y=7,u4Max(x++,y++)=7;
*但是Max(x++,y++),就不一样了,第一次调用后x=6,y=8,Max(x++,y++)=7
*我们把上面的具体展开看下Max(x++,y++)=((x++)>(y++)?(x++):(y++))
*这样就很明显x和y中有一个被多加了一次,这也是我们不预期的一个操作,所以这个持续效果值得我们日常撸码时候注意
*/

宏我们就简单记录这么多,使用宏一定要注意item3里面的细节,不然很容易造成很多不预期得结果导致不必要的麻烦。

宏(macro)定义的简介相关推荐

  1. 宏(macro)定义与使用

    文章结构如下: 宏的定义 宏的替换与代码展开 宏的替换产生的问题 获取宏参数名称 宏参数的结合 宏的取消 宏定义的换行连接 标准预处理宏 宏(macro)是基于#define所实现的另一种预处理功能. ...

  2. C语言的宏macro的使用

    C's Macro Introduction 1.The Connect Macros: ## 这是一个预处理连接符,这个操作符主要用来将两个符号连接成为一个完整的宏符号.通过下面的代码,可以看到其具 ...

  3. c语言 macro,C/C++中宏/Macro的深入讲解

    前言 宏(Macro)本质上就是代码片段,通过别名来使用.在编译前的预处理中,宏会被替换为真实所指代的代码片段,即下图中 Preprocessor 处理的部分. C/C++ 代码编译过程 - 图片来自 ...

  4. 宏的定义和调用,输出字符串

    宏的定义和调用,输出字符串 data segment string db "hello,bad boy",0ah,0dh,'$' data ends code segment ma ...

  5. 数据结构的定义和简介

    1. 概述 数据结构定义: 我们如何把现实中大量而复杂的问题以特定的数据类型和特定的存储结构保存到主存储器(内存)中,以及在此基础上为实现某个功能(如元素的CURD.排序等)而执行的相应操作,这个相应 ...

  6. C++中宏的定义与用法(现已被内联函数所代替)

    在noip中,宏还是被经常采用,所以这里讲一下,C++中宏的定义与用法 第一种用法--配合条件编译:#define DEBUG 定义一个叫DEBUG的标识符.它应该与#ifdef或#ifndef配合使 ...

  7. warning:4005 DXGI_STATUS_OCCLUDED,宏重定义

    最近新装的VS2012,发现D3D11程序普遍出现大量的warning:C4005:DXGI_STATUS_OCCLUDED,宏重定义 参考网上的解决方案轻松解决(Click Me): 在项目属性-- ...

  8. 宏重定义 头问题重定义解决办法

    头问题件重定义: 头文件重复包含的问题往往是重定义的问题.下面我们有两种方式解决头文件的重复包含:一个是条件编译的#ifndef...#endif 和 #pragma once. 例如采用: #ifn ...

  9. 关于宏重复定义的问题分析

    前言 在项目中,遇到一个问题,发现一个文件里有2个同样的宏名,并且替代的值相同,可能是前面不小心多复制了一次导致: 但是这里也值得深思和考虑,如果在一个项目中,不小心定义2个相同宏名,但是值不一样的现 ...

最新文章

  1. 解决getOutputStream() has already been called for this response[java io流]
  2. 在循环中删除list中的元素
  3. Spring事务处理流程和原理(动脑学院笔记)
  4. 利用jvisualvm分析JVM,进行性能调优
  5. C语言再学习 -- C 预处理器
  6. SAP CRM Fiori应用My Opportunity的点阵外观
  7. python多个变量的for循环
  8. 有个做微商的兄弟,他是卖品牌运动鞋的,最近很苦恼
  9. CSS常用选择器简析(带简单案例)
  10. 计算机专业知识笔记,事业单位计算机专业知识重点笔记
  11. 最新微信开通状态过滤程序
  12. CMSC5713-IT项目管理之四、项目规划Project Planning
  13. 科技爱好者周刊(第 160 期):中年码农的困境
  14. Error: illegal invocation in <execute> or <revert> phase (action: element.updateProperties或Laber)
  15. 开发者除了技术硬实力之外,还有哪些不可或缺的软实力
  16. python内置函数入门_Python入门-内置函数一
  17. 网格员计算机基本操作,maxwell基本操作之——网格剖分
  18. Linux:进程管理 | 进程创建 | 进程终止 | 进程等待 | 进程替换
  19. Verilog——篮球24S计时器
  20. 使用 amMap 轻松添加互动效果的 JavaScript 地图

热门文章

  1. mediaserver
  2. ListViewItem实现listview中条目的显示控制
  3. iOS UITextView调整行间距
  4. windows 10 打开任务管理器的快捷键
  5. 计算机word做课程表实验报告,《用word做课程表》教学设计
  6. 我是如何放弃投行回归技术的
  7. 抛硬币吃苹果的概率问题
  8. 手机关机不拔电池也能被定位吗?
  9. 通过PHP实现PNG转JPG
  10. P2p网站建设解决方案