扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
函数式宏(function-like macro)较之对象式宏可以进行更复杂的代换。
创新互联为企业提供:品牌网站制作、网络营销策划、小程序开发、营销型网站建设和网站运营托管,一站式网络营销整体服务。实现不断获取潜在客户之核心目标,建立了企业专属的“全网整合营销推广”,就用不着再为了获取潜在客户而苦恼,相反,客户会主动找您,生意就找上门来了!
函数式宏 sqr 是在编译时展开并填入程序的,因此 只要是能用双目运算符 * 进行乘法计算的数据类型,都能使用函数式宏 。
函数定义则需为每个形参都定义各自的数据类型,返回值的类型也只能为一种。就这点而言,函数较为严格。
函数为我们默默无闻地进行了一些复杂处理,如:
而函数式宏所做的工作只是宏展开和填入程序,并不进行上述处理。
根据以上特征, 函数式宏或许能使程序的运行速度稍微提高一点,但是程序自身却有可能变得臃肿 。
函数式宏在使用上必须小心谨慎。例如, sqr(a++) 展开后 ((a++) * (a++)) 。每次展开, a 的值都会自增两次。在不经意间表达式被执行了两次,导致程序出现预料之外的结果,我们称这种情况为宏的 副作用(side effect) 。
定义的意思
在C语言中的宏定义就是定义外部变量 内部函数使用exiterm来调用
如:exiterm char c1,c2;
C语言中的宏定义的字是:define
C语言中的define宏定义有带参数的和不带参数两中形式
不带参格式是:#define 宏名 字符串
带参格式是:#define 宏名(参数1,参数2,...) 字符串
在C语言里宏定义只用来做的宏名替换,而不做语法检查的,因而它不是C语句,所以在宏定义的时候不需要在后面加";"
宏也在C里也叫预处理命令,因为宏是在程序编译前先进行字符替换的,所以叫预处理.在C里还有其它的预处理命令如:
#define
#undef
#ifdef
等等
宏是一种预处理指令,它提供了一种机制,可以用来替换源代码中的字符串。
1、条件编译:
C语言中,预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行相应的转换,预处理过程还会删除程序中的注释和多余的空白符号。
预处理指令是以#开头的代码行,#必须是该行除了空白字符外的第一个字符。#后是指令关键字,在#和指令关键字之间允许存在若干空白字符。
使用宏进行条件编译的用法与使用宏防止多重引用类似。示例如下:
使用条件编译,方便程序员在调试程序的过程中,执行一些在程序发布后并不需要执行的指令。只要在需要调试的代码前加上_DEBUG的定义,就可以在调试程序的过程中输出调试信息。
这样方便查看程序在运行过程中有没有出现错误,定位错误出现的地方。而在程序发布之前,取消_DEBUG的定义就可以不再执行调试代码。
2、宏函数:
函数的调用是需要一定的时间和空间代价的。因为系统在调用函数时,需要保留"现场",即将程序要执行的指令的下一条指令的位置压入栈,然后转入调用函数去执行,调用完函数后再返回主调函数,恢复"现场",返回到栈里保存的的下一条指令的位置继续执行。
所以函数的调用需要额外的时间和空间代价。
而宏函数则不存在上述问题,宏函数在预编译时,同函数定义的代码来替换函数名,将函数代码段嵌入到当前程序,不会产生函数调用。
所以会省去普通函数保留现场恢复现场的时间,但因为要将定义的函数体嵌入到当前程序,所以不可避免的会占用额外的存储空间。
在频繁调用同一个宏的时候,该现象尤其明显。宏函数的示例定义如下:
#define MAX(a,b) ((a)(b)?(b):(a))
宏函数的优点在于避免函数调用,提高程序效率。
同时需要注意的是inline标识符。inline也将函数定义为内联的。但是使用内联函数需要注意的是:函数体必须十分简单,不能含有循环、条件、选择等复杂结构,否则就不能作为内联函数了。
事实上,有时候即便你没有将函数指定为内联函数,编译器也会将一些简单的函数作为内联函数处理,而对于一些复杂的函数,即使声明为内联函数,编译器也不会理会的。
inline函数的瓶颈就在于此,使用inline标识符将函数声明为内联的,但这只是一种提示,到底编译器有没有优化还依赖于编译器的实现,而使用宏函数则完全由代码本身控制。
但在使用宏函数的时候,需要明确的是宏函数只是简单的替换,需要注意括号的使用。
扩展资料:
宏的更多规则特性:
(1)宏名一般用大写。
(2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义。
(3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
(4)宏定义末尾不加分号。
(5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。
(6)可以用#undef命令终止宏定义的作用域。
(7)宏定义不可以嵌套。
(8)字符串" "中永远不包含宏。
(9)宏定义不分配内存,变量定义分配内存。
(10)宏定义不存在类型问题,它的参数也是无类型的。
参考资料:
百度百科--宏定义
直接调用即可。如下示例:
#includestdio.h#define sum(b,c){int d=0;d=b+c;printf("两者的和:%d\n",d);}int main(){ int x=0,y=0; scanf("%d%d",x,y); sum (x,y); return 0;}使用宏函数或者宏函数时,注意如下几点:
(1)宏函数的参数没有类型,预处理器只负责做形式上的替换,而不做参数类型检查,所以传参时要格外小心。
(2)宏函数定义要注意格式,尤其是括号。
如果上面的宏函数写成 #define MAX(a, b) (ab?a:b),省去内层括号,则宏展开就成了k = (i0x0fj0x0f?i0x0f:j0x0f),运算的优先级就错了。同样道理,这个宏定义的外层括号也是不能省的。若函数中是宏替换为 ++MAX(a,b),则宏展开就成了 ++(a)(b)?(a):(b),运算优先级也是错了。
(3)宏函数往往会导致较低的代码执行效率。
int a[]={9,3,5,2,1,0,8,7,6,4};int max(n){return n==0?a[0]:MAX(a[n],max(n-1));}int main(){max(9);return 0;}若是普通函数,则通过递归,可取的最大值,时间复杂度为O(n)。但若是宏函数,则宏展开为( a[n]max(n-1)?a[n]:max(n-1) ),其中max(n-1)被调用了两遍,这样依此递归下去,时间复杂度会很高。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流