结构体相关知识

简介: 结构体相关知识

一、结构体内存对齐



f08d0bbcb8b74670b565c5279f565d4d.png

(1) 如何计算?

首先得掌握结构体的对齐规则;

1、第一个成员在与结构体变量偏移量为0的地址处。

2、其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。                                                   对齐数=编译器默认的一个对齐数与该成员大小的较小值。

**vS中认的对齐数值为8


**Linux环境没有默认对齐数,其自身大小就是默认对齐数。

3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。                                     4、如果嵌套了结构体的情况,(嵌套的结构体对齐至的最大对齐数的整数倍处)结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。


(2)计算偏移量


size_t offsetof(structname,membername);


头文件#include<stddef.h>

d9f07b1a42604c1894ab5dc3d6e77c0c.png



**所以在我们设计结构体的时候,我们要既满足对齐,又要节省空间,我们应该


让占用空间小的成员尽量集中在一起。


(3)修改默认对齐数


#pragma pack(n)


n就是你要修改的默认对齐数。


二、位段


(1)位段的声明


1、位段的成员必须是int、unsigned、int或者 signed int 及char 。


2、位段的成员名后面有一个冒号和一个数字。


其中位段的空间是按照需要以四字节(int)或者一个字节(char)的方式来开辟的。


还有位段涉及很多不确定性因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。


例如:


ec8f8bcefef74dc39433ad8547a3dcd9.png

它可能是按下图来存放



4b135fa9380c4ea4b874a66c72dc8aa0.png

三、枚举enum


(1)枚举的值



225ce516524f4db2a276c8826220cf32.png

(2)枚举的优点


1、增加代码的可读性和可维护性。


2、和#define定义的标识符比较枚举有类型检查,更加严谨。


3、防止了命名污染(封装)。


4、便于调试。


5、使用方便,一次可以定义多个常量。


四、联合(共用体)


67f84e75cd1947258d37c9722e2cd150.png


其中c和i共用了一个字节,所以占了4个字节。


但c和i不可以一起使用,因为改变了c值,i的值也会跟着改变。


例如:


用这个来判断编译器的大小端


2d33e448b3394be69667aef7002c9544.png


1、计算联合体大小


1、联合的大小至少是最大成员的大小。


2、当最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍。


例如:char数组占五个字节大小,是最大成员,但其对齐数为1,使用要对齐,


所以所占内存为8个字节。



043756562cd14aee9e880c38f6ae56b0.png

五、柔性数组(结构体中的最后一个元素允许是未知大小的数组,这就叫柔性数组)


32bee38628ed4b1db2fe034dcf853000.png

f6749a645faf481eb9e3fa03a1b81243.png

(1)特点


1、结构中的柔性数组成员前面必须至少有一个其他成员。


2、sizeof返回的这种结构大小不包括柔性数组的内存。


3、包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的空间应该大于结构的大小,以适应柔性数组的预期大小。


如下图所示:



f04a0b0fc5464977a8df145df21f4201.png

(2)优点


1、方便内存释放。


2、可以加快访问速度。


目录
相关文章
|
6月前
|
存储 算法 C语言
c结构体
c结构体
33 1
|
6月前
|
存储 安全 编译器
一篇文章介绍结构体
一篇文章介绍结构体
51 1
|
6月前
|
算法 C语言
结构体相关知识
结构体相关知识
|
机器学习/深度学习 存储 编译器
Day_16 结构体
Day_16 结构体
|
编译器
|
编译器 C++
C#视频-结构体
C#视频-结构体
55 0
C—结构体
C语言学习第十四弹
|
存储 C++