CSDN的各位友友们你们好,今天千泽为大家带来的是
自定义类型-结构体的知识详解,
接下来一起走进结构体的世界吧!
如果对您有帮助的话希望能够得到您的支持和关注,我会持续更新的!
👉 一起进入今天的学习内容吧!!!👈
💎一.结构体基础知识
1.结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
结构体,联合体,枚举以及数组都是自定义类型;
2.结构体的自引用
struct Node
{
int data;
struct Node* next;
};
3.结构体的特殊声明
匿名结构体类型
struct
{
int a;
char b;
float c;
}x;
struct
{
int a;
char b;
float c;
}a[20], *p;
🚩二.结构体内存对齐
⛳重点来喽!!!
结构体内存对齐基本概念
(1)结构体内部地址的偏移量:结构体内部某个地址的偏移量指的是结构体内存空间中某个字节的地址与结构体首地址的差值(以字节为单位)(结构体的内存中存储结构是从低地址向高地址排列的,与数组相同)。
(2)对齐数:结构体的每个成员都有自己的对齐数。
结构成员对齐数 = 编译器默认的一个对齐数 与 该成员大小(单位为字节)的较小值。
注意确认成员对齐数时,数组成员要视为多个内置类型成员来看待,不能将数组成员看做一个整体。比如char a[3]作为某个类型的结构体的成员,那么确认成员对齐数时要将其看成3个char类型的变量而不能将其看成一个整体。
结构体内存对齐规则
结构体成员的内存对齐规则:
1.结构体第一个成员的地址的偏移量为0。(即第一个成员存储在结构体首地址处)
2.其他成员变量的地址的偏移量必须为该成员的对齐数的整数倍。
3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍
基于以上规则,就可以计算一个结构体所占内存大小。
更多例子
嵌套结构体的内存计算
如果有嵌套结构体的情况,那么作为另外一个结构体的成员的结构体,其对齐数为自身内部成员的对齐数中的最大对齐数。
结构体的整体大小就是所有成员的对齐数中的最大对齐数(含嵌套结构体的对齐数)的整数倍。
结构体内存对齐的意义
1. 平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处(比如在偏移量为某对齐数的整数倍的地址处)取某些特定类型的数据,否则抛出硬件异常。
2. 性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
结构体的内存对齐是拿空间来换取时间的做法。是C语言的一种用于提高程序性能的内存管理机制。
🚩三.位段
一.位段概念介绍
1.位段的成员必须是 int、unsigned int 或signed int (或者其他整形家族的数据)。
2.位段的成员名后边有一个冒号和一个数字。
struct A
{
int _a:2;
int _b:5;
int _c:10;
int _d:30;
};
二.位段的内存分配
为位段成员开辟内存空间时,是根据成员的类型一段一段空间去开辟的,比如上面的struct A, _a成员为int类型,该位段开辟内存时会先向系统申请4个字节(32bit)的空间,将_a,_b,_c都存入这四个字节的空间中,由于这4个字节无法再存下_d,所以需要再申请4个字节来存放30bit的成员 _d.
struct S
{
char a:3;
char b:4;
char c:5;
char d:4;
};
int main ()
{
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
return 0;
}
三.位段存在的跨平台问题
不同的操作系统中,位段的实现会有差异:
1. int 位段被当成有符号数还是无符号数是不确定的。
2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题.)
3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的.
所以跨平台程序一般不使用位段。