宏与函数
来源:互联网 发布:梦幻之星nova捏脸数据 编辑:程序博客网 时间:2024/05/16 06:05
1.宏与函数
在定义方式上两者有所不同,宏定义方式为:#define MAX(a,b) ((a)>(b)?(a):(b))
函数定义:int max(int a,int b){return a>b?a:b;}
宏的名称常为大写,用于与普通函数区分。
在一行写不下时,可以用反斜杠隔开,
# define MAX(a,b) \
((a)>(b)?(a):(b))
若想取消宏定义,可以用#undef …
# define N 5
#undef N
宏的优点是它在预处理的地方展开,不需要额外的时间开销,省去了堆栈分配,压栈出栈,释放堆栈等操作,所以调用宏比调用一个函数更有效率。另外,宏与类型是无关的。函数的参数必须声明为一种特定的类型,所以它只能在类型合适的表达式上使用。举例来说,#define MAX(a,b) ((a)>(b)?(a):(b))
这里,a,b可以为char,int,usigned int,double等类型,如果用函数,必须限定为某种类型,这里也是宏的优势所在。
# define MAL(type) \
((type *)malloc(sizeof(type)))
上面的例子可以实用MAL(int) MAL(char)等形式,而这个功能用函数是无法实现的,因为函数无法将类型关键字传入函数体。
宏也有不尽如人意的地方,比如 #define f(x) (x*x) ,如果是求f(5)会得到25,而求f(2+3)时,并不会得到25,而是2+3*2+3=11。在定义宏的时候需要注意的是括号,每个变量或者表达式尽量加上括号,以避免产生歧义。
在宏参数在宏定义中出现的次数不止一次,如果这个参数具有副作用,那么当你使用这个宏的时候可能会出现危险,导致不可预测的结果。考虑一下代码,
# define MAX(a,b) ((a)>(b)?(a):(b))
x=5;
y=8;
z=MAX(x++,y++);
printf(“x=%d,y=%d,z=%d\n”,x,y,z);
这段代码的执行结果是 x=6,y=10,z=9.
要理解这个结果,只要展开宏的代码即可,
z=((x++)>(y++))?(x++):(y++)
较小的值增加了一次,而较大的值增加了两次!
宏与函数的区别
属性
# define 宏
函数
代码长度
宏代码插入到程序中,除了非常小的宏之外,程序的长度将大幅度增长
函数代码只出现在一个地方
执行速度
更快
存在额外开销
操作符优先级
要为参数加上括号
参数求值
参数求值可能有副作用
参数多次求值没有副作用
参数类型
与类型无关
与类型有关
一个小例子:
不使用比较操作符,利用宏来比较两个整型数的大小
# define MAX(a,b) (((a)-(b))>>31)?(b):(a)
上面的例子中假定了int 型数据变量占据4个字节,a-b右移31位即可得到符号位,符号位为1时a<b,符号位为0时,a>b.
2内联函数与宏的区别
内联函数和宏的区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。
我们可以用Inline来定义内联函数,不过,任何在类的说明部分定义的函数都会被自动的认为是内联函数。内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。这样,内联函数就和普通函数执行效率一样了,内联函数中一般没有循环和递归等结构。
- 宏与宏函数
- 内联函数 与 宏
- 宏与内联函数
- 宏与内联函数
- 宏与函数
- 内联函数与宏
- 宏与函数
- 宏与内联函数
- C宏与函数
- 宏与内联函数
- 宏与内联函数
- 宏与函数
- 宏与内联函数
- 宏与内联函数
- 宏与内联函数
- 宏与内联函数
- 内联函数与宏
- 宏与函数
- ——读《研堂见闻杂录》笔记
- 拉贝眼中的北京旧闻记者黄加佳新浪博客
- 叶永烈:她冒险保住傅雷的骨灰叶永烈新浪博客
- 《中国经营报》专栏-历史的碎片--秦始皇的死亡意识李冬君新浪博客
- mysql中Myisam锁问题
- 宏与函数
- Android之Home键监听封装
- $(this).bind("change",itemno_change);
- 首篇
- Steps
- Integer to Roman
- bind带autocomplete时,最好是从新的tr复制
- CDH的Cloudera Manage安装或升级
- 广度/宽度优先搜索(BFS)