当前位置: 首页 > article >正文

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

目录

1. 联合体类型的声明

2. 联合体的特点

3.1 成员变量共用一块内存

3.2 由于共用内存导致的相关性

4. 结构体与联合体对比

5. 联合体大小的计算

6. 联合体的应用

6.1 多类型特定属性组结构体

6.1.1 设计方案1:采用纯结构体

6.1.2 设计方案2:结构体+联合体

6.2 判断大小端

6.2.1 方法1:使用指针类型的解引用权限原理

6.2.2 方法2:使用联合体的共用内存原理


1. 联合体类型的声明

#define	_CRT_SECURE_NO_WARNINGS
#include<stdio.h>
union Un {
	char c;
	int i;
};
int main() {
	union Un u = { 0 };
	printf("%d\n", sizeof(u));
	return 0;
}

2. 联合体的特点

1、联合体与结构体类似,联合体也是由一个或多个成员构成,这些成员可以是不同类型。

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

3、联合体的特点:所有成员共用一块内存空间。故联合体也称共同体;

3. 联合体的内存分配

3.1 成员变量共用一块内存

#define	_CRT_SECURE_NO_WARNINGS
#include<stdio.h>
union Un {
	char c;
	int i;
};
int main() {
	union Un u = { 0 };
	printf("%d\n", sizeof(u));
	printf("&u   = %p\n", &u);
	printf("&u.c = %p\n", &u.c);
	printf("&u.i = %p\n", &u.i);
	return 0;
}

运行结果及内存分配如下: 

3.2 由于共用内存导致的相关性

#define	_CRT_SECURE_NO_WARNINGS
#include<stdio.h>
union Un {
	char c;
	int i;
};
int main() {
	union Un u = { 0 };
	u.i = 0x11223344;
	u.c = 0x55;
	printf("%x\n", u.i);
	return 0;
}

单步调试,查看内存实际存储: 

4. 结构体与联合体对比

1、关于定义与关键字等:

结构体联合体
关键字structunion
成员多个不同类型成员多个不同类型成员
内存分配每个成员都有自己独立的空间所有成员共用同一块内存空间

2、关于内存分配:

5. 联合体大小的计算

1、联合体的大小至少是最大成员的大小;

2、当最大成员大小不是最大对齐数的整数倍时,联合体的大小须对齐到最大对齐数的整数倍

union Un1
{
 char c[5];
 int i;
};
union Un2
{
 short c[7];
 int i;
};
int main()
{
 printf("%d\n", sizeof(union Un1));
 printf("%d\n", sizeof(union Un2));
 return 0;
}

运行结果如下:

分析如下:

(1)对于联合体union Un1而言:

数组c有5个char类型的元素,共占5个字节;整型变量i占4个字节;

最大对齐数 = max { sizeof ( char ) , sizeof ( int ) } = max {1, 4 } = 4;

union Un1大小至少为5,且须为4的整数倍,故大小为8;

(2)对于联合体union Un2而言:

数组c有7个short类型的元素,共占14个字节;整型变量i占4个字节;

最大对齐数 = max { sizeof ( short ),sizeof ( int ) } = max { 2, 4 } = 4;

union Un2大小至少为14,且须为4的整数倍,故大小为16;

6. 联合体的应用

6.1 多类型特定属性组结构体

假设当前有图书、杯子、衬衫三种商品,对于每种商品都有库存量、价格、商品类型属性;

不同商品类型,也会有其他特定信息:

图书还需书名、作者、页数属性;杯子还需设计属性;衬衫还需设计、颜色、尺寸属性;

6.1.1 设计方案1:采用纯结构体

struct goods
{
 //公共属性
 int stock;     //库存量
 double price;  //定价
 int type;      //商品类型
 
 //特殊属性
 char title[20];    //书名
 char author[20];   //作者
 int pages;     //⻚数
 
 char design[30];   //设计
 char colors[20];        //颜⾊
 int sizes;         //尺⼨
};

若采用纯结构体作为商品的自定义类型,则由于特殊属性的存在须在结构体内包含所有商品所需的所有属性,造成一定空间浪费;

6.1.2 设计方案2:结构体+联合体

对于每一个商品,它只属于一种商品类型,故而一种商品只会有一组特殊属性;

采用以下设计思路:

先列出公共属性,将各商品的特殊属性设计为结构体,再作为联合体的成员变量

struct goods
{
	int stock;		//库存量
	double price;   //定价
	int type;		//商品类型

	union Un {
		struct Book
		{
			char title[20];	  //书名
			char author[20];  //作者
			int pages;        //⻚数
		}book;
		struct Mug
		{
			char design[30];  //设计
		}mug;
		struct Shirt
		{
			char design[30];  //设计
			char colors[20];  //颜⾊
			int sizes;		  //尺⼨
		}shirt;
	}item;
};

6.2 判断大小端

6.2.1 方法1:使用指针类型的解引用权限原理

#define	_CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int check_sys_bypointer() {
	int n = 1;  // 0x00 00 00 01H
	return *(char*)&n; // 低地址存低字节数据->小端
}
int main() {
	// 小端返回1,大端返回0
	int ret = check_sys_bypointer();
	if (ret == 1)
		printf("小端\n");
	else
		printf("大端\n");
	return 0;
}

运行结果如下:

6.2.2 方法2:使用联合体的共用内存原理

#define	_CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int check_sys_byunion() {
	union U {
		char c;
		int i;
	}u;
	u.i = 1;     // 0x00 00 00 01H
	return u.c;  // 返回4字节中的第1个字节(返回低地址处的值)
}
int main() {
	// 小端返回1,大端返回0
	int ret = check_sys_byunion();
	if (ret == 1)
		printf("小端\n");
	else
		printf("大端\n");
	return 0;
}

运行结果如下:


http://www.kler.cn/a/510695.html

相关文章:

  • Netty的相关组件之间的关系
  • Dockerfile -> Docker image -> Docker container
  • [EAI-018] π0: A Vision-Language-Action Flow Model for General Robot Control
  • Hadoop•用Web UI查看Hadoop状态词频统计
  • 第22篇 基于ARM A9处理器用汇编语言实现中断<四>
  • 21天学通C++——11多态(引入多态的目的)
  • 国产编辑器EverEdit -重复行
  • 第4章:Python TDD消除重复与降低依赖实践
  • 深度学习python基础(第一节) 变量和数据类型
  • 设计微服务的过程
  • 从Cursor到Replit Agent:AI编程技术全面综述
  • 【Python】endote参考文献格式获取,从PubMed
  • Next.js 实战 (八):使用 Lodash 打包构建产生的“坑”?
  • 【NLP高频面题】LSTM的前向计算如何进行加速?
  • 遥感应用论文精选
  • C++ 面向对象(继承)
  • 机器学习皮马印第安人糖尿病数据集预测报告
  • C#,入门教程(03)——Visual Studio 2022编写彩色Hello World与动画效果
  • # 爬楼梯问题:常见数列的解法总结
  • 冬季深圳小览
  • Pytorch深度学习指南 卷I --编程基础(A Beginner‘s Guide) 第0章
  • “深入浅出”系列之C++:(6)CMake构建项目
  • 蓝桥杯3525 公因数匹配 | 枚举+数学
  • DDD - 如何设计支持快速交付的DDD技术中台
  • 软工:第一部分(初识软工)
  • “深入浅出”系列之数通篇:(5)TCP的三次握手和四次挥手