1.宏和函数的速度——宏更快
比如在两个数中找出较大的一个。
如:
那为什么不用函数来完成这个任务?
原因有二:
1.用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多,所以宏比函数在程序的规模和速度方面更胜一筹。
2.更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用,反之这个宏怎可以适用于整形、长整型、浮点型等
详细分析
右击鼠标,转到反汇编,可以看到函数Max的汇编代码:
可以看出函数花费的时间主要有:
1.函数调用前的准备(传参、函数栈帧空间的维护)
2.主要运算
3.函数返回、函数返回值的处理、函数栈帧空间的销毁。
而宏Max的汇编代码:(可以看出什么都没显示,这是正常的,宏同样不能够调试)
虽然什么都没有显示,但是可以看出与函数相比,宏的时间花费只有主要运算。因此宏的运行速度比函数快。
2.宏相比于函数的缺点
当然和函数相比宏也有劣势的地方:
- 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序 的长度。
- 宏是没法调试的。
- 宏由于类型无关,也就不够严谨。
- 宏可能会带来运算符优先级的问题,导致程容易出现错。
但是宏有时候可以做函数做不到的事情。比如:宏的参数可以出现类型,但是函数做不到。 如:
3.二者的优劣
属 性 | #define定义宏 | 函数 | |
---|---|---|---|
代 码 长 度 | 每次使用时,宏代码都会被插入到程序中。除了非常 小的宏之外,程序的长度会大幅度增长 | 函数代码只出现于一个地方;每 次使用这个函数时,都调用那个 地方的同一份代码 | |
执 行 速 度 | 更快 | 存在函数的调用和返回的额外开 销,所以相对慢一些 | |
操 作 符 优 先 级 | 宏参数的求值是在所有周围表达式的上下文环境里, 除非加上括号,否则邻近操作符的优先级可能会产生 不可预料的后果,所以建议宏在书写的时候多些括号 | 函数参数只在函数调用的时候求 值一次,它的结果值传递给函 数。表达式的求值结果更容易预 测 | |
带 有 副 作 用 的 参 数 | 参数可能被替换到宏体中的多个位置,所以带有副作 用的参数求值可能会产生不可预料的结果 | 函数参数只在传参的时候求值一 次,结果更容易控制 | |
参 数 类 型 | 宏的参数与类型无关,只要对参数的操作是合法的, 它就可以使用于任何参数类型 | 函数的参数是与类型有关的,如 果参数的类型不同,就需要不同 的函数,即使他们执行的任务是 相同的 | |
调 试 | 宏是不方便调试的 | 函数是可以逐语句调试的 | |
递 归 | 宏是不能递归的 | 函数是可以递归的 |