范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

几种特殊的函数宏封装方式

  1
  函数宏介绍   函数宏,即包含多条语句的宏定义,其通常为某一被频繁调用的功能的语句封装,且不想通过函数方式封装来降低额外的弹栈压栈开销。   函数宏本质上为宏,可以直接进行定义,例如: #define INT_SWAP(a,b) int tmp = a; a = b; b = tmp   但上述的宏具有一个明显的缺点:当遇到 if、while 等语句且不使用花括号仅调用宏时,实际作用范围在宏的第一个分号后便结束。即 a = b 和 b = tmp 均不受控制语句所作用。   因此,在工程中,一般使用三种方式来对函数宏进行封装,分别为 {}、do{...}while(0) 和({})。下文将一一对三种方式进行分析,比较各自的优劣点。   2
  {} 方式   INT_SWAP 宏使用 {} 封装后形态如下: #define INT_SWAP(a,b) { int tmp = a; a = b; b = tmp; }   此时,直接调用与在无花括号的控制语句(如 if、while)中调用均能正常运行,例如: #define INT_SWAP(a,b) { int tmp = a; a = b; b = tmp; } int main() { int var_a = 1; int var_b = 2; INT_SWAP(var_a, var_b); printf("var_a = %d, var_b = %d ", var_a, var_b); // var_a = 2, var_b = 1 if (1) INT_SWAP(var_a, var_b); printf("var_a = %d, var_b = %d ", var_a, var_b); // var_a = 1, var_b = 2 }   但当无花括号的 if 语句存在其他分支(else if、else 等)如: if (1) INT_SWAP(var_a, var_b); else printf("hello world! ");   会发现编译出错: ... /mnt/hgfs/share/pr_c/src/main.c: In function ‘main’: /mnt/hgfs/share/pr_c/src/main.c:18:2: error: ‘else’ without a previous ‘if’ else   这是因为 INT_SWAP(var_a, var_b); 最后的 ; 已经把 if 的作用域终结了,后续的 else 当然没有找到与之匹配的 if 了。   因此,解决方法有两种,分别为不使用 ;(port.1)或规定必须使用带花括号的if(port.2),例如: /* port.1 */ if (1) INT_SWAP(var_a, var_b) else { printf("hello world! "); } /* port.2 */ if (1) { INT_SWAP(var_a, var_b); } else { printf("hello world! "); }   可见,不使用 ; 的调用方式无论从程序阅读还是使用方法方面都是十分别扭的;而规定必须使用带花括号的 if 的调用方式有违常理的,因为宏函数应该适用于任何语法。   优缺点总结: 优点:简单粗暴。   缺点:不能在无花括号且有分支的 if 语句中直接调用;能够不带 ; 直接调用。   3
  do{...}while(0) 方式   INT_SWAP 宏使用 do{...}while(0) 封装后形态如下: #define INT_SWAP(a,b) do{ int tmp = a; a = b; b = tmp; }while(0)   do{...}while(0) 表示只执行一遍 {} 内的语句,表象来说与 {} 的功能是一致的。不同的是,do{...}while(0) 可以提前退出函数宏、整合为一条语句与强制调用时必须使用 ;。   由于 do{...}while(0) 实际为 while 循环,因此可以使用关键字 break 提前结束循环。利用该特性,可以为函数宏添加参数检测。例如: #define INT_SWAP(a,b) do{ if (a < 0 || b < 0) break; int tmp = a; a = b; b = tmp; }while(0)   由于 do{...}while(0); 实际为一种语法,编译器会把 do{...}while(0); 认为为一条语句。   因此,do{...}while(0) 方式的函数宏可以在无花括号且有分支的 if 语句中直接调用。例如: #define INT_SWAP(a,b) do{ if (a < 0 || b < 0) break; int tmp = a; a = b; b = tmp; }while(0) int main() { int var_a = 1; int var_b = 2; if (1) INT_SWAP(var_a, var_b); else printf("hello world! "); printf("var_a = %d, var_b = %d ", var_a, var_b); // var_a = 2, var_b = 1 return 0; }   C 语言规定,do{...}while(0) 语法必须使用 ; 作为语句结尾。因此不可能存在以下语句的程序出现: if (1) INT_SWAP(var_a, var_b) else { printf("hello world! "); }   优缺点总结: 优点:支持在无花括号且有分支的 if 语句中直接调用;支持提前退出函数宏;强制调用时必须使用 ;。   缺点:无返回值,不能作为表达式的右值使用。   4
  ({}) 方式   ({}) 为 GNU C 扩展的语法,非 C 语言的原生语法。   INT_SWAP 宏使用 ({}) 封装后形态如下: #define INT_SWAP(a,b) ({ int tmp = a; a = b; b = tmp; })   与 do{...}while(0) 相同,({}) 支持在无花括号且有分支的 if 语句中直接调用。例如: #define INT_SWAP(a,b) ({ int tmp = a; a = b; b = tmp; }) int main() { int var_a = 1; int var_b = 2; if (1) INT_SWAP(var_a, var_b); else printf("hello world! "); printf("var_a = %d, var_b = %d ", var_a, var_b); // var_a = 2, var_b = 1 return 0; }   与 do{...}while(0) 不同的是,({}) 不能提前退出函数宏与支持返回值。({}) 毕竟不是 while 循环,不能直接使用 break退出函数宏是比较容易理解。那支持返回值是什么意思呢?   答案是 C 语言规定 ({}) 中的最后一条语句的结果为该双括号体的返回值。例如: int main() { int a = ({ 10; 1000; }); printf("a = %d ", a); // a = 1000 }   因此,({}) 可以为函数宏提供返回值。例如: #define INT_SWAP(a,b) ({ int ret = 0; if (a < 0 || b < 0) { ret = -1; } else { int tmp = a; a = b; b = tmp; } ret; }) int main() { int var_a = 1; int var_b = 2; if (INT_SWAP(var_a, var_b) != -1) printf("swap success !! "); // swap success !! else printf("swap fail !! "); printf("var_a = %d, var_b = %d ", var_a, var_b); // var_a = 2, var_b = 1 return 0; }   可见,此时的 INT_SWAP 宏已与函数十分接近。   优缺点总结: 优点:支持在无花括号且有分支的 if 语句中直接调用;有返回值,支持作为表达式的右值。   缺点:不支持提前退出函数宏;非 C 的原生语法,编译器可能不支持。   5
  总结   综上,在 {}、do{...}while(0) 和 ({}) 这三种函数宏的封装方式之中,应尽可能不使用 {},考虑兼容性一般选择使用 do{...}while(0),当需要函数宏返回时可以考虑使用 ({}) 或直接定义函数。

