zoukankan      html  css  js  c++  java
  • C语——宏小结

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

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

    其中参数列表是一个由逗号分隔的符号列表,对应参数作用于stuff中,相当于宏替换函数;如果没有参数列表,那就是我们平常用得比较多的宏替换变量了。

    使用特别要注意问题


    1. 分号问题

    2. 符号优先级问题

    3. 作用域问题

    4.使用带副作用的宏参数

    宏定义处用了分号

    #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;
     }

    改造:

     #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. 替换插入代码,导致程序代码长度大大加长。

  • 相关阅读:
    SPOJ 8093 JZPGYZ
    UVA1030 Image Is Everything
    UVA11996 Jewel Magic
    UVA11922 Permutation Transformer
    UVA1479 Graph and Queries
    P3224 [HNOI2012]永无乡
    UVA11020 Efficient Solutions
    UVA12206 Stammering Aliens
    UVA11107 Life Forms
    UVA11019 Matrix Matcher
  • 原文地址:https://www.cnblogs.com/tp-16b/p/9200703.html
Copyright © 2011-2022 走看看