- 1、结构体
- 1.1、结构体声明
- 1.2、结构体自引用
- 1.3、结构体变量的定义和初始化
- 1.4、结构体内存对齐(重点)
- 1.5、结构体传参
- 小知识
特殊情况:
如果声明时忽略了结构体的名称,就是匿名结构体(最好不对结构体匿名)
结构体自引用的正确方式
struct Node
{
int data;
struct Node* next;
};
int main()
{
return 0;
}
1.3、结构体变量的定义和初始化
各种类型的结构体初始化方法
#include1.4、结构体内存对齐(重点)typedef struct Node { int data; struct Node* next; }Node; struct stu { char name[20]; char sex[5]; int age; int height; }s2,s3,s4;//变量列表(s2,s3,s4是全局结构体变量) struct Data//结构体内嵌套结构体 { struct stu s; char ch; double; }; int main() { struct Node n2 = { 100,NULL };//用大括号初始化 struct stu s1 = { "zhangsan","nan",20,180 }; struct Data d = { {"lisi","nv",30,166},'w',3.14 }; //嵌套结构体如何初始化 return 0; }
1、结构体的第一个成员,存放在结构体变量开始位置的0偏移处
2、从第二个成员开始,都要对齐到对齐数的整数倍地址处
3、VS环节下默认对齐数为8,成员自身大小和默认对齐数的较小值,就是对齐数
4、结构体的总大小必须是最大对齐数的整数倍
5、最大对齐数是指所有成员的对齐数中最大的那个
6、如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍
7、我们可以通过#pragma pack 来改变结构体内存默认对齐数
#pragma pack (1)//默认对齐数修改为4,改为 1 即为没对齐,一般修改为2,4,6……
struct S
{
double d;
char c;
};
#pragma pack()
PS:Linux环境中没有默认对齐数,对齐数就是成员自身大小
1.5、结构体传参1、结构体传参有两种方式,第一种是传值,另一种是传地址
2、传值会造成大量的内存空间浪费,所以一般选择传地址
小知识1、typedef是C语言中的关键字,其作用是为一种数据类型定义一个新的名字
2、为什么会存在结构体内存对齐
性能原因:为了访问未对齐的内存,处理器需要做两次内存访问,而对齐的内存访问仅需要一次访问,所以结构体内存对齐是拿空间来换取时间的做法,所以我们在设计结构体的时候,我们既要满足对齐,又要节省空间,就需要让占用空间小的成员尽量聚集在一起
3、ofsetof()是一个宏,返回的是结构体成员在内存中的偏移量
#include#include struct S { char c1; int a; char c2; }; int main() { //offsetof()返回 结构体成员 在内存中的偏移量 printf("%dn", offsetof(struct S, c1));//0 printf("%dn", offsetof(struct S, a));//4 printf("%dn", offsetof(struct S, c2));//8 return 0; }



