打印
[ARM入门]

C 陷阱与缺陷学习 笔记 —— 六、预处理器

[复制链接]
512|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
千岁寒|  楼主 | 2018-10-24 19:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
宏:只对程序其文本作用
  • 注意宏中的空格(区分的关键) #define   Func(x) (x*2+3)
        例如:#define  F (x)  ((x)-1)    
  • 注意括号的安全使用
        例如
        #define f(x)(x*x)
              替换结果为:e=(a+b*a+b)*(c+d*c+d) = 5*34=170
        #define f(x) x*x  
              替换结果为:e=a+b*a+b*c+d*c+d=1+2+12+24+4=43
         #define f(x) ( (x)*(x) )
              替换结果为:e=( (a+b)*(a+b)*(c+d)*(c+d) )=3*3*10*10=900
  • 宏不是函数 #define  abs(x)  x>0?x:-x
        例如: abs(a-b)    <---> a-b>0?a-b:-a-b    ERROR
        所以每个元 都要加括号
       #define   abs(x)   ( (x) >0 ? (x) : (-(x)) )
        例如:abs(u8Data[i++])  引入可变元之后导致展开的各项都做了重复操作 ERROR
  • 宏不是语句
         例如:#define  assert(e)   if(!e)  assert_erroe(__FILE__, __LINE__)


                 if(x>0 && y>0)
                        assert(x>y);
                    else
                        assert(y>x);
ERROR
                    if(x>0 && y>0)
                         if(!(x>y))  
                            assert_erroe(__FILE__, __LINE__);
                         else
                             if(!(y>x))  
                                assert_erroe(__FILE__, __LINE__);


例如:#define  assert(e) \
                            {  if(!e)  assert_erroe(__FILE__, __LINE__)  ; }



     if(x>0 && y>0)
                        assert(x>y);
                    else
                        assert(y>x);
ERROR
                    if(x>0 && y>0)
                    {    if(!(x>y))  
                            assert_erroe(__FILE__, __LINE__);
                    };  
                    else
                    {
                         if(!(y>x))  
                            assert_erroe(__FILE__, __LINE__);
                    };



解决办法:
                        1- 重新定义为一个函数
                        2- #define   assert(e) \
                                    ( (void) ( (e) || assert_error(__FILE__, __LINE__) ) )      
                            这实际上是利用  ||   运算符 对两侧的操作数依次求值的性质:
                                如果e为则符号右侧的表达式未进行运算就得出TRUE的结论;
                                如果e为假则符号右侧的表达式进行运算调用assert_error
                                void---强制无类型转换,告诉编译器不要waring!



  • 宏不是类型定义
注:与typedef的区别
            #define  T1  struct   foo *
            typedef struct foo *  T2;



           T1 a,b;      <!=>   T2 a,b
struct foo * a,b;    <!=>   struct foo * a;  struct foo * b;


相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

72

主题

244

帖子

4

粉丝