结构体定义用struct ,结构体里的变量为结构体的属性,结构体也是一种类型,是我们自己定义的类型。
struct days
{
int year ;
int month ;
int day ;
};
比如在这里定义一个日期的结构体,struct +结构体名称 后面大括号里面写结构体成员 , 别忘了最后要带上 " ; " , 结构体是和基本类型一样的类型,也可以用来定义变量。如struct days a , 此时的a便是结构体变量,占有12个字节。也可以定义指针,数组等,如struct days ar[5] ,struct days *p 。
那在定义了结构体变量后,它在内存中是如何分布的呢。在我们定义结构体变时,会一次给够结构体的字节个数。按结构体中变量顺序开辟连续空间。给结构体赋值: a = { 2021 , 8 , 10} 。
访问结构体成员用 " . " , 如 a.year ,如果是一个指针指向结构体 struct days *p =&a,
对于指针的节引用是 p->year ,表示的是a中的year 。
结构体的大小
那么结构体所占的字节是不是把里面的基本类型字节相加就可以了呢?
struct student
{
char name[10];
int id;
char gender[5];
};
int main()
{
struct student b;
int a = sizeof(b);
printf("%d\n", a);
return 0;
}
这里我们简单的定义一个结构体计算一下
按正常思路应该输出的是19,但这里输出的是24 , 这里就有以下对齐原则;
1 . 结构体成员对首地址的偏移量要为基本成员类型的整数倍 , 比如这里的id 距结构体的首地址是10个字节 ,但id 为整形 是4个字节,10不是4的整数倍 ,所以底下会多开辟两个空间 id是从第13个字节开始的 。
2 结构体的总大小要是结构体中最大基本成员类型的整数倍 ,当我们按照1的原则对齐好后是21个字节 ,但21 不是4的整数倍 ,所以又会多开辟3个字节对齐。 最后为24个字节。
要注意这里说的都是基本成员类型 ,结构体的第一个变量虽然是数组 ,但它的本质还是char类型 ,按照一个字节一个字节对齐的。
联合体
联合体 用 union 来定义 , 联合体定义和struct类似 ,但联合体中的变量是用的同一空间 ,
union up
{
char c;
int k;
char i;
char j;
};
int main()
{
union up b;
b.k = 0x11223344;
int a = sizeof(b);
printf("%d\n", a);
printf("%x\n", b.c);
printf("%x\n", b.i);
printf("%x\n", b.j);
return 0;
}
这里定义了一个结构体 ,来看看它的字节个数和里面成员的值
打印发现它只占了四个字节 ,并且里面的char类型的值一样,都是int 的第一个字节 ,说明联合体里面的成员共用一个空间 ,而且都是从第一个字节开始 。 这里用 联合体检查大端还是小端是非常方面的 , 比如让 int类型的值为1 看char类型是1还是 0 。
那联合体的大小是最大类型的字节个数吗? 其实联合体也是有对齐原则的 ,联合体的大小必须是最大类型成员的整数倍 。 这里的最大成员不单单只基本成员类型 ,也包括其他的 ,如数组,结构体等。