无人版滴滴就要来了,国内首款低成本无人驾驶摆渡车将于年内实现量产无需司机,乘客通过手机APP一键叫车,车辆自己开到指定地点接客,再将乘客送往目的地。解放日报上观新闻记者获悉,近日,中科院合肥技术创新工程院智能移动机器人中心技术团队攻克了无人驾驶这些功能设计,微信走心了作为一个日活超10亿的社交产品,微信的每一个功能改版都要经受海量用户的检验。所以,微信的每一个功能的设计周期都会很长。他们对于功能的打磨的细腻与走心,从本文笔者举出的这两个例子就能苏宁菜场4月底上线,24小时内送至苏宁小店,盒马美团罗森均已入局4月3日,AI财经社获悉,苏宁小店将于4月下旬上线苏宁菜场。据悉,苏宁菜场计划24小时内将蔬菜从原产地发货至苏宁小店门店,主要针对蔬菜鲜肉豆制品活鱼(现杀)等商品。同时,苏宁小店A华为主动放弃默认4K模式,不把DxO分数作为目标集微网消息(文数码控),华为的P30Pro上个月在法国发布,它以112的综合成绩理所当然的拿下了DxOMark榜单的第一名,但是它的视频录制分数却只有97分,相较于上一代的P20P锤子新品将至?坚果手机开始补货在聊天宝发布会后,锤子科技罗永浩基本很少在公众露面,截止到现在已经有近3个月时间。不仅如此,锤子科技情况百出,高管集体退出全部机型官网无货被今日头条收购等等,而对于这些消息,罗永浩微信这一功能不关闭,隐私会一直泄露,许多人都没发现!在去年微信更新大版本7。0后,公众号文章右下角的点赞升级为了好看,同时在微信看一看功能中,为好看提供了一个专属的模块,只要你点了好看,好看板块就会显示你观看过的文章。而最近,微信则章泽天卸任,是偶然还是必然?重庆嫩绿茶艺有限公司的董事变更引起网友的各种猜想,原因很简单,因为变更的人是京东老大刘强东的夫人奶茶妹妹章泽天。章泽天卸任这仅仅是普通的人事变动?还是刻意而为之?根据调查,章泽天此在闲鱼上看到有卖坏CPU的,几十块钱一个,那买家用来干嘛呢?CPU能修好吗?在某宝上卖的坏CPU一般会标注仅用于学术交流教学收藏和研究,而且销量还不错,这些坏的CPU到底有什么用呢?不禁让我想到了今年315晚会的家电维修问题。随着科技的进步,硬件市场应透明10个Python图像编辑工具以下提到的这些Python工具在编辑图像操作图像底层数据方面都提供了简单直接的方法。ParulPandey当今的世界充满了数据,而图像数据就是其中很重要的一部分。但只有经过处理和分中国黑客界鬼才,他写的病毒五年才能彻底清理,如今已经回归正道很多高科技的犯罪分子成为了一个世界性的难题,黑客就是这样的一个存在。他们只要动动手指就可以进入大家的电脑,甚至还能入侵现在的智能家居,安装智能摄像头,而且还能通过一些漏洞控制摄像头明年iPhone尺寸大改,5G难产据Digitimes报道,苹果近期正在制定2020年新iPhone的屏幕规格。与2019年相比,苹果2020年要推出的三款iPhone在尺寸上有了较大变动。Digitimes援引供
得伪球迷者得天下进入世界杯时代每隔四年,这个世界会出现一种非常独特的天文现象地球围着足球转。一个多月的赛事,整个世界都在为那粒小小的足球疯狂。而每到这个时候,总会有一种声音出来伪球迷看什么球啊?对此,本伪球迷必知识产权侵权纠纷恐成搜狗IPO后最大风险据报道,北京时间11月9日晚搜狗将在纽交所上市。在过去3个多月时间里,搜狗不断向资本市场讲述着自己的情怀和故事。但是在其IPO招股书中所写的悬而未决或将来潜在的法律纠纷可能影响到我用酷狗旋转音效播放这张歌单,你连伸懒腰都是优雅的当你坐进一家咖啡馆,被浓郁的香气催促着点单,片刻等待后,热乎乎飘着暖气的杯子被递上来,你陷入一个难题,是直接喝掉一大口么?还是傻乎乎地吹气?很简单,打开酷狗,通过旋转与优雅搜出这张估值600亿的喜茶,商标是70万买来的上个月,喜茶完成5亿美元的D轮融资,估值金额已达600亿人民币。截至2020年底,喜茶在全球60余个城市开出695家门店,喜茶创始人聂云宸曾透露喜茶单店月营业额平均在100万以上。商标被驳回了怎么办?不是所有的商标注册流程都是一帆风顺的,很多个人和企业申请商标时会遇到商标驳回的情况。比如,近期华为注册的P100商标被驳回,此前阿里腾讯小米等公司都遭遇过商标驳回,不管是大企业还是抖音爆火的人类高质量男性,被抢注商标人类高质量男性一词来源于一则求偶短视频。经常刷抖音的朋友可能看到过,一个叫徐勤根的男士梳着油头画着白脸纸人妆,自称为人类高质量男性,在镜头前磕磕绊绊的介绍自己,想要求偶人类高质量女商标热点丨华为P100商标被驳回!美团饭小圈试水外卖社交1华为技术有限公司于今年3月份申请的P100商标近期被驳回,7月28日华为公司又重新申请了2个P100商标,目前处于等待受理阶段。2华为申请注册SmileSMILEWARE商标,国华为因鸿蒙HongMeng商标状告国家知识产权局,一审败诉众所周知,鸿蒙是华为发布的手机操作系统。因为鸿蒙商标,华为没少费心思。近日,华为公司与国家知识产权局关于第38684797号鸿蒙HongMeng商标纠纷案一审结果公开。鸿蒙Hong商标热点丨109件奥运健儿姓名商标被驳回!塔利班商标被抢注1国家知识产权局发布通告,针对近期频发的奥运健儿姓名被抢注商标一事,目前已依法驳回杨倩陈梦全红婵等109件商标注册申请。2近日,塔利班商标被抢注,国际分类涉餐饮住宿材料加工等,申请商标热点丨密雪时光与蜜雪冰城近似被无效1近日,重庆江小白酒业有限公司申请注册二人饮九人饮百人饮千人饮万人饮等多个商标,国际分类均为酒,当前商标状态为商标申请中。2关于密雪时光商标二审判决公开,该商标由自然人李某于201互联网专利第一案今日开庭,搜狗诉百度7项专利侵权9月14日,号称互联网专利第一案的搜狗诉百度专利侵权诉讼案,在完成相关的前期调查准备后,正式于北京知产法院开庭审理。据了解,本轮庭审主要围绕百度侵权的7项专利进行。随着该案进入正式