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

news/2025/1/20 17:53:38/

目录

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 01Hreturn *(char*)&n; // 低地址存低字节数据->小端
}
int main() {// 小端返回1,大端返回0int ret = check_sys_bypointer();if (ret == 1)printf("小端\n");elseprintf("大端\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 01Hreturn u.c;  // 返回4字节中的第1个字节(返回低地址处的值)
}
int main() {// 小端返回1,大端返回0int ret = check_sys_byunion();if (ret == 1)printf("小端\n");elseprintf("大端\n");return 0;
}

运行结果如下:


http://www.ppmy.cn/news/1564716.html

相关文章

2025寒假备战蓝桥杯01---朴素二分查找的学习

文章目录 1.暴力方法的引入2.暴力解法的思考 与改进3.朴素二分查找的引入4.朴素二分查找的流程5.朴素二分查找的细节6.朴素二分查找的题目 1.暴力方法的引入 对于下面的这个有序的数据元素的组合&#xff0c;我们的暴力解法就是挨个进行遍历操作&#xff0c;一直找到和我们的这…

PHP版接口调试工具(自定义GET|POST|COOKIE|HEADER|User Agent|来路Referer)

<?php // 如果是OPTIONS请求&#xff0c;直接返回 if ($_GET[act] ! ) { header(Content-Type: application/json); // 允许跨域请求 header(Access-Control-Allow-Origin: *); header(Access-Control-Allow-Methods: GET, POST, OPTIONS); header(Access-Control-Allow-He…

SQL Server查询计划操作符——查询计划相关操作符(4)

7.3. 查询计划相关操作符 28)Declare:该操作符在查询计划中分配一个本地变量。该操作符是一个语言元素。该操作符具体如图7.2-28所示。 图 7.2-28 查询计划操作符Declare示例 29)Delete:该操作符从一个对象中删除满足其参数列中可选谓词的数据行。该操作符具体如图7.2-29…

SQL ON与WHERE区别

在 MySQL 中&#xff0c;ON 和 WHERE 都用于过滤数据&#xff0c;但它们的使用场景和作用有所不同&#xff0c;尤其是在涉及 JOIN 操作时。下面通过具体的例子来说明它们的区别。 1. ON 的作用 ON 用于指定表之间的连接条件&#xff0c;决定哪些行应该被连接在一起。它在 JOI…

【js进阶】设计模式之单例模式的几种声明方式

单例模式&#xff0c;简言之就是一个类无论实例化多少次&#xff0c;最终都是同一个对象 原生js的几个辅助方式的实现 手写forEch,map,filter Array.prototype.MyForEach function (callback) {for (let i 0; i < this.length; i) {callback(this[i], i, this);} };con…

【24】Word:小郑-准考证❗

目录 题目 准考证.docx 邮件合并-指定考生生成准考证 Word.docx 表格内容居中表格整体相较于页面居中 考试时一定要做一问保存一问❗ 题目 准考证.docx 插入→表格→将文本转换成表格→✔制表符→确定选中第一列→单击右键→在第一列的右侧插入列→布局→合并单元格&#…

考研数据结构线性表之顺序表

第二章线性表 1.1线性表的定义和基本操作 定义&#xff1a;线性表时具有\textcolor{blue}{相同数据类型}的n&#xff08;n≥0&#xff09;个数据元素的\textcolor{blue}{有限序列}&#xff0c;其中n为表长&#xff0c;当n0时线性表是一个空表。若用L命名线性表&#xff0c;则其…

CC工具箱使用指南:【Excel点集转面要素(批量)】

一、简介 群友定制工具。 此工具的功能是将一系列Excel文件转成面要素。 假设文件夹下有许多Excel文件&#xff1a; Excel文件长这样&#xff1a; 工具取x,y列&#xff0c;转成点集并生成面要素&#xff0c;同时将Excel文件名作为一个字段保存下来。 二、工具参数介绍 点击…