定义结构体数组与定义结构体变量的方法一样,只要说明是数组,给出数组元素个数即可。例如,有结构体类型student:
struct student
{
int sno;
char sname[10];
int sage;
char depmt[20];
float cscore;
};
如果想定义结构体数组,与结构变量的定义相似,也分直接定义和间接定义两种方法。
(1)直接定义法定义结构体数组。
struct student
{
…
}sl[3];
定义一个student型结构体数组,数组名为s1,其中含3个元素。
(2)间接定义法定义结构体数组。
struct student
{
…
};
main()
{
struct student s[3];
…
}
结构体数组的存放和普通数组一样,也是在内存中顺序存放的,存放示意图如图所示。
sno sname age depmt cscore1001 | zhangsdn | 21 | computer | 78 |
1002 | lisi | 20 | computer | 83 |
1003 | wangwu | 21 | computer | 90 |
一个结构体数组元素的长度可以用sizeof运算求得,例如:
main()
{
struct student s [3];
printf("%d\n",sizeof s[0]); /*计算一个结构体数组元素的长度*/
printf("%d\n",sizeof s); /*计算一个结构体数组整+在内存所占的字市*/
程序执行,输出结果为:
44
132
可能读者经过分析认为,该结构体数组元素所占的内存字节数应该是sno(int4字节)+ sname(char10字节)+ sage(int4字节)+ depmt(char20字节)+ cscore(int4字节)=42。那么系 统给出的为什么是44个字节呢?
这是因为在VC6.0编译系统中,结构体类型存在结构字节边界(Struct Member Alignment)的要求,具体为:各成员变量在内存中的起始地址相对于结构体变量(或数组)的起始地址的偏移量,必须为该变量的类型所占用的字节数的倍数。如果某成员的偏移量不是该类型的整数倍数,则VC编译系统会自动填充一定的字节数,以保证结构体字;边界的要求。同时VC为了确保结构体的大小为结构体 中所占内存空间最大的成员类型的字节数的倍数,在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。
假设为结构体数组s的第一个元素s[0]分配的首地址为2000, s[0]的地址与结构体数组的首地址相同,偏移量为0,是sizeof(int)的倍数,则s[0].sno的地址空间为200~2003,之后为s[0].sname分配内存地址2004,偏移量为4,是size(char)的倍数,所以s[0].sname所占内存地址段 为2004-2013;当为s[0].sage分配空间时,应该分配2014,偏移量为14, 14不是sizeof(int)的倍数,为保证偏移量是sizeof(int)的倍数,VC自动填空2个字节,然后s[0].sage所分配的内存地址段为2016-2019。
按照这样的过程,依次为s[0].d印mt分配内存地址段为2020〜2039;为s[0].cscore分配内存地址段为2040~2043。
这样一来,该结构体数组元素所占字节大小为4+10+2 (系统自动填充的2个字节)+4+20+4=44 个字节。
因为该结构体数组元素在内存中占44个字节,其中占内存空间最大的成员类型为float型(4个字节),44%4为0,所以不需要在后面填充字节。
已有 22658 名学员学习以下课程通过考试
最需教育客户端 软件问题一手掌握
去 App Store 免费下载 iOS 客户端
点击加载更多评论>>