自定义类型包括:结构体,联合体,枚举
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
例如形容一个学生
struct stu
{
char name[20];
int age;
}s1,s2;
结构体标签如果省略,就变成匿名结构体,只能使用一次
struct
{
char name[20];
int age;
}s1;
结构体的自引用
struct Node
{
int data;
struct Node* next;
};
结构体初始化
struct score
{
int n;
char ch;
};
struct stu
{
char name[20];
int age;
struct score s;
};
int main()
{
struct stu s1 = { "zhangsan",20,{10,'d'} };
printf("%s %d %d %c\n", s1.name, s1.age, s1.s.n, s1.s.ch);
return 0;
}
结构体内存对齐规则
1.第一个成员在与结构体变量偏移量为0的地址处
2.其他成员变量要对齐到某个数(对齐数)的整数倍地址处。
对齐数=编译器默认对齐数与该成员大小的较小值. VS编译器默认为8
3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
结构体传参,要传结构体的地址。
位段的声明和结构体类似,有两个不同:
1.位段的成员必须是int ,unsigned int 或signed int
2.位段的成员名后边有一个冒号和数字。
枚举
枚举顾名思义就是可以一一列举
默认情况下,枚举的第一个元素从零开始
但是可以更改
enum Day
{
Mon=1,
Tue,
Wen,
Thr,
Fri,
Sat,
Sun
};
int main()
{
printf("%d\n", Mon);//1
printf("%d\n", Tue);//2
printf("%d\n", Wen);//3
printf("%d\n", Thr);//4
printf("%d\n", Fri);//5
printf("%d\n", Sat);//6
printf("%d\n", Sun);//7
}
联合(共用体)
联合的成员是共用同一块内存空间的,这样一个联合体变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)
联合体也存在对齐
union Un
{
char arr[5];
int i;
}u;
int main()
{
printf("%d\n", sizeof(u));//8
return 0;
}