结构体、联合体、枚举
结构体:
struct Student
{
char name[32];
int age;
int sex;
char add[32];
};
上面只是一种数据类型(同int、char基本类型一样),表示是一个结构体,不占用地址空间,只有在定义结构体变量时才分配空间,即struct Student stu1;stu1才占有地址空间。
结构体大小的计算:
规则:
1. 结构体成员变量的偏移量为该成员变量大小的整数倍。(第一个成员变量的偏移量为0,0是任何数的整数倍;结构体成员变量的偏移量不是数组和内套结构体整数倍)
2. 结构体的大小必须是所有成员变量大小的整数倍(数组和内套结构体除外)
struct Test1{ // 当前偏移量 成员变量大小 所占大小
char a; // 0 1 1
char b; // 1 1 2
char c; // 2 1 3
int tmp; // 3 4 8 //当前偏移量3不是该成员变量大小(4)的整数倍,所以3要加1变成4。最后所占的空间为8,满足是所有成员变量大小的整数倍
};
sizeof(struct Test1) = 8
struct Test2{
char a; // 0 1 1
int tmp; // 1 4 8//当前偏移量1不是该成员变量大小(4)的整数倍,所以1要加3变成4,所这时占的空间大小为8
char b; // 8 1 9//9不是所有成员变量大小的整数倍,所以还要加3,即12是4或1的整数倍
};
sizeof(struct Test2) = 12
struct Test3{
char a; // 0 1 1
int tmp; // 1 4 8//当前偏移量1不是该成员变量大小(4)的整数倍,所以1要加3变成4,这时所占的空间大小为8
char str[8]; // 8 8 16 //这里可以不是数组的整数倍,但必须是另外两个成员变量的整数倍
};
sizeof(struct Test3) = 16
struct Test3_1{
char a; // 0 1 1
int tmp; // 1 4 8//当前偏移量1不是该成员变量大小(4)的整数倍,所以1要加3变成4,这时所占的空间大小为8
char str[9]; // 8 9 17 //这里偏移量不为该成员变量大小的整数倍。所以所占空间的大小为17。17不是4的整数倍,所以17要加3,即20是4或1的整数倍
};
sizeof(struct Test3_1) = 20;
//对于有内嵌结构体的结构体,要先计算内嵌结构体的大小,然后再加上外部变量
struct Test4{
char a; // 0 1 1
int tmp; // 1 4 8
struct B{ // 8 8 8 16
char c; // 1
int b; // 4+3
}b1;//这里要定义一个b1变量,没有b1的话,就不对了
float e; // 16 4 20//20可以不为内嵌结构体大小的整数倍,但必须是其他成员变量的整数倍
};
sizeof(struct Test4) = 20;
struct Test4_1{
char a; // 0 1 1
int tmp; // 1 4 8
struct B{ // 12 8 12 20//这里的偏移量不为该成员变量的整数倍,所以所占空间大小为20
int b; // 4
char c; // 5
int d; // 12
}b1;//这里要定义一个b1变量,没有b1的话,就不对了
float e; // 20 4 24//24可以不为内嵌结构体大小的整数倍,但必须是其他成员变量的整数倍
};
sizeof(struct Test4_1) = 24;
struct Test4_2{
char a; // 0 1 1
int tmp; // 1 4 8
struct B{ // 16 8 16 24//这里的偏移量不为该成员变量的整数倍,所以所占空间大小为20
char c; // 1
double d; // 16
}b1;//这里要定义一个b1变量,没有b1的话,就不对了
float e; // 24 4 28//28可以不为内嵌结构体大小的整数倍,但必须是内嵌结构体中成员变量(double)的整数倍和外部成员变量的整数倍。
//所以也要为double的整数倍
};
//对齐值小于最大类型成员值
#pragma pack(4) //指定向4对齐 最大是8
struct Test5{
char ch; //1
int i;//8
float f;//12
double d;//12 8 20 //偏移值12是4的整数倍,不用是8的整数倍
};
sizeof(struct Test5) = 20//如果我们没有指定对齐值,这个结构体大小是24,我们指定向4对齐,所以大小是4的倍数,所以结构体大小是20。
//对齐值大于最大类型成员值
#pragma pack(10)
struct Test6{
char ch; //1
int i; //8
float f;// 12
double d;//12 8 24//12不是8的整数倍,所以要加4,即为16
};
sizeof(struct Test6) = 24//我们指定的对齐值是10,最大为8,是否就向10对齐?不是,当指定对齐值大于自身对齐值时,向自身对其值对齐,大小是24.
联合体(共用体):有时同一地址空间存放类型不同,不同类型的变量共享一块空间
结构体的元素有自己单独的空间,而共用体元素共享空间,空间的大小由最大的类型确定;
结构体元素互不影响,共用体赋值会导致覆盖,
union Test
{
int idata;
char cdata;
double ddata; //8字节
}
union Test u1;
u1.idata = 10;
u1.cdata = 20;
printf("idata = %d\n", u1.idata); // 这里的值为20,它把前面的值覆盖了
枚举:
枚举也是一种数据类型,也要定义
enum Weekend {sun,mon,tus,wed,thu,fri,sat};