65.【C语言】联合体

目录

目录

1.定义

2.格式

3.例题

答案速查

分析

4.练习

答案速查

分析

5.相同成员的联合体和结构体的对比

6.联合体的大小计算

2条规则

 答案速查

分析

练习

答案速查

分析

7.联合体的优点

8.匿名联合体


1.定义

和结构体有所不同,顾名思义:所有成员联合使用同一块内存空间,因此也叫共用体

注:编译器只为最大的成员分配足够的内存空间;如果不符合对齐数,则会增加一部分空间(有关联合体的大小计算见第6点)给联合体其中一个成员赋值,其他成员的值也跟着变化

2.格式

union 联合体标签
{
  //......
};

3.例题

求下列代码的执行结果

#include <stdio.h>
union U
{
	char a;
	int b;
};

int main()
{
	printf("%zd\n", sizeof(union U));
	union U u;
	printf("%p\n", &u);
	printf("%p\n", &u.a);
	printf("%p", &u.b);
	return 0;
}

答案速查

d4118c9946ba4652ad1c468a86b830dc.png

分析

01.printf("%zd\n", sizeof(union U));

编译器只为最大的成员分配足够的内存空间

char a 对齐数为1,int b对齐数为4(注:联合体对齐数的计算方法同结构体的),因此为a和b分配4字节的空间

02.printf("%p\n", &u); & printf("%p\n", &u.a); & printf("%p", &u.b);

所有成员联合使用同一块内存空间,因此取地址的结果一样

4.练习

求下列代码执行后,联合体在内存中存储的数据

#include <stdio.h>
union U
{
	char a;
	int b;
};

int main()
{
	union U u;
	u.b = 0x12345678;
	u.a = 0x99;
	return 0;
}

答案速查

VS2022按小端序存储

因此为99 65 43 21

分析

运行环境x86+debug

下断点(F9)至u.a = 0x99;,内存窗口输入&u

b9e13e41a08b461a9d4da5df5afd1d63.png

执行至return 0;

90a02df542a140eeac5840f939cea39a.png

5.相同成员的联合体和结构体的对比

union U
{
	char a;
	int b;
};

struct S
{
	char a;
	int b;
};

 

ac2dc47ab413436b94608d0967af1600.png025ef410d82543c893989cd7d66fa485.png

6.联合体的大小计算

2条规则

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

2.当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍(多数人往往会忽视第2点)

例如:

求下列代码的执行结果

#include <stdio.h>
union U
{
	char a[5];
	int b;
};

int main()
{
	printf("%zd", sizeof(union U));
	return 0;
}

 答案速查

8ed448d2452149db8085ca5330e76076.png

分析

如果不考虑第二点规则,答案应该是5

如果考虑第二点规则,

char a[5]; 自身对齐数:1,VS默认对齐数:8,所以对齐数为1

int b; 自身对齐数:4,VS默认对齐数:8,所以对齐数为4

a[5]与b的最大对齐数为4

所以联合体的大小至少为4的整数倍(4,8,12,...,4k),大于5且最近的4整数倍的数为8

练习

求下列代码的执行结果

#include <stdio.h>
union U
{
	short a[7];
	int b;
};

int main()
{
	printf("%zd", sizeof(union U));
	return 0;
}

答案速查

05214c9e024a433b9710d8eb6dc37303.png

分析

short a[7]; 自身对齐数:2,VS默认对齐数:8,所以对齐数为2

int b; 自身对齐数:4,VS默认对齐数:8,所以对齐数为4

如果不考虑第二点规则,答案应该是14(7*2=14)

如果考虑第二点规则,short a[7];与int b;的最大对齐数为4,所以联合体的大小至少为4的整数倍(4,8,12,...,4k),大于14且最近的4整数倍的数为16

7.联合体的优点

如果一些变量既有公共属性,又有各自的联合属性,可以把公共属性单独写出来,剩余属于各自本身的属性使用联合体起来(联合体内嵌结构体)

这样可以节省空间

8.匿名联合体

同匿名结构体,见文63.【C语言】再议结构体(上)

 

联合体(Union)是C语言中的一种特殊的数据结构,在同一个数据结构中,可以存放不同类型的变量,这使得联合体能够共享相同的内存空间。这种特性在处理动态数据类型、位操作等场景非常有用。 ### 内存分配原理 当声明一个联合体时,编译器会为其分配足够的内存以容纳其成员中所需的最大数据类型大小。这意味着,当你向联合体内存储不同类型的值时,并不会浪费额外的空间。例如: ```c union example { int i; char c; }; union example u; u.i = 42; // 使用int部分 printf("Integer value is %d\n", u.i); u.c = 'A'; // 使用char部分 printf("Character value is %c\n", u.c); ``` 在这个例子中,`union example`实际上只占用了一个整数所需的内存空间,无论是存储整型还是字符类型的数据。这是因为C编译器会计算出所有可能的成员所需的最大内存,并分配给整个联合体。 ### 访问联合体成员 访问联合体内的某个成员时,通常需要先指定你想查看的是哪一个成员。由于联合体成员共用同一段内存区域,因此直接通过指针进行访问也是可能的,但是需要注意内存边界的问题。 ### 相关问题: 1. **如何有效地利用联合体减少程序内存消耗?** - 在设计数据结构时考虑是否可以采用联合体,特别是当你需要存储几种不同类型的值但实际运行时只能使用其中一种类型时。 2. **联合体与其他数据结构(如结构体)相比有何优缺点?** - 优点:节省内存,对于同时需要几种不同类型数据的情况特别有效。 - 缺点:无法同时访问联合体的所有成员,如果尝试这样做可能导致未定义的行为。 3. **在哪些具体的编程应用场景中可以充分利用联合体的特点?** - 网络通信协议的解析、文件头信息的读取、设备驱动程序中硬件状态寄存器的访问等,这类场合往往需要快速切换多种数据类型的操作而不需要频繁地分配和释放内存资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值