结构体
结构体类型的创建
struct Student
{
char name[20];
short age;
char sex[5];
}stu1,stu2,stu3;
int main()
{
struct Student stu4;
return 0;
}
匿名结构体
匿名结构体
struct
{
char name[20];
short age;
char sex[5];
}stu1;
struct
{
char name[20];
short age;
char sex[5];
}*ps;
int main()
{
ps = &stu1;//这样是不合法的,虽然ps和stu1的内容一样,但他两的类型不同
}
结构体的自应用
struct Node
{
int data;//4
struct Node* next; //4 //链表的方法
};
int main()
{
struct Node n;
return 0;
}
typedef struct Node
{
int data;//4
struct Node* next; //4 不能省去struct
}Node;
int main()
{
struct Node n;
return 0;
}
结构体的内存对齐(特别重要)
#include<stddef.h>//offsetof的头文件
struct S1
{
char c1;
int i;
char c2;
};
//struct S2
//{
// char c1;
// char c2;
// int i;
//};
struct S3
{
double d;//8
char c;//1
int i;//4 最后算出结构体总大小为16
};
struct S4
{
char c1;//0
//1-7
struct S3 s3;//8-23 嵌套结构体到对齐到自己最大对齐数的整数倍处
double d;//24-31
};
int main()
{
printf("%d\n", sizeof(struct S3));//16
printf("%d\n", sizeof(struct S4));//32
//struct S1 s1 = { 0 };
//rintf("%d\n", offsetof(struct S2, c1));//0 offsetof代表 相对于起始位置的偏移量
//printf("%d\n", offsetof(struct S2, c2));//1
//printf("%d\n", offsetof(struct S2, i));//4
//struct S1 s1 = { 0 };
//struct S2 s2 = { 0 };
//printf("%d\n", sizeof(struct S1));//12 //两种打印方式都一样
//printf("%d\n", sizeof(s1));
//printf("%d\n", sizeof(struct S2));//8
//printf("%d\n", sizeof(s2));
system("pause");
return 0;
}
结构体内存对齐的规则 要牢牢掌握
1.第一个成员永远都放在结构体起始位置的0偏移处
2.从第二个成员开始,每个成员都放在某个对齐数的整数倍的偏移处
这个对齐数:成员自身的大小和默认对齐数的较小值
默认对齐数:
VS环境下:8 Linux gcc:4
3.结构体的总大小必须是所有成员对齐数中最大对齐数的整数倍
4.如果结构体中嵌套结构体,
嵌套结构体要对齐到自身最大对齐数的整数倍,
结构体的总大小是所有对齐数(包含嵌套结构的对齐数)中最大对齐数的整数倍
对其原因:提高效率
节省空间的方法:把小的放在一起
修改默认对齐数
#pragma pack(4)//将默认对齐数改为4
struct S
{
double d;//0-7
char c;//8
};
#pragma pack()//没写数字代表修改取消
int main()
{
printf("%d\n", sizeof(struct S));//12
return 0;
}
//#pragma pack(1) 代表没有对齐,0偏移量
结构体传参(传地址)(传结构体)