C语言 || 联合(共用体)

目录

联合类型的定义

联合的特点

联合大小的计算


联合类型的定义

联合是一种特殊的自定义类型

这种类型定义的变量也包含一系列的成员,这些成员会共用一块空间

//联合类型的声明,联合关键字union+联合类型Un
union Un   创建了Un类型
{
    char a;
    int i;
}u1;    //创建了一个Un类型的变量u1
        //u1是全局变量
int main()
{
    union Un u2;    //创建了一个Un类型的变量u2,u2是局部变量
    return 0;
}

我们知道了如何定义一个联合体类型,现在我们来计算一下Un这个类型的联合体有多大

union Un  
{
    char a;    //1字节
    int i;    //4字节
}u1;           //sizeof(union Un)是多少呢?

答案是多少呢,我们来放到编译器中运行一下 

你想到了吗?你可能会想char类型占1一个字节,int类型占4个字节,至少也得是5个字节吧?那么为什么呢?我们接着来看 

我们惊讶的发现,三个地址竟然是一样的

为什么会这样呢,我们就需要说说联合的特点 

联合的特点

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

union Un  
{
    char a;   
    int i;   
}u1;           

这是一块内存空间,先存储char类型变量a(1个字节)

        a

我们由前面的图示可知u1.i的地址和u1.a的地址是一样的,因此这块内存空间接下来在存储int类型变量i(4个字节)时会变成如下

        i        i        i        i

我们发现a和i会共用一块空间,这就是为什么之前图片三者地址相同的原因,至于第一个计算联合体大小的问题,我放到了下一块内容进行描述

因为联合会共用一块空间,因此联合与结构体的初始化略有不同

 

 结构体这样初始化,只会把变量a初始化为10,变量i为默认值0,但联合体就不一样了

  因为联合体的成员会共用一块内存,会将所有的成员一同初始化

再看下段代码

u.i的赋值会覆盖掉对u.a的赋值(改a的时候i会改,改i的时候a又会改),因此联合的特点还有:同一时间只能使用它的一个变量 

联合大小的计算

现在回归到我们一开始遗留的一个问题,到底如何计算联合体的大小

联合有自己的对齐方式

1.联合的大小至少是最大成员的大小

2.当最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍

union Un  
{
    char a;    //对齐数是1
    int i;    //对齐数是4   
};           //最大对齐数是4

在Un类型的联合体中,最大成员的大小是4,而4正好又是最大对齐数的整数倍,因此sizeof(union Un)的结果就是4

我们在举两个例子

union Un1
{
    char c[5];
    int i;
};
union Un2
{
    short c[7];
    int i;
};        //sizeof(union Un1)和sizeof(union Un2)的结果是多少?

来看第一个

union Un1
{
    char c[5];    //成员大小为5,对齐数为1
    int i;        //成员大小为4,对齐数是4
};        //最大对齐数是4

 联合体大小至少是最大成员的大小5,但5不是最大对齐数4的整数倍,因此向上取到8,因此Un1类型的大小是8

第二个

union Un2
{
    short c[7];    //成员大小是14,对齐数是2
    int i;        //成员大小是4,对齐数是4
};                //最大对齐数是4

联合体大小至少是最大成员的大小14,但14不是最大对齐数4的整数倍,因此向上取到16,因此Un2类型的大小是16 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值