C语言自定义类型【联合体】

🚠订阅专栏:自定义类型
🚜关注博主:翻斗花园第一代码手牛爷爷
🚙gitee仓库:牛爷爷爱写代码



🚗前言

这篇文章我们来介绍第三个自定义类型——联合体(共用体)。联合体也是一种特殊的自定义类型,这种类型的变量也包含一系列的成员,特征是这些成员共用同一块空间。因此也称共用体。

🚕联合体的声明

联合体的关键字是union,联合体的声明与前两个自定义类型的声明有异曲同工之处。联合体的声明形式如下代码。

union num
{
	int i;
	char ch;
	short t;
};

🚒联合体的定义

联合体的定义我们可以在声明时进行定义,如下代码。

union num
{
	int i;
	char ch;
	short t;
}val2, val3;

也可以在函数中进行定义,如下代码。

union num
{
	int i;
	char ch;
	short t;
};

int main()
{
	union num val;
	return 0;
}

🚑联合体详解

🚒详解一

联合体的成员公用一块空间,我们通过一段代码来观察,如下代码。

union num
{
	int i;
	char ch;
	short t;
};

int main()
{
	union num val;
	printf("%d\n", sizeof(val));
	printf("%d\n", sizeof(union num));
	return 0;
}

我们通过sizeof计算出这个联合体的大小,运行结果如下图。
在这里插入图片描述
我们现在来分析联合体成员共用一块空间到底是怎么来进行共用的。首先我们知道如果几个成员想要共用一块空间的话,那么这块空间就必须得足够放下这几个成员,所以就得取这几个成员中所占空间最大的成员的空间作为共用的空间。在上述代码中我们来看联合体成员,变量iint类型,变量chchar类型,变量tshort类型,在vs下我们知道int类型占4个字节,char类型占1个字节,short类型占2个字节,所以这个联合体的大小就是4个字节。

🚚详解二

在知道了联合体的大小之后,我们又想,联合体成员在同一块空间中又是怎么存储的呢?下面我们用一段代码来观察分析,如下代码。

union num
{
	int i;
	char ch;
	short t;
};

int main()
{
	union num val = { 0 };
	printf("%p\n", &val.ch);
	printf("%p\n", &val.i);
	printf("%p\n", &val.t);
	
	return 0;
}

我们用%p来打印各个成员的地址,运行结果如下图。
在这里插入图片描述
我们可以观察到,每个成员的起始地址都是一样的,证明他们共用了一块空间。在此基础上,我们画图来进行理解分析,如下图。
在这里插入图片描述
在理解联合体的存放机制后我们可以发现,当我们存放第一个数据进去的时候没什么影响,但是当我们存放第二个数据进去的时候,那么第一个数据就会改变。我们用代码来观察,如下代码。

union num
{
	int i;
	char ch;
	short t;
};

int main()
{
	union num val = { 0 };
	val.i = 10;
	printf("%d\n", val.i);
	val.t = 1;
	printf("%d\n", val.i);
	return 0;
}

我们创建一个变量,然后将10赋值给i,打印i的值后在将1赋值t,然后再打印i的值,观察两次结果的变化,运行结果如下图所示。
在这里插入图片描述
我们可以观察到i的值发生了变化,再次证明了联合体成员共用一块空间。

🚑详解三

前面我们说联合体的大小是最大成员的大小,这种说法其实是不完全正确的,正确的说法因该是联合体的大小至少是最大成员的大小,而且还有一条规则是当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。这里我们还是通过代码来进行观察,如下代码。

union num
{
	int i;
	char ch[5];
};

int main()
{
	union num val = { 0 };
	printf("%d\n", sizeof(union num));
	return 0;
}

这个代码当我们不注意第二条规则的话,我们很容易就认为这个联合体的大小就是5,但是当我们结合第二天规则我们发现,联合体的成员的最大对齐数为4,而最大成员的大小为5,5不是4的整数倍,因此需要扩容到最大对齐数的整数倍,联合体的大小就为8。我们运行代码观察结果,如下图。
在这里插入图片描述
我们再画图进行分析,如下图。
在这里插入图片描述
其中黄色扩容出来的内存都是没有的内存。

🚐总结

更新到这,C语言自定义类型到这里又告一段落了,在文中如果有错误或者纰漏还望指正,欢迎评论区进行留言评论,如果觉得有帮助,希望大家支持一下,来个一键三连。在这里插入图片描述

在这里插入图片描述

  • 31
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 42
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拖拉机厂第一代码手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值