struct结构体的使用及内存分配规则,和union联合体的简单说明

struct结构体的使用

和数组一样,struct可以保存多个成员数据,不同的是数组都是相同类型的数据,而struct可以保存不同类型的成员数据

用法:

struct Node {
    int i;
    char arr[3];
};

struct Node abc;

结构体变量也可以写在结构体构造时的末尾:

struct Node {
    int i;
    char arr[3];
}abc;

同样,也可以使用typedef对结构体进行重命名(下面代码意思就是将struct Node重命名为stu,创建结构体变量时就可以直接stu abc了):

typedef struct Node {
    int i;
    char arr[3];
}stu;

还有一种偏僻的写法叫做匿名结构体,就是不写结构体名,直接在结尾创建结构体变量,但是这样写的话后面就不能再创建该结构体的变量使用:

struct {
    int i;
    char arr[3];
}stu;

struct的内存对齐

首先看看上面创建的结构体变量的大小,int i+char arr[3]直接计算的话应该是7个字节大小,那么在结构体中也是这样吗

可以看到,结果为8,造成这种结果的原因就要谈到结构体的内存对齐规则了,首先有一个偏移量的概念,偏移量就是指离结构体起始内存位置的字节数,1、结构体的首个成员永远位于偏移量为0的位置,下面再创建比较复杂的结构体,使用offsetof宏函数观察每个成员的偏移量,该宏的头文件为stddef.h

通过运行结果和图可以清楚看到,char j到int i一共有4个字节大小,中间空了3字节的空间,这就是结构体内存对齐的第二条规则:2、从第二个成员开始,每个成员都要对齐到对齐数整数倍的位置。对齐数:默认对齐数和自身大小的较小值,vs对齐数为8。int i的对齐数就为4,char j已经占了一个字节,所以i就需要到偏移量为4的位置对齐

我们还可以看到,sizeof该结构体变量为24,图上为4+4+8+3=19,这就是第三条规则:3、结构体整体的大小为结构体成员最大对齐数的整数倍,而上图的结构体成员最大对齐数为double k的8,19补全即为24

还有一种情况就是:4、结构体内嵌套另一个结构体,这个时候嵌套的结构体对齐数为自身的最大对齐数,对齐后往后补全所占内存,最后对齐结构体和嵌套的结构体中最大对齐数的整数倍

因此,我们在设计结构体时,应该将较小的结构体成员放在一起,这样就能防止内存对齐时浪费太多空间(修改默认对齐数#pragma pack(num),num就为修改的默认对齐数)

位段

位段即为struct成员变量指定可以使用的内存大小,大小为bit:

struct num {
    char i : 3;
    char j : 1;
    int k : 11;
};

后面给了冒号+值的都是位段,如果申请的一个内存块能放得下两个指定内存的成员变量,就会放在同一个内存块,但是如果放不下,那么该内存块剩余部分是否使用还是直接重新分配,标准比较模糊,这里不做深入探讨

union联合体

可以看到联合体union Nu num的大小为8个字节,并且联合体和所有成员都指向同一个地址,也就是说所有成员都是公用同一块空间的,所以联合体也叫共用体。当然,共用体一次也只能使用一个,否则同一个地址会产生影响,因此我们可以判断union联合体的大小就为最大的那个成员大小

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值