结构体
特殊的结构体
//匿名结构体
struct
{
int a;
char b;
double c;
}x; //这里定义了几个,就只能用几个了,没名字,没法定义
结构体自引用
struct Node
{
int date;
struct Node next; //这里不行,你不能知到Node到底多大
};
//正确的自引用
struct Node
{
int date;
struct Node* next; //地址的大小就是4或8字节,是固定的
};
结构体内存对齐
struct S1
{
char c1;
int i;
char c2;
};
int main()
{
struct S1 s1 = { 0 };
printf("%d\n", sizeof(s1));//这里输出什么
return 0;
}
为什么是12呢,?这里这就是结构体对齐了
1.第一个成员在与结构体变量偏移量为0的地址处
2.其他成员变量要对齐到对齐数的整数倍处
对齐数:编译器默认的对齐数与该成员大小的较小值,每个变量都有对齐数(int一般为4,double为8,char为1,在和默认的对齐数比,取最小的)
VS中默认对齐数为8
Linux无默认对齐数(所以对齐数就是该成员的大小)
3.结构体的总大小为最大对齐数(每个成员的对齐数相比,取最大)的整数倍
4,结构体嵌套时,嵌套的结构体对齐到自己最大对齐数的整数倍处,结构体的整体大小还是所有变量的最大对齐数的整数倍(包括嵌套结构体里的变量)。
举例
为什么存在内存对齐?
大部分的参考资料都是如是说的:
1. 平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址
处取某些特定类型的数据,否则抛出硬件异常。
2. 性能原因:
数据结构
(
尤其是栈
)
应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器
需要作两次内存访问;而对齐的内存访问仅需要一次访问。
总体来说:
结构体的内存对齐是拿
空间
来换取
时间
的做法
结构体默认对齐数修改
#pragma pack(4) //设置默认对齐数
struct test
{
char c;
int i;
};
#pragma pack() //恢复默认对齐数
位段
//这就是位段的一种
struct A
{
int a : 5;//中间的是 :
int b : 8;
int c : 10;
int d : 20;
};
printf("%d\n", sizeof(a)); //输出8
那么为什么输出8,:后面的数字又是什么?
什么是位段
1.位段的成员必须是整形家族(char, int, unsigned int)
2. 由冒号加数字组成
位段的内存分配
....................知识欠缺
枚举
。。。。。。知识欠缺