为了账号安全,请及时绑定邮箱和手机立即绑定

146. 设有以下定义语句:

146. 设有以下定义语句:

C
包小龙虾 2018-08-01 11:55:12
146. 设有以下定义语句:struct student{ int num;char name[10];float score;} wang,zhang;则变量wang所占的内存字节数是( )。A. 14B. 16C. 18D. 20求会的大神解析下,拜托了
查看完整描述

3 回答

已采纳
?
onemoo

TA贡献883条经验 获得超454个赞

每种类型都有一个叫做“对齐值”的属性。这个属性相当于描述“在内存中其能够分配的起始地址和前一一个此类型能够分配的起始地址的间距”。

啊,好吧,我的文字表达能力比较差,上述说法我自己看着都觉得累,其实通俗地说就是限制了“能在内存中哪些位置放这个类型的对象”。

我还是举些例子吧,我们在假想的一小段内存中进行描述,这段内存的起始地址被当作 0 地址:

  • 假定 int 类型本身占 4 字节,对齐值也是 4。那么如果想在这段内存中放一个 int 变量,能放在哪里呢?

    起始的 0 字节处当然可以放。但如果我不从这段内存起始处放,能不能从第 2 字节处放一个 int 呢?  答案是不可以!

    因为 int 的对齐值是 4。内存 0 字节之后,只能间隔 4 字节再放一个 int 对象,所以只能在这段内存的 4 字节处放一个 int。注意:这并不是因为 0 到 3 字节被前一个 int 占用了!即便这段内存中只放一个 int,前面 0 到 3 字节都是空的,也不能在 1、2、3 字节处放置 int ——两个合法的放置 int 的起始地址必须间隔 4。

    也就是只能在这段内存的 0、4、8、12 ....字节处分配 int 对象。

  • char 类型本身占用 1 字节(这点不用假设了,C标准规定如此),对齐值也是 1 。那么你可以知道,这段内存的任何一个字节处都可以合法地放置一个 char 对象。

  • 我希望你看懂了我的这些罗嗦解释。

还有,就像你知道 C 语言是很灵活的,其实 C 标准并没有规定每种类型具体占用内存的大小和其对齐值,不同平台可能有自己的规定。C 标准只是规定了对齐值必须是 2 的整数次幂(从 C11 标准开始,你可以用 _Alignof 运算符来获得类型的对齐值)


union 的所有成员的起始地址都一样,所以基本上不用考虑对齐的问题。

struct 的不同成员是依次放置于内存中的,每个成员在内存中的位置都必须满足其类型对齐值的要求!  而整个 struct 的对齐值一般是其成员对齐值中最大的一个(不过此题不涉及这点)。


正如我前面提到 C 标准没有具体规定类型的对齐值。那么严格地说,这道题出得也不严谨,它应该说明这些类型的对齐值再让学生做计算的。既然它没说,我就用常见的对齐值来解释下题目中的 struct:

  • int 占 4 字节,对齐值为 4。所以 struct 中前 4 个字节就是这个 num,这是很显然的。

  • char 占 1 字节,对齐值为 1。数组中元素是紧挨着放置的,所以 name 数组占 10 字节。

    这样 struct 前 14 个字节就是 num 和 name 占用的。

  • float 占 4 字节,对齐值为 4。那第三个成员 score 就不能从第 15 字节起了。它必须放在 4 的倍数的位置上,所以第 15、16 字节要被空出来,从第 17 字节处放置 score。score 占用第 17、18、19、20 字节。

那么整个 struct 就占用 20 字节。  

查看完整回答
1 反对 回复 2018-08-12
  • 包小龙虾
    包小龙虾
    嗯嗯,看了大神的回答,我自己理了一下思路,以后这样子想对吗?:union 没有涉及到字节对齐的问题,所以在碰到union 时还是按“union 占用的内存就是其最大成员占用的大小”只有在碰到结构体时才考虑对齐的问题。就是说:“结构体大小等于最后一个成员的偏移量加上其大小”,int 类型本身占 4 字节,对齐值也是 4,char 类型本身占用 1 字节,而char name[10];占10,与前面的4相加就是14,而因为要满足(1)结构体变量中成员的偏移量必须是成员大小的整数倍。又因为float 类型要占4,所以前面的14要再加上2变成16,也就是float score;的偏移量是16,16满足(1)结构体变量中成员的偏移量必须是成员大小的整数倍。加上他本身的大小4,就变成了20。再满足一个条件就是‘(2)结构体大小必须是所有成员大小的整数倍,即所有成员大小的公倍数。’而20就是 int num; char name[10]; float score; 这三个的公倍数。
  • onemoo
    onemoo
    再准确点的话,不是“成员的偏移量必须是成员大小的整数倍”,而应该说是“成员的偏移量必须是成员的类型的对齐值的整数倍”。
  • onemoo
    onemoo
    也不是“结构体大小必须是所有成员大小的整数倍”,而应该是“结构体大小必须是其对齐值的整数倍”。 结构体的对齐值一般是它所有成员对齐值中最大的一个。 这个例子中的结构体,其成员对齐值最大的是4,所以结构体的对齐值也为4。那么20恰好满足4的倍数,所以结构体的大小就是20了。
点击展开后面5
  • 3 回答
  • 2 关注
  • 1703 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信