struct结构体大小的计算及将char *数组赋值给struct类型

本文探讨了C语言中struct结构体大小的计算,涉及到字节对齐的原则,例如一个包含无符号64位整型和另一个结构体的struct,其实际大小可能大于成员变量简单累加的大小。同时,文章介绍了如何将char *数组赋值给struct类型,并指出在计算结构体大小时应使用sizeof(结构体名称)。

1.struct结构体大小的计算
我已自己的代码为例:

typedef unsigned char		__u8;
typedef unsigned short		__u16;
typedef unsigned int		__u32;
typedef unsigned __int64 __u64;
typedef __u8	f8_u8;
typedef __u16 f8_u16;
typedef __u32 f8_u32;
typedef __u64 f8_u64;
typedef __u64 f8_uuid;

struct mem_addr_t {
	f8_u16	addr;
	f8_u8	section;
	f8_u8	padding_0;
}PACKED;

struct var_def_t {
	f8_uuid uuid;//f8_vm
	struct mem_addr_t addr;//f8_binary
};

现在我们要计算var_def_t结构体的大小:此结构体包含两个成员变量uuid(无符号64位整型,占8个字节)和 addr(mem_addr_t结构体类型)。
那下面问题又来了,mem_addr_t结构体类型占多大空间呢:

struct mem_addr_t {
	f8_u16	addr;      //无符号短整型,占两个字节
	f8_u8	section;   //无符号char型,占一个字节
	f8_u8	padding_0; //无符号char型,占一个字节
}PACKED;

由上可知,mem_addr_t类型占四个字节(注意这不是简单的累加),我们通过sizeof(mem_addr_t)得到的字节数也同样为4。
这会我们在反过头来计算看var_def_t结构体的大小:

struct var_def_t {
	f8_uuid uuid;               //f8_vm  无符号64位整型,占8个字节
	struct mem_addr_t addr;     //f8_binary  刚才上面已经说到,占4个字节大小
};

如果按累加的计算方式的话,var_def_t应该是占12个字节的大小,但是我们用sizeof(var_def_t)得到的字节大小是16个字节。这是因为计算struct字节大小的时候要字节对齐,在计算大小的时候,addr要补上四个字节,所以一共占16个字节。
2.将char *数组赋值给struct类型
此处还是以自己的代码为例:

char BinaryAddress[64];
var_def_t * def;
for(int i = 0; i < 64; i++)
{
	BinaryAddress[i] = '\0';
}
BinaryAddress[0] = '?';            //转换为16进制为0x3f
BinaryAddress[1] = '?';            //转换为16进制为0x3f  
BinaryAddress[2] = '\x10';         //转换为16进制为0x10
BinaryAddress[3] = '[';            //转换为16进制为0x5b
BinaryAddress[4] = '}';            //转换为16进制为0x7d
BinaryAddress[5] = '?';            //转换为16进制为0x3f
BinaryAddress[6] = '\f';           //转换为16进制为0x0c
BinaryAddress[7] = '?';            //转换为16进制为0x3f
BinaryAddress[8] = '\f';           //转换为16进制为0x0c
BinaryAddress[9] = '\0';           //转换为16进制为0x3f
BinaryAddress[10] = '\x2';         //转换为16进制为0x3f

def = (var_def_t*)BinaryAddress;   

BinaryAddress是64字节char型数组,为了测试,代码中我对前11个字节进行了赋值。def是一个var_def_t类型的指针,指向了BinaryAddress的首地址,在前面我们已经算过了,var_def_t占用地址空间为16字节,所以计算机会将BinaryAddress的前16个字节赋值给var_def_t类型。

f8_uuid m_64 = def->uuid;	              //uuid类型占8个字节,m_64 = 0x3f0c3f7d5b103f3f
f8_u16	m_addr= def->addr.addr;           //addr.addr无符号短整型,占两个字节 def->addr.section = 0x02 '\x2'
f8_u8	m_section=def->addr.section;      //def->addr.section = 0x02 '\x2'
f8_u8	m_padding_0=def->addr.padding_0;  //def->addr.padding_0 = 0x00 '\0'

我在调式的过程中还犯过一个错误,为了看def所占的字节大小,我用了sizeof(def),我以为得到的是struct var_def_t类型的大小,其实不是:

int n_def = sizeof(def);   
//def是一个指针类型,与指向什么无关,表示的是寻址能力
//在x86平台下,指针类型占4个字节,在x64平台下,指针类型占8个字节

想看结构体大小用sizeof(结构体名称就可以)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值