联合体结构体嵌套

结构体联合体基础

下文转载博主为:关于结构体和联合体大小的计算_结构体和联合体字节计算_Monitor0913的博客-优快云博客

一 .结构体

1:当没有定义 #pragma pack(value) 这种指定 value 字节进行对齐时,
它的计算规则是:整体的大小在满足为最大数据类型所占字节的倍数下要达到所占内存最小。
举例如下:
typedef struct
{
char a[5];
int b;
double c;
}Test;
没有指定字节对齐。在结构体成员中,a占5个字节,b占4个字节,c占8个字节。5+4+8=17.但是17不是 8的倍数,所以(5+3)+(4+4)+8=24.故占24个字节。

2:当定义了 #pragma pack(value),以 value字节进行对齐时,它的计算规则如下:
整体的大小必须为 value 的最小整数倍。举例如下:
#pragma pack(4)
typedef struct
{
char a[5];
int b;
double c;
}Test;
指定4字节对齐,所以(5+3)+4+8=20。故占20个字节。
#pragma pack(2)
typedef struct
{
char a[5];
int b;
double c;
}Test;
如果指定2字节对齐,那么就是(5+1)+4+8=18个字节。

二 .联合体

同样也分为两种情况:
1:当没有定义 #pragma pack(value) 这种指定 value 字节进行对齐时,它的计算规则是:
联合体中最大成员所占内存的大小且必须为最大类型所占字节的最小倍数。举例如下:
union
{
char a[7];
int b[2];
double c;
}Test;
成员a 占7字节,成员b 占 4*2=8 字节,成员c 占8字节,
最大类型字节数8,根据计算规则,该联合体的大小为 8字节。
union
{
char a[7];
int b[3];
double c;
}Test;
a占7字节,b占12字节,c占8字节。那么此联合体大小为16字节。
2:当定义了 #pragma pack(value),以 value字节进行对齐时,它的计算规则如下:
联合体中最大成员所占字节且必须为value的最小倍数。举例如下
#pragma pack(2)
union
{
char a[7];
int b[3];
double c;
}Test;
如果定义以2字节对齐,a占7字节,b占12字节,c占8字节,那么此联合体大小为12字节。

三.结构体嵌合联合体计算大小

1:当没有定义 #pragma pack(value) 这种指定 value 字节进行对齐时,它的计算规则是:
联合体按照最大成员所占字节且为最大数据类型所对应的字节的最小整数倍的原则进行计算,
它所占的字节数与结构体中其他成员所占字节的总和应为结构体中最大数据类型所对应的字节的最小倍数。

typedef struct
{
union
{
char a[10];
int b[2];
double c;
}test;
char d[5];
int e;
double f;
}Test;
联合体中a占10字节,b占8字节,c占8字节。此联合体大小为16字节,
那么结构体中 d占5字节,e占4字节,f占8字节。16+(5+3)+(4+4)+8=40.所以占40个字节。

2:当定义了 #pragma pack(value),以 value字节进行对齐时,它的计算规则如下:
联合体中最大成员所占字节且为value的最小整数倍,它所占的字节数与结构体其他成员所占字节数的总和为value的最小整数倍。
举例如下:
#pragma pack(2)
typedef struct
{
union
{
char a[10];
int b[2];
double c;
}test;
char d[5];
int e;
double f;
}Test;
联合体中a占10字节,b占8字节,c占8字节。10满足是2的最小倍数,此联合体大小为10字节。
此结构体大小为10+(5+1)+4+8=28字节。

开发代码实战

typedef union
	{
		Data[6];
		struct
			{
				unsigned char K;//1 byte
				unsigned char OverV:1;//1/8占一个字节里的第1bit
				unsigned char UnderV:1;
				unsigned char Respon_Err:1;
				unsigned char reserve1:5;//5/8
				unsigned char reserve2[4];
			}B;
	}X;			

(1)该联合结构体大小为:6 //Data[6]大小为0~5=>6
(2)​Data[0]​=K Data[2]=reserve2[1]
(3)在这里插入图片描述

### C语言联合体结构体嵌套的使用示例及注意事项 #### 1. 联合体结构体嵌套的基础概念 在C语言中,联合体(`union`)和结构体(`struct`)可以通过相互嵌套的方式实现更灵活的数据管理功能。这种设计使得程序能够根据不同需求动态调整数据存储模式[^4]。 #### 2. 结构体嵌套联合体 当在一个结构体内嵌入联合体时,通常是为了节省内存空间并提供多种可能的数据形式。以下是具体示例: ```c // 定义一个包含联合体结构体 struct Variant { int type; // 用于标识当前存储的数据类型 union { int i; float f; char c; } value; }; int main() { struct Variant var; // 设置为整数类型 var.type = 0; // 假设0表示int var.value.i = 10; // 修改为浮点数类型 var.type = 1; // 假设1表示float var.value.f = 3.14f; return 0; } ``` 此代码展示了如何通过改变 `type` 字段来控制联合体内部的实际有效字段。 #### 3. 联合体嵌套结构体 如果将结构体嵌入到联合体中,则可以在同一块内存区域中切换不同的复杂数据布局。以下是一个例子: ```c // 定义一个包含两个结构体联合体 union Data { struct { int x; int y; } point; struct { float radius; float area; } circle; }; int main() { union Data data; // 初始化为点坐标 data.point.x = 10; data.point.y = 20; // 切换为圆属性 (注意此时point的内容会被覆盖) data.circle.radius = 5.0f; data.circle.area = 78.5f; return 0; } ``` 这里需要注意的是,在修改其中一个成员之前应清楚其影响范围以及潜在的风险——即其他成员可能会被破坏或重写。 #### 4. 复杂嵌套场景下的应用案例 对于更加复杂的业务逻辑,可以进一步扩展嵌套层次以满足特定需求。例如员工薪资管理系统可采用如下模型: ```c #include <string.h> struct Employee { char name[50]; int id; union { struct { float hourly_wage; int hours_worked; } hourly; struct { float annual_salary; float bonus; } salaried; } payment; int is_hourly; // 标志位,0表示年薪制(salaried),1表示小时工(hourly) }; int main() { struct Employee emp1; // 配置为小时工 strcpy(emp1.name, "John Doe"); emp1.id = 1001; emp1.is_hourly = 1; emp1.payment.hourly.hourly_wage = 15.50; emp1.payment.hourly.hours_worked = 40; return 0; } ``` 这段代码清晰地体现了如何利用标志位区分不同类型的工作性质,并分别设置对应的工资参数[^4]。 #### 5. 注意事项 - **共享内存风险**:由于联合体会让多个成员共用一块物理地址,因此操作某个成员前需确认不会干扰其它部分。 - **初始化顺序**:建议先完成整个对象的整体初始化再单独赋值各子组件。 - **编译器差异**:某些高级特性可能存在跨平台兼容性问题,请查阅目标环境文档验证支持情况。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值