几种典型宏程序的编写方法

宏是程序设计语言一个重要的内容,对于一些步骤少却又使用频繁的操作,考虑到程序容量和执行效率的问题我们一般不将其封装为函数而是以宏的形式出现。对于单片机程序这一点尤为突出。宏语言分类非常广泛,这里介绍C语言常用的一些宏的编写方法。

二进制数宏

  • 01

    利用二进制宏可以解决C语言不能直接使用二进制量的问题,宏核心代码如下: #define LONG_TO_BIN(n) \ (                    \ ((n >> 21) & 0x80) | \ ((n >> 18) & 0x40) | \ ((n >> 15) & 0x20) | \ ((n >> 12) & 0x10) | \ ((n >>  9) & 0x08) | \ ((n >>  6) & 0x04) | \ ((n >>  3) & 0x02) | \ ((n      ) & 0x01)   \ ) #define BIN(n) LONG_TO_BIN(0x##n##L) 我们可以直接使用BIN(11100111)这种形式来使用常量,这就是最直观的二进制形式,非常方便,下载我们新建工程,测试代码如图:

  • 02

    由数制转换基本知识可知 二进制11000111对应十进制的199,我们使用BIN(11000111)与使用199具有同样的效果,程序运行结果验证了这一点。

位清除和设置宏

  • 01

    对于位操作,C语言提供了位域,但是位域要结合结构体使用,而由于C语言对字节对齐的方式未给出严格定义,不同编译器对于结构体的内存布局会有不同的实现方式,这就导致位域存在兼容性问题。我们可以使用位清除和未设置宏来解决这一问题: #define SET_BIT(var,BIT_POS) {var |= (0x01 << ((BIT_POS) % 8));} #define CLR_BIT(var,BIT_POS) {var &= (~(0x01 << ((BIT_POS) % 8)));} 其中SET_BIT(var, BIT_POS)为位设置宏,即设置变量var的第BIT_POS位为1,其中BIT_POS由0到该变量的最长长度 - 1,比如对于8位变量它的取值就是0~7。CLR_BIT(var, BIT_POS)与之类似,只不过CLR_BIT是将对应的位清零。 通过测试可以更好地理解,图为测试代码具体实现:

  • 02

    图为程序的运行结果,a最开始是0,而运行SET_BIT(a, 0)后变成了1,也就是a的最低位被SET_BIT置位了,而接着运行CLR_BIT(a, 0)后,a又变成0了,这也就是a的最低位被CLR_BIT清零了。

避免容量浪费的位编辑宏

  • 01

    前面介绍的位设置和位清除宏,可以实现变量的位操作,但是对于SET_BIT(var, BIT_POS)如果将BIT_POS传入变量,那么编译器会产生多余的代码造成空间浪费,这里再介绍一种避免这种问题的位编辑宏,分别为SET_BITn()和CLR_BITn(),分别对给定的变量的指定位置位和清零。具体实现如下: #define BIT0_SEL 0x01 #define BIT1_SEL 0x02 #define BIT2_SEL 0x04 #define BIT3_SEL 0x08 #define BIT4_SEL 0x10 #define BIT5_SEL 0x20 #define BIT6_SEL 0x40 #define BIT7_SEL 0x80 #define SET_BITn(var,BITn_SEL) {var |= (BITn_SEL);} #define CLR_BITn(var,BITn_SEL) {var &= (~(BITn_SEL));} 图中位该宏的测试代码:

  • 02

    图为程序的运行结果,初始状态a为0, 当我们执行SET_BITn(a, BIT0_SEL);后a的值变成了1,即a的最低位被SET_BITn置位了,接下来我们执行CLR_BITn(a,  BIT0_SEL),这是a的值变成0了,这是说a的最低位被CLR_BITn清零了。这验证了我们宏程序的准确性。

