c提供了两种类型的聚合数据类型:数组和结构体。
数组是相同类型的数据在内存空间按顺序存储的集合,每个元素是通过下标引用或指针间接访问来选择的。
结构是一些值的集合,各成员是不同的数据类型。
结构体的自引用:
struct work1
{
int a;
struct work1 b;
int c;
};
这种引用是非法的,因为b是一个完整的结构,还包含b,这样会重复下去,有点像永远不会停止的递归。
struct work1
{
int a;
struct work1 *b;
int c;
};
b是指针,编译器在结构的长度确定之前就已经知道指针的长度,所以这类的自引用是合法的,事实上是一种同类型的不同结构。在链表和树中都是使用这种技巧。
结构的存储分配:编译器按照成员列表的顺序一个接一个的给每个成员分配空间,只有当存出成员时需要满足正确的边界对齐要求时,成员之间才能出现用于填充的额外内存空间。
struct Ling
{
char a;
int b;
char c;
};
系统分配的空间是12个字节。
系统会按字节数最大的数据类型分配空间,所以a会被分配4个字节,由于a是char类型,会多出3个字节的存储空间,但是b的存储空间是需要4的字节,由上述的编译器按照成员列表的顺序一个接一个的分配空间可知此时a多余的存储空间是不能够被b引用的。
struct Ling
{
int a;
char b;
char c;
};
此时系统会分配8个字节空间,此时按照4个字节分配空间,a是4个字节,b是4 个字节,但是b是char类型,所以会多出3个字节的空间,会被字节的分配给c进行引用。
数组是相同类型的数据在内存空间按顺序存储的集合,每个元素是通过下标引用或指针间接访问来选择的。
结构是一些值的集合,各成员是不同的数据类型。
结构体的自引用:
struct work1
{
int a;
struct work1 b;
int c;
};
这种引用是非法的,因为b是一个完整的结构,还包含b,这样会重复下去,有点像永远不会停止的递归。
struct work1
{
int a;
struct work1 *b;
int c;
};
b是指针,编译器在结构的长度确定之前就已经知道指针的长度,所以这类的自引用是合法的,事实上是一种同类型的不同结构。在链表和树中都是使用这种技巧。
结构的存储分配:编译器按照成员列表的顺序一个接一个的给每个成员分配空间,只有当存出成员时需要满足正确的边界对齐要求时,成员之间才能出现用于填充的额外内存空间。
struct Ling
{
char a;
int b;
char c;
};
系统分配的空间是12个字节。
系统会按字节数最大的数据类型分配空间,所以a会被分配4个字节,由于a是char类型,会多出3个字节的存储空间,但是b的存储空间是需要4的字节,由上述的编译器按照成员列表的顺序一个接一个的分配空间可知此时a多余的存储空间是不能够被b引用的。
struct Ling
{
int a;
char b;
char c;
};
此时系统会分配8个字节空间,此时按照4个字节分配空间,a是4个字节,b是4 个字节,但是b是char类型,所以会多出3个字节的空间,会被字节的分配给c进行引用。