C语——宏小结

c语言关于宏的使用十分频繁。可是宏的使用有利也有弊,与此同时,它仍是一个特别容易搞错的地方。正是基于此,它经常成为一些面试会侧重考察的地方。ios

所谓宏就是 #define 机制包括的一个规定,即容许把参数替换到文本中。它的声明方式:#define name(参数列表) stuff  面试

其中参数列表是一个由逗号分隔的符号列表,对应参数做用于stuff中,至关于宏替换函数;若是没有参数列表,那就是咱们日常用得比较多的宏替换变量了。安全

使用特别要注意问题

 


1. 分号问题函数

2. 符号优先级问题spa

3. 做用域问题调试

4.使用带反作用的宏参数code

 

宏定义处用了分号blog

#include <iostream>
using namespace std; #define MAX( l, r) l > r? l: r; 
int main() { int a =1 , b=2; if( a) int max = MAX( a,b);// <=> max = a > b? a:b;; 出错!!
    else { } return 0; }

 

 

符号优先级问题作用域

 #include <iostream>
 using namespace std; #define MAX( l, r) l > r? l: r 
 int main() { int a =1 , b=2; int max = MAX( a && 3, b);//a && 3 > b? a && 3: b 达不到预想结果
     cout<<max; return 0; }

改造:io

 #define MAX( l, r) ( (l)> (r)? (l) :(r) )   
 int main() { int a =1 , b=2; int max = MAX( a && 3, b);//(a && 3) > b? (a && 3) : b
     cout<<max; return 0; }

 

 

做用域问题

 

 #include <iostream> using namespace std; //=优先级很低,不用优先级问题
 #define SWAP(l, r) {\ int tmp = l;\ l = r; \ r = tmp;} int main() { int a =1 , b=2; if(a) SWAP(a, b); //<=> {.... } ;   此处只容许出现一条语句,但这里产生2条
 else { } cout<<a <<" "<<b<<endl; return 0; }

 

解决:用do{... }while(0)  解决

 //=优先级很低,不用优先级问题
 #define SWAP(l, r) do{\ int tmp = l;\ l = r; \ r = tmp;}while(0) int main() { int a =1 , b=2; if(a) SWAP(a, b); //<=> do{.... }while( 0) ;  else { } cout<<a <<" "<<b<<endl; return 0; }

 

 

带反作用的宏参数

当宏参数在宏定义中出现次数超过一次时,若是这个参数具备反作用,那么当使用这个宏时就出现危险,致使不可预料的结果。反作用就是在表达式求值时出现永久性的效果。好比x++,它能够增长x的值。当下一次执行该表达式时,他将产生一个全新的结果。仍是之前面的的MAX函数为例

 #include <iostream>
 using namespace std; #define MAX(l, r) ( (l)>(r)? (l): (r)) int main() { int a =1 , b=2; int max = MAX(a++, b++); //<=> (a++)>( b++)? ( a++):( b++); //结果: 3 2 4
 cout<<max<<" "<<a<<" "<<b<<endl; return 0; }

 

结果让较小的值a增长了一次,但确让较大的值b增长了2次。这种带反作用宏参数会修改变量的值,使用需格外注意。

 

 

宏的优缺点


 优势

1. 快! 因为是预处理时期直接宏替换,不用像函数那样来回调用返回,增长额外开销。

2. 因为能够替换变量,修改变量仅需在宏定义处修改,增长了程序的可维护性。

 

缺点:

1. 没有类型安全的检查。宏和类型是无关的,只要对参数操做合法,它可使用任何参数类型。

2. 极易出错。  宏参数求值是要依赖于周围表达式的上下文环境。没有合理地加括号,得不到指望的结果; 同时参数每次用于宏定义时,它们都会从新求值,因为这样屡次求值,因此让具备反作用的参数可能产生不可预料的结果。

3. 不可调试。因为预处理阶段,直接进行了宏替换,对替换掉的代码没法进行调试检查。

4. 替换插入代码,致使程序代码长度大大加长。

相关文章
相关标签/搜索