联合体(共用体) union 的深入理解

1.联合类型的定义:

联合也是一种特殊的自定义类型
这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。

//联合类型的声明
union Un
{
char c;
int i;
};


//联合变量的定义
union Un un;


//计算连个变量的大小
printf("%d\n", sizeof(un));

 

解析:联合体(并不一定是共用完全部,有可能是不完全共用,只共用一小部分;或是联合体中的其他元素加起来的字节数要大于最大的那个元素的字节数,会把联合体共用完,然后占用新的内存字节)是先共用低地址处的字节的,当联合体中的一方被修改,另一方也会被修改,所以在使用联合体变量时,一般只用其中的一个。并且联合体也遵守结构体对齐的原则,联合体的总字节数要是联合体的元素中的最大对齐数的最小整数倍;

二、联合体的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联
合至少得有能力保存最大的那个成员)。

union Un
{
int i;
char c;
};
union Un un;


// 下面输出的结果是一样的吗?
printf("%d\n", &(un.i));
printf("%d\n", &(un.c));

解析:结果是一样的,都是联合体的首地址。


//下面输出的结果是什么?
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);

解析:结果是 11223355,nu.i被后面共用位置的nu.c的赋值修改了。

若是nu.c先赋值,nu.i后赋值,那么输出结果就是 11223344。

可以运用该方法,对这里的nu.c进行修改,来确定编译的大小端,因为联合体的共用都是从低地址开始的,如果使用nu.c对nu.i进行修改,并un.c为66,如果输出结果是(高字节处)11223366(低字节处),则说明(高地址)(高字节)11223366(低地址)(低字节),则说明是小端存储;如果输出结果是(高字节)(低地址)66223344(低字节)(高地址),则说明是大端存储。

联合体中含有数组时,

(本来也是)数组也是先将元素存放在低地址处的,从下标小到大,地址也从小到大。所以联合体的低地址中是元素的低下标的元素,并且vs编译器中也遵循小端存储,所以低下标处的元素是放在低字节处的。

例:

#include<stdio.h>
int main()
{
  union
  {
    short k;
    char i[2];
  }*s, a;
  s = &a;
  s->i[0] = 0x39;
  s->i[1] = 0x38;
  printf(“%x\n”,a.k);
  return 0;
}

解析:输出结果是 3839,打印的结果是左边高字节,右边低字节;union只有2字节,2字节的十六进制只有4位,所以答案CD排除。而位顺序类似小端,低地址在低处,所以39是低地址,在低位,38在高位,所以是3839,故选A。

堆栈的时候是先利用高地址的,这点要区别于联合体。

栈区中,先利用高地址建立联合体→联合体中先利用低地址存放元素→联合的数组中存放元素是先从低地址开始。



 

  • 10
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值