为什么80%的码农都做不了架构师?>>>   

当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union)。在C Programming Language 一书中对于联合体是这么描述的:

1)联合体是一个结构;

2)它的所有成员相对于基地址的偏移量都为0;

3)此结构空间要大到足够容纳最"宽"的成员;

4)其对齐方式要适合其中所有的成员;

下面解释这四条描述:

由于联合体中的所有成员是共享一段内存的,因此每个成员的存放首地址相对于于联合体变量的基地址的偏移量为0,即所有成员的首地址都是一样的。为了使得所有成员能够共享一段内存,因此该空间必须足够容纳这些成员中最宽的成员。对于这句“对齐方式要适合其中所有的成员”是指其必须符合所有成员的自身对齐方式。

下面举例说明:

如联合体

?union U
{
    char s[9];
    int n;
    double d;
};

s占9字节,n占4字节,d占8字节,因此其至少需9字节的空间。然而其实际大小并不是9,用运算符sizeof测试其大小为16.这是因为这里存在字节对齐的问题,9既不能被4整除,也不能被8整除。因此补充字节到16,这样就符合所有成员的自身对齐了。从这里可以看出联合体所占的空间不仅取决于最宽成员,还跟所有成员有关系,即其大小必须满足两个条件:1)大小足够容纳最宽的成员;2)大小能被其包含的所有基本数据类型的大小所整除。

测试程序:

/*测试联合体  2011.10.3*/
#include <iostream>
using namespace std;
union U1{   
        char s[9];   
        int n;   
        double d;
};

union U2{   
        char s[5];   
        int n;   
        double d;
};
int main(int argc, char *argv[]){  
         U1 u1;   
         U2 u2;   
         printf("%d\n",sizeof(u1));  
         printf("%d\n",sizeof(u2));  
         printf("0x%x\n",&u1);   
         printf("0x%x\n",&u1.s);  
         printf("0x%x\n",&u1.n);   
         printf("0x%x\n",&u1.d);   
         u1.n=1;  
         printf("%d\n",u1.s[0]);   
         printf("%lf\n",u1.d);   
         unsigned char *p=(unsigned char *)&u1;  
         printf("%d\n",*p);   
         printf("%d\n",*(p+1));   
         printf("%d\n",*(p+2));   
         printf("%d\n",*(p+3));  
         printf("%d\n",*(p+4));  
         printf("%d\n",*(p+5));  
         printf("%d\n",*(p+6));  
         printf("%d\n",*(p+7));   
         return 0;
}
复制代码

输出结果为:

16
8
0x22ff60
0x22ff60
0x22ff60
0x22ff60
1
0.000000
1
0
0
0
48
204
64
0
请按任意键继续. . .

对于sizeof(u1)=16。因为u1中s占9字节,n占4字节,d占8字节,因此至少需要9字节。其包含的基本数据类型为char,int,double分别占1,4,8字节,为了使u1所占空间的大小能被1,4,8整除,则需填充字节以到16,因此sizeof(u1)=16.

对于sizeof(u2)=8。因为u2中s占5字节,n占4字节,d占8字节,因此至少需要8字节。其包含的基本数据类型为char,int,double分别占1,4,8字节,为了使u2所占空间的大小能被1,4,8整除,不需填充字节,因为8本身就能满足要求。因此sizeof(u2)=8。

从打印出的每个成员的基地址可以看出,联合体中每个成员的基地址都相同,等于联合体变量的首地址。

对u1.n=1,将u1的n赋值为1后,则该段内存的前4个字节存储的数据为00000001 00000000 00000000 00000000

因此取s[0]的数据表示取第一个单元的数据,其整型值为1,所以打印出的结果为1.

至于打印出的d为0.000000愿意如下。由于已知该段内存前4字节的单元存储的数据为00000001 00000000 00000000 00000000,从上面打印结果48,204,64,0可以知道后面4个字节单元中的数据为00110000 11001100 01000000 00000000,因此其表示的二进 制浮点数为

00000000 01000000 11001100 00110000 00000000 00000000 00000000 00000001

对于double型数据,第63位0为符号位,62-52 00000000100为阶码,0000 11001100 00110000 00000000 00000000 00000000 00000001为尾数,根据其值知道尾数值约为0,而阶码为4-1023=-1019,因此其表示的浮点数为1.0*2^(-1019)=0.00000000000......,因此输出结果为0.000000。

===================================================================================================

联合体uniON的存放顺序是所有成员都从低地址开始存放,利用该特性就可以轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。

