C++常见问题之二#define使用中的陷阱
来源:互联网 发布:简单好唱的英文歌知乎 编辑:程序博客网 时间:2024/06/07 07:28
一.使用#define宏应注意的问题
1.使用宏定义表达式的时候,加括号是一个好习惯
首先我们来看一段简短的代码,并试着分析其输出:
#include <iostream>#define Add(a,b) a+bint main(){std::cout<<Add(1,2)*Add(2,3)<<std::endl;return 0;}
结果输出:
很显然,当我们看到这么一段代码的时候,肯定会呲之以鼻,认为这么简单的错误怎么可能发现不了?别急,这还只是开始,下面我们在对上述代码进行改进,便有了下面的代码:
#include <iostream>#define Add1(a,b) (a+b)#define Add2(a,b) (a) + (b)#define Mul(a,b) (a*b)int main(){std::cout<<Add2(1,2)*Add2(2,3)<<std::endl; //理论上应该是 15std::cout<<Mul(Add2(1,2),3)<<std::endl;//理论上应该输出 9system("pause");return 0;}
结果输出:
上述结果表明,即使是整体加上括号或者分别单独加上括号都不能很好的解决问题,最完备的解决方案就是不要吝啬你的括号,用完备的括号完备的保护每一个宏参数,也就是说,针对上述案例,应该这样:
#define Add(a,b) ((a)+(b))
#define Mul(a,b) ((a)*(b))
2.使用宏的时候,参数不能变化
首先,照例我们还是来看一段问题代码:
#include <iostream>#define CUBE(a) ((a)*(a)*(a))inline int Cube(int a){return a*a*a;}int main(){int base1 = 2,base2=2;int nCube1 = CUBE(++base1);int nCube2 = Cube(++base2);std::cout<<"nCube1 = "<<nCube1<<std::endl;std::cout<<"nCube2 = "<<nCube2<<std::endl;system("pause");return 0;}
再看一下输出结果:
其实这样的结果也很好理解,因为宏是单纯的替换,每一次替换都自增了一次,这就是宏在展开时对其参数的多次取值替换所带来的副作用,为避免这种情况,最简单的方法就是保证使用宏的时候参数不能变换。
3.用大括号将宏所定义的多条表达式括起来
我们还是来看一段示例:
#include <iostream>typedef struct Cube{int x;int y;int z;};#define INITIAL(a,b,c)\a=1;\b=2;\c=3;int main(){int x,y,z;INITIAL(x,y,z);std::cout<<"x = "<<x<<" y = "<<y<<" z = "<<z<<std::endl;//OK no problemCube cube[10];int i=0;for (;i<10;++i)INITIAL(cube[i].x,cube[i].y,cube[i].z);for (i=0;i<10;++i)std::cout<<cube[i].x<<" "<<cube[i].y<<" "<<cube[i].z<<std::endl;system("pause");return 0;}
结果显示:
其实说来说去还是一个宏替换的范围问题,改正很简单,只要在宏定义的时候加上大括号就行了,其实宏是一个很强大的工具,但是我们在用的时候要格外的小心,千万不要吝啬你的括号。
4 2
- C++常见问题之二#define使用中的陷阱
- C陷阱篇之define的缺陷
- 建议4:小心宏#define使用中的陷阱
- 改善C++ 程序的150个建议学习之建议4:小心宏#define使用中的陷阱
- 【C语言探索之二】内存陷阱
- C语言中define的陷阱
- C/C++ 之 define的使用
- C++.net常见问题之二(字符串)
- C陷阱(二)
- python(二):使用multiprocessing中的常见问题
- 关于宏#define使用陷阱总结
- C #define中的 "\,#,## #@"
- C #define中的 "\,#,## #@"
- C++Primer学习之二#define,const,constexpr
- C陷阱篇之复合表达式中的确定与不确定
- C语言define之#,##
- C语言之define
- C陷阱与缺陷之词法陷阱
- TFIDF算法及应用
- PAT 1072. Gas Station
- 基础2
- HTML5网页如何让所有的浏览器都能识别HTML5标签样式
- 为了是浏览器识别<mxria></mxria>标签并显示对应样式的效果
- C++常见问题之二#define使用中的陷阱
- iOS 中正则表达式使用方法汇总
- Intel and AMD Manuals
- capitalism lab自动存档问题
- ddddddddddddd
- DLL搜索路径和DLL劫持
- LeetCode(151)Reverse Words in a String
- First Missing Positive -- LeetCode
- 编译 ARM 上的 GDB