zoukankan      html  css  js  c++  java
  • 宏定义

    预处理

     预处理是程序编译前的一个预先处理的动作,编译一共有4个步骤:C原文件 --> 预处理 --> 编译 --> 汇编 -> 链接 --> 可执行文件。
    预处理的工作主要是展开我们C源码中的#开头的语句,去掉了所有的注释,在严格的意义来说,这些语句它并不属于C语言的语法范畴。
     以下是预处理的一些指令:
      1.头文件 : #include
      2.宏定义 : #define
      3.取消宏 : #undef
      4.条件编译 : #if #ifdef #ifndef #else #elif #enif
      5.显示错误 : #error
      6.修改当前文件的名字行号 :#line
      7.向编译器中发送特定的指令 : #progma
     可以在编译程序的时候添加一个-E的选项,让编译器在预处理之后停下来不要继续往下走,macro.i是源程序将#展开的内容。

    gcc macro.c -o macro.i -E 
    

    宏的概念

     宏(macro)实际上以一段字串,在源码中只是用来直接替换目标位置,一般宏都使用全大写字母(这只是一个习惯)。

    #define    PI           3.141592 
    #define    BUF_SIZE     64 
    int main (int argc, char const *argv[])
    {
          printf("PI:lf	" , PI); 
          int a = 100 + PI ; 
          printf("a:%d
    ", a);
    } 
    
    输出:PI:3.141592    a:103
    

    注意:
    1.PI就是一个宏,在我们的源代码中如果出现宏的使用,则通过预处理之后会直接被替换,只是直接的字符替换而已,不会考虑语法或运算关系。

    无参宏

     无参宏意味着我们在使用的时候不需要传递参数

    #define    BUF_SIZE     64 
        
    int main (int argc, char const *argv[])
    {
          int arr[BUF_SIZE];   //定义了一个int型数组,大小为64个
    }
    

    注意:
    1.宏他的本指就值直接的替换,没有任何的语法检查;
    2.使用宏的情况下如果代码有跟新迭代时,只需要修改宏的一处,整个代码中所有用到宏的地方都会被修改;
    3.宏的名字可以提高代码的可读性。

    带参宏

     带参宏 在使用的时候需要携带参数来使用。

    #define MAX(a,b) a>b ? a : b 
    int main (int argc, char const *argv[])
    {
          printf("%d	" , MAX(100,998) );  
          printf("%d
    " , 100>998 ? 100 : 998 ); 
    } 
    输出:998      998
    

    注意:
    1.使用带参宏的时候也是直接替换。
    2.只是存粹的文本替换,没有任何的语法检查/判断,也没有任何的运算
    3.宏在预处理之后已经被替换,代码实际运行时是不需要额外的时间开销,只会浪费一点内存的空间。

    带参宏的副作用

     由于宏只是存粹的文本替换,中间不涉及任何的计算与语法检查,类型匹配,所以用起来会比用函数麻烦很多。

    #define     MAX(a,b)    a>b ? a : b
    
    int main (int argc, char const *argv[])
    {
          int x = 100;
          int y = 200; 
          printf("MAX:%d
    " , MAX(x,y == 200 ? 888:999 ) ); 
    }
    

    从以上的代码中, 不管表达式 y == 200 ? 888:999  的值都是大于 x ,但是却出来最大值为x 、
    观察一下替换后的结果:

        printf("MAX:%d
    " , x>y == 200 ? 888:999 ? x : y == 200 ? 888:999 );   //注意从右向左运算,?的优先级大于:
    

    所以应该修改长如下:

        #define   MAX(a,b)  (a)>(b) ? (a) : (b) 
        printf("MAX:%d
    " , (x)>(y == 200 ? 888:999) ? (x) : (y == 200 ? 888:999) ); 
    

    使用括号对宏当中的每一项括起来,提高优先级,这样替换之后逻辑不会出现问题。

  • 相关阅读:
    透视投影矩阵的推导
    选择排序
    递归运动函数的实现
    插入排序
    基本光照模型
    顶点法向量从物体坐标系变换到世界坐标系
    Phong和BlinnPhong光照模型
    unity3d使用脚本保存屏幕截图
    【转】C++11常用特性的使用经验总结
    右手坐标系下LookAt视图矩阵的推导
  • 原文地址:https://www.cnblogs.com/ding-ding-light/p/14094479.html
Copyright © 2011-2022 走看看