计算两个数字差的绝对值

  • 01

    有时候我们需要获得两个量的差距,这个其实可以通过判断语句来实现,不过这样看起来显的代码有点臃肿了,比如,将变量a和b差的绝对值赋值给c我们可以这样做: if(a > b) { c = a - b; } else { c = b - a; } 很简单的一个功能,但却占用了8行,感觉有点多了,不如试试下面的宏程序: #define ABS(NUM1,NUM2) ((NUM1) > (NUM2) ? (NUM1 - NUM2):(NUM2 - NUM1)) 这样便可以写作: c = ABS(a, b); 而且你还可以倒过来这样写: c = ABS(b, a); 仅仅才一行,程序看起来是不是感觉清爽多了? 图中给出一个测试代码,帮助进一步理解这个宏程序:

  • 02

    图中为ABS测试程序的运行结果,可以看出当a = 0, b = 10时a和b之间差10各数,与程序运行结果一致。而当a  = 10, b = 10时,它们之间差0各数,程序执行ABS(a,b)后结果为0,也是一致的。最后当a = 11, b = 10,即a和b之间差1个数,程序执行ABS(a, b)后结果也是1.

(0)

相关推荐

  • win8怎样关闭程序 2种关闭win8程序的方法介绍

    Win8系统是目前最新一代操作系统,也是微软公司开发的一款最具革命性变化的操作系统,主要是增加了触摸屏设备的触控体验,在操作上已经与我们熟悉的XP、Win7系统有不少改变。对于初次使用Win8系统,往 ...

  • 四种拯救Excel表格损坏的方法

    不管是什么软件,都免不了被损坏的命运,Excel也是一样的,但是,当Excel损坏的时候,我们应该怎么去做呢?是任其发展,还是采取修补 自救的方法,当然我们会选择后者,采取修补自救的方法,但是,到底有 ...

  • 三种新建WPS文字格式文件的方法

    三种新建WPS文字格式文件的方法 位置:界面左上角,WPS文字下拉菜单下找到"新建". 使用新建文件: 1. 从"快速访问工具栏"或"文档标签栏&qu ...

  • win7系统运行word提示Word断字功能不可用请运行Microsoft Office安装程序的解决方法

    用户经常在win7操作系统中使用word编辑文章,运行word时弹出“Word 断字功能不可用.请运行Microsoft Office安装程序,安装该功能,然后重试”的提示窗口,怎么办呢?下面我们的小 ...

  • Java程序怎样编写

    下面是一个简单Java程序的编写过程. 编写方法 01 为了在您的机器上配置起一个Java开发环境--您将使用一个"开发环境"来"开发"(编写)程序--您需要完 ...

  • gmail邮箱怎么退出?2种gmail邮箱退出登录的方法

    不知道gmail怎么退出? 下文将告诉大家2种gmail邮箱退出登录的方法,很多朋友找不到gmail邮箱的退出按键,那么该如何退出呢?让我们通过下文详细了解吧 gmail怎么退出?gmail邮箱退出登 ...

  • 为什么ps不能打字?ps不能打字程序错误解决方法

    为什么ps不能打字?小编带来了ps不能打字程序错误解决方法,当我们需要在图片上输入文字却提示失败的话,该怎么处理这样的问题呢?请看下文介绍吧。 依次打开编辑--首选项---文字,然后在文字后面的选项中 ...

  • 路由器怎么恢复设置 两种路由器恢复出厂设置的方法

    当我们忘记路由器登陆密码或者觉得路由器上网不稳定有故障的时候,通常可以通过将路由器恢复出厂设置,然后重新进行路由器设置来解决一些较难解决的问题。路由器恢复出厂设置大致有两种方法,一种是进入路由器设置管 ...

  • 怎么看硬盘的缓存 两种查看硬盘缓存容量的方法

    怎么看硬盘的缓存?硬盘缓存容量越大越好吗?由于在Windows系统以及硬盘表面铭牌标注上,一般无法直接看到硬盘缓存大小的标注,因此关于怎么看硬盘的缓存,也是硬件爱好者所常问的问题,下面小编教大家两种查 ...