zoukankan      html  css  js  c++  java
  • 关于联合体union的详细解释

    1.概述

    联合体union的定义方式与结构体一样,但是二者有根本区别。

    在结构中各成员有各自的内存空间,一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间,一个联合变量的长度等于各成员中最长的长度。

    2.联合体长度

    在The C Programming Language里面讲述union内存分配的原话是

    1)联合体就是一个结构

    2)联合体的所有成员相对于基地址的偏移量为0

    3)此结构空间要大到总够容纳最“宽”的成员

    4)并且,其对其方式要适合于联合体中所有类型的成员

    我的理解可以概括为两点:

    1)联合体的结构空间要足够大,要等于最长的一个结构变量的空间,但是这个最长的空间要满足以下条件:

         1.要大于等于最长的一个结构变量的空间

          2.并且要能够整除其他结构变量的数据长度,即联合体空间对其他成员的元类型要能够整除(int a[5],其元类型为int,元类型长度为4),实际上就是要取一个元类型的最小公倍数。

    这儿举例来说

    [cpp] view plaincopy
     
    1. union    
    2. {  
    3.     float   fuel_load;  
    4.     char a[5]; 
    5.     int   pallets;  
    6. }fighter;  
    [cpp] view plain copy
     
    1. union     
    2. {   
    3.     float   fuel_load;   
    4.     char a[5];  
    5.     int   pallets;   
    6. }fighter;   


    这个结构体中,各个结构变量的空间分别为float   fuel_load; 占4个字节,char a[5];占5个字节,int   pallets;占4个字节。通过“3)此结构空间要大到总够容纳最“宽”的成员”这句话,我们可以认为是结构体的空间为5个字节即可,但是“其对其方式要适合于联合体中所有类型的成员”没有满足,对于这个问题,通过上面红色字体部分可以解决。,因此联合体空间为8.8可以整除 4(float、int长度)和1(char的长度),并且8大于数组5.

    再举一个例子有助于大家理解。

    [cpp] view plaincopy
     
    1. struct   aircraft  
    2. {  
    3. int   wingspan;  
    4. int   passengers;  
    5. union    
    6. {  
    7. float   fuel_load;  
    8. float   bomb_load;  
    9. int   pallets;  
    10. };  
    11. }fighter;  
    [cpp] view plain copy
     
    1. struct   aircraft   
    2. {   
    3. int   wingspan;   
    4. int   passengers;   
    5. union     
    6. {   
    7. float   fuel_load;   
    8. float   bomb_load;   
    9. int   pallets;   
    10. };   
    11. }fighter;   

     

    sizeof(fighter) 是12 。int   wingspan; int   passengers;两个int型 8个字节。union中 3个都是4个字节,因此union长度为4个字节,一共是4*3 =12字节。

    3.内存分配

    一句话:联合体变量的各个成员都是从低字节开始公用的。即:所有的成员都是从低字节开始的。

    我们先为整个union分配一个空间,这个空间大小就是上面(2)内存分配中所讲述的。

    [cpp] view plaincopy
     
    1. union { 
    2.       int i; 
    3.       char x[2]; 
    4. }a; 
    5. int main(void) 
    6.    a.x[0] = 10; 
    7.    a.x[1] = 1; 
    8.    printf("%d ",a.i); 
    9.    return 0; 
    [cpp] view plain copy
     
    1. union {  
    2.       int i;  
    3.       char x[2];  
    4. }a;  
    5. int main(void)  
    6. {  
    7.    a.x[0] = 0;  
    8.    a.x[1] = 0;  
    9.    printf("%d ",a.i);  
    10.    return 0;  
    11. }  


    其内存如下图所示。a.x[0] 处于低字节,x[1]高字节。当调用i这个成员变量的时候,其开始地址仍然是从起始地址开始,数4个字节输出。因此为 256 + 10 = 266

    4.附录 各个数据类型的长度

    type bytes

    int  4

    char 1

    short int 2

    bool 1

    long 4

    long long 8

    float 4

    double 8

    long double 8

    http://blog.csdn.net/laoyang360/article/details/7596251

  • 相关阅读:
    通过Eclipse生成可运行的jar包
    消息队列原理概念扫盲
    为mutable类型的容器(array,set等)添加kvo,有点麻烦,供参考和了解下吧
    iOS archive(归档)的总结 (序列化和反序列化,持久化到文件)
    http相关概念在iOS中的使用介绍
    AutoLayout技术选型和应用
    addChildViewController相关api深入剖析
    SymmetricDS 完全配置安装手册
    决策树之 C4.5 算法
    决策树之 ID3 算法
  • 原文地址:https://www.cnblogs.com/findumars/p/6417940.html
Copyright © 2011-2022 走看看