Fork me on GitHub
hahaya +
facebook send mail to hahaya sina weibo
关于订阅 hahaya's blog » Blog » blog
分类:
标签:

之前只是知道有union这个东西,但是几乎没有使用过,最近在看libevent的源码,发现其中用到了union,就查了一些关于union的资料,发现union有很多妙用,就顺便记录在此。

联合union

union和struct有一些相似之处,但是两者有本质上的不同。在struct中,每个成员有各自的内存空间,一个struct变量的总长度是各成员长度之和。而在union中,各成员共享一段内存空间,一个union变量的长度等于各成员中最长的长度。这里所谓的共享不是指多个成员同时装入一个联合变量中,而是只该union变量可以被赋予任一成员指,但是每次只能赋一种值,赋入新值则冲去旧值,下面使用一个例子说明:

#include <stdio.h>

union NUM{
    int a;
    int b;
};

/**
 * 定义一个名为DATA的union类型,它有两个成员变量:一个整形、一个char型数组
 * 这个DATA类型的union可以存放整形量no或存放char数组name
 */
union DATA{
    int no;
    char name[10];
};

int main(int argc, char **argv){
    NUM num;
    num.a = 1;


    //在32位机上,union所占空间为NUM中长度最长的变量所占空间 故为4
    printf("the size of union:%d\n", sizeof(num));
    //在union中各变量公用内存 所以a和b使用相当的内存 故对其中一个赋值
    //相当与对另一个赋值
    printf("the value of union a=%d, b=%d\n", num.a, num.b);

    return 0;
}

使用union让代码更加方便阅读

假设需要一个3*3的数组,我们可以使用如下方法写:

#include <stdio.h>

struct Data{
    int a;

    /*
     * 联合中的结构体和数组共享内存,并且两者使用相同大小的内存,所以不会有空间浪费
     * 需要其中的某个元素时可以使用 data.float_num.f1来代替m.f[0][0],
     * f[0][0]在使用起来不方便、直观,并且容易出错
     */
    union{
        struct{
            float f1, f2, f3, f4, f5, f6;
        };

        float f[3][3];
    }float_num;
};

int main(int argc, char **argv){
    struct Data data;
    data.float_num.f1 = 1.00;
    data.float_num.f2 = 2.00;
    data.float_num.f3 = 3.00;
    data.float_num.f4 = 4.00;
    data.float_num.f5 = 5.00;
    data.float_num.f6 = 6.00;

    printf("f[0][0]=%f\n", data.float_num.f1);
    
    return 0;
}

使用union节省内存

假设有一个二叉树,根节点和中间节点不存放数据,只存放左右子节点指针,而叶子节点只存数据而没有子节点,我们有如下两种方法定义二叉树的节点

struct Node{
    struct Node *left_node;
    struct Node *right_node;
    float data;
};

union Node{
    struct{
        struct Node *left_node;
        struct Node *right_node;
    }pPointer;

    float data;
}

在32位机器上,使用结构体时,需要的内存空间大小为:4 + 4 + 8 = 16,而使用联合union时,需要的内存空间大小为最大长度成员需要的内存空间大小,即为:8。由此可知,使用union能节省每个节点能节省一半的内存空间。在libevent中也有许多类似的用法。

作者:hahaya
出处:http://hahaya.github.com/use-union
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
分类: 标签:
点击查看评论