int checkCPUendian()
        {
                union
                {
                        unsigned int a;
                        unsigned char b;
                }c;
                c.a = 1;
                return (c.b == 1);
        }
        /*return 1 : little-endian, return 0:big-endian*/

转载于:https://my.oschina.net/3pgp/blog/189933

关于UNION联合体结构的运用相关推荐

  1. c# union结构体_P/Invoke各种总结(八、在C#中使用Union联合体)

    Union联合体(共用体) 这里稍微简单介绍一下union这种类型. 有时候需要使几种不同类型的变量存放到同一段内存单元中,例如:可把一个整型变量.一个字符串变量放在同一个地址开始的内存单元中.以上两 ...

  2. STM8学习笔记---union联合体的应用

    平时用单片机编写程序经常会遇到将一个16位数拆封为两个8位数,或者将将两个8位数组成一个16位数.如: data = data_h * 256 + data_l; data_h = data / 25 ...

  3. C++ union联合体

    union即联合体,在一个联合体可以定义多种不同的数据类型, 一个被声明为该联合类型的变量中允许装入该联合所定义的任何一种数据,这些数据共享同一段内存,以达到节省空间的目的.union变量所占用的内存 ...

  4. c语言 union 与结构 位域妙用

    测试1: #include <stdio.h> #include <string.h> int main() { union unCMD {// First Command B ...

  5. C语言union联合体中不同类型变量读取同一地址数据问题

    有下列代码 #include<stdio.h>union {int a[2];long b;char c[4]; }s;int main() {s.a[0]=0x12345678;s.a[ ...

  6. C/C++计算类/结构体和联合体(union)所占内存大小(内存对齐问题)

    目录 一,内存对齐的三条规则 二,注意事项: 三,举例说明 1,示例1 2,示例2 3,示例3 4,示例4 四,联合体(union) 五,字节对齐的原因 六,计算练习 一,内存对齐的三条规则 数据成员 ...

  7. 联合体union和大小端(big-endian、little-endian)

    1.联合体union的基本特性--和struct的同与不同 union,中文名"联合体.共用体",在某种程度上类似结构体struct的一种数据结构,共用体(union)和结构体(s ...

  8. java c语言union转换_C语言联合体(union)的使用方法及其本质-union

    转载自:https://blog.csdn.net/sizhouqun_84342712/article/details/53187106 1.联合体union的基本特性--和struct的同与不同 ...

  9. 结构体与共用体(联合体)

    参考:结构体与共用体 作者:一只青木呀 发布时间: 2020-08-09 08:29:22 网址:https://blog.csdn.net/weixin_45309916/article/detai ...

最新文章

  1. 基本概念,BGP协议的特征和消息类型,状态转换?
  2. keypair java_如何在Java中序列化和反序列化RSA KeyPair
  3. 2019-06-13 Java学习日记之MySql
  4. 【mysql基础知识】解决java连接mysql时将localhost改为本机的ip地址后失败问题
  5. 如何获得完美的调色板?完美的配色素材专辑拿走!
  6. 灰度资产管理总规模升至460亿美元
  7. 三相异步电机----电机公式(三)
  8. window10 重装后“未安装任何音频输出设备”
  9. Unity中不同平台快速切换
  10. 设计模式---002适配模式(转载自我的老师 Alley-巷子)
  11. http 代理服务器搭建 tinyProxy
  12. AutoX-1. 网页瀑布流 AutoX-2. 蚂蚁王国的蜂蜜
  13. FPGA Altera Remote Update笔记
  14. 《东周列国志》第四十八回 刺先克五将乱晋 召士会寿余绐秦
  15. 百度地图api卫星地球模式的调用
  16. 【Python】Pandas 表格样式设置指南,看这一篇就够了!
  17. 为什么Netty使用NIO而不是AIO
  18. 10 探索其他Excel对象
  19. 计算机专业论文docx,计算机专业精选论文.docx
  20. Java web开发——Servlet详细介绍

热门文章

  1. Python读CSV数据
  2. 使用Ansible中的playbook
  3. linux对文件的描述,对Linux文件系统的简单理解
  4. 源码安装nginx开启SSL功能
  5. C++_STL——list(and forward_list)
  6. oracle 序列号同步,关于序列同步的问题
  7. 用户信息检索另一台服务器,客户机上一用户访问另一台机器上的informix数据库...
  8. LNMP环境搭建(一)搭建PHP环境
  9. 多模态理论张德禄_观点 | 多模态研究:认知语言学的新方法
  10. python控制caxa模块_CAXA二次开发实用手册.doc