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

    1,定义一个宏,计算数组的长度
    #define ARRAYSIZE(a) sizeof(a)/sizeof(a[0])

    2,定义一个宏,计算结构体中成员的偏移
    #define offsetof(s,m) (size_t)&(((s *)0)->m) 

    3,多语句宏:
    在程序设计中,另外一个很经典的算法就是将两个数进行交换。比如有2个整数:
    int a = 10;
    int b = 20;
    交换后,a的值为20,b的值为10。在程序里面,必须要使用一个临时变量,来先把a的值保存起来,然后再把b的值赋给a,再把临时变量保存起来的a的值赋值给b。如果不用临时变量把a的值保存起来,那么当把b的值赋给a的时候,a的值就会丢失。 错误的写法如下:
    a = b; //a的值丢失
    b = a;//a和b的值最终都是b的值
    正确的写法:
    int tmp = a; //使用tmp变量保存a的值
    a = b;
    b = tmp;
    上面的算法可以用宏来定义如下:
    #define SWAP(a,b)
    {
        int tmp;
        tmp = a;
        a= b;
        b = tmp;  
    }
    上面的宏定义中,每行语句都用一个’’来连接,用来将两个int类型的整数交换。然后在程序中使用这个宏定义如下: 
    void main(void)
    {
        int a = 10;
        int b = 20;
        SWAP(a, b);
        printf(“a=%d, b=%d ”, a, b);
    }
    这种对于多条语句的定义方法,虽然在普通的时候一般不会出现什么问题。但是,来看看下面的条件语句:
    If (x>y)
        SWAP(a, b);
    else
        SWAP(a,b);
    如果对上面的条件语句进行宏展开,就得到了下面的程序:
    if (x>y)
    {
        int tmp;
        tmp = a; 
        a= b; 
        b = tmp; 
    };
    else
    {
        int tmp;
        tmp = a;
        a= b; 
        b = tmp; 
    };
    很显然,else语句部分会和if语句被;语句分割,所以会出现一个语法错误。即else语句会找不到if语句与之配对了。
    于是,多余多条语句定义的宏,一般采用do-while(0)的格式来定义:
    #define SWAP(a,b)
    do {
        int tmp;
        tmp = a;
        a= b;
        b = tmp;
    }while(0)
    这样,上面的程序展开之后:
    if (x>y)
    do{
        int tmp;
        tmp = a; 
        a= b;
        b = tmp;
    }while(0);
    else
    do {
        int tmp; 
        tmp = a;
        a= b; 
        b = tmp;
    }while(0);
    这样宏定义中的语句也只执行一次就退出了do-while循环,也避免了上面宏定义出现的一个特殊错误。

    4,宏就是简单替换。记住这是简单的替换而已,不要在中间计算结果,一定要替换出表达式之后再算。
    比如#define MAX(a,b) ((a)>(b)?(a):(b))
    则遇到MAX(1+2,value)则会把它替换成:
    ((1+2)>(value)?(1+2):(value))

    5,对于宏的二义性,来看看下面的例子。从下列选项中选择不会引起二义性的宏定义是:
    A、 #define POWER(x) x*x
    B、 #define POWER(x) (x)*(x)
    C、 #define POWER(x) (x*x) 
    D、 #define POWER(x) ((x)*(x))
    分析:
    A.#define POWER(x) x*x 
    如果调用POWER(5+6),本意是 (5+6)*(5+6)=121,实际却是:5+6*5+6=41
    B.#define POWER(x) (x)*(x)
    如果调用POWER(5+6)/POWER(5+6),本意是得到结果为1,实际却是:(5+6)*(5+6)/(5+6)*(5+6)=11*11/11*11=121
    C.#define POWER(x)(x*x) 
    如果调用POWER(5+6)+POWER(5+6),本意是 (11*11)+(11*11)=121+121=242,实际却是: (5+6*5+6)+(5+6*5+6)=41+41=82
    D.没有二义性。

  • 相关阅读:
    Mysql学习笔记(十四)备份与恢复
    Mysql学习笔记(十三)权限管理
    docker容器持久化卷讲解
    logstash关于date时间处理的几种方式总结
    ELK收集tomcat状态日志
    ELK收集tomcat访问日志并存取mysql数据库案例
    利用fpm制作rpm包
    Elasticsearch一些常用操作和一些基础概念
    Linux Cluster
    LNMP下动静分离部署phpmyadmin软件包
  • 原文地址:https://www.cnblogs.com/fengxing999/p/11142527.html
Copyright © 2011-2022 走看看