自学内容网 自学内容网

【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;
}

运行结果如下:


原文地址:https://blog.csdn.net/m0_63299495/article/details/145240169

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!