预处理器之宏的使用
来源:互联网 发布:博森瑞大数据dba培训 编辑:程序博客网 时间:2024/06/06 05:04
我们知道C程序在编译过程之前,C语言预处理器首先对程序代码作了了必要的转换处理。 宏在C程序中是非常有用的,比如我们可以通过修改宏定义来修改在程序中出现的所有实例。同时通过宏定义还可以免去函数调用带来的重大系统开销。
虽然宏定义非常有用,但是宏定义也是非常容易出错的。主要表现为以下几点:
1、 不能忽视宏定义中 的空格
比如在下面的宏定义中
#define f (x) ((x)-1) 因为在f和(x)之间有一个空格,所以这个宏定义实际代表的是f 代表(x) ((x)-1),这和我们预想的f (x)代表((x)-1)相去甚远。
****这里需要特别注意的是,虽然在宏定义的时候空格不能忽视,但是当我们在程序中用到宏定义时,空格却是可以忽略的,比如我们的宏定义中#define f(x) x+3;在程序中我们可以用f(x)来调用该宏,这时候是没有任何错误的。
2、宏并不是函数
因为宏从表面上看其行为与函数非常相似,我们有时候会把他们视为完全相同。然而情况却并非如此。
比如我们定义一个宏 #define max(a,b) a>b?a:b; 但是当我们计算max(x-z,y-z)时,宏展开后的结果却和我们预想的相去甚远,展开为 x-z>y-z?x-z:y-z; 显然这不是我们想要的结果。因此在进行宏定义的时候我们最好都把每个参数用大括号括起来。同样整个结果表达式也应该用括号括起来,以防止当宏用于一个更大一些的表达式中可能出现的错误问题。
是不是这样的宏就没有任何问题了,当然不是!!!!!!!!!!!在宏调用中,如果一个操作数在两处被调用,就会被求值两次,比如我们定义的宏#define max(a,b) a>b?a:b; 在进行宏调用时,max(x++,y++);中的x和y都用可能被++两次,解决这种问题的方法有两个,要么不使用宏调用,将宏改为函数,要么宏调用中的参数没有副作用。
3、宏并不是类型定义
很多编程者都喜欢用宏来定义一种数据类型,比如 :
#define FOOTYPE struct foo *
FOOTYPE a;
FOOTYPE b,c;
编程者本来的意图是将b,c都定义为指向结构的指针,而事实上将第二个声明扩展开为
struct foo * a,b;
这个语句中a被定义为一个指向结构的指针,而b却被定义为一个结构(而不是指针);
- 预处理器之宏的使用
- 工作总结之预处理指令与宏的使用
- MySQL入门之预处理语句的使用
- 宏使用之预处理操作符总结
- ProC中使用宏的预处理流程
- ”预处理器定义“使用
- 我的研究之预处理
- #pragma预处理命令的使用
- #pragma预处理命令的使用
- #pragma预处理命令的使用
- 预处理指令 #pragma 的使用
- C#预处理指令的使用
- 方便的预处理器特征(宏)
- 通用预处理器宏assert()的用法
- 预处理器(宏的用法)
- 预处理中宏定义"#"与"##"的区别之我见
- 预处理宏的问题
- 预处理器的介绍
- 系统滴答定时器(systick)的应用
- repeater+AspnetPager+存储过程分页
- C++使用ADO2数据库类查询、添加、修改、删除操作
- ABAP 绩效 组织单位 选择屏字段 搜索帮助
- android 命令行编译
- 预处理器之宏的使用
- Python的引用计数器
- 浏览器有水平滚动条时,把滚动条滑到最右边后,右边的背景颜色不显示解决方案,缩小窗口,拉动下方滚动条,背景缺失解决方案
- Python中类的继承
- 使用truss、strace或ltrace诊断软件的"疑难杂症"
- POJ2311
- Java中获取windows、Linux和windows7的MAC地址
- UVa575 Skew Binary
- android OutOfMemory时抓取heap快照