首页 > 试题广场 >

则执行后,变量sz的值将得到

[单选题]
现在有以下语句:
struct _THUNDER {
    int iVersion;
    char cTag;
    char cAdv;
    int iUser;
    char cEnd;
} Nowcoder;
int sz = sizeof(Nowcoder);


则执行后,变量sz的值将得到
  • 11
  • 12
  • 13
  • 16
推荐
【正确答案】D
【解析】内存对齐的规则:
1.第一个成员必须是从0位置开始偏移
2.后面的成员从成员的大小和对齐模数相比取小的整数倍的的地方(对齐模数默认是 8)
3.最后要对结构体整体进行对齐:成员中最大的那一个和对齐模数相比取小的整数倍
这里结构体具体的每个成员所在位置:
int iVersion;  0 ~ 3
char cTag;    4 ~ 4
char cAdv;    5 ~ 5
int iUser;      8 ~ 11
char cEnd;    12 ~ 12
最后末尾 13 ~ 15 补 3 个字节,一共是 16 个字节。

内存对齐知识点讲解】
更多C++基础专业知识讲解,点击链接即可查看
https://www.nowcoder.com/link/zxyl-cpp12
编辑于 2021-11-17 15:01:11 回复(0)
<p>内存对齐</p><p><br></p>
发表于 2020-08-18 09:34:26 回复(0)
发表于 2020-08-08 17:33:17 回复(0)
内存对齐
发表于 2017-02-07 23:54:16 回复(0)
分别 占字节数 int 4 char 1 char 1 int 4 char 1

对齐方式   4  1  1  ②   4   1  ③

圆圈的数代表补充的空字节
对齐方式: 前面的长度必须为当前要添加的字符长度的整数倍,到最后还要补齐使得最终长度是最长的字符的整数倍
发表于 2015-07-30 14:15:00 回复(4)
这种题要坚持两个原则 (1)当前成员变量之前的总容量必须为此变量大小的整倍数 (2)整个结构体的总容量必须为最大成员变量的整数倍
发表于 2017-03-11 13:36:41 回复(0)
struct _THUNDER{    /* 长度对比,按X长度对齐,开始位置,计算,存放位置 */
int iVersion; /* 4<8,按4对齐,0, 0%4 =0; [0,3] */
char cTag; /* 1<8,按1对齐,4, 4%1=0; [4]*/
char cAdv; /* 1<8,按1对齐,5, 5%1=0; [5] */
int iUser; /* 4<8,按4对齐,8, 8%4=0; [8,11] */
char cEnd; /* 1<8,按1对齐,12, 12%1=0; [12] */
                 /*最后没有对齐,非4的整数倍数,补齐, [13,15]*/
}Thunder;

struct A{ /* 长度对比,按X长度对齐,开始位置,计算,存放位置 */
char c1; /* 1<8,按1对齐,0, 0%1=0; [0]*/
int i; /* 4<8,按4对齐,4, 4%4 =0; [4,7] */
short s; /* 2<8,按2对齐,8, 8%2=0; [8,9]*/
int j; /* 4<8,按4对齐,12, 12%4 =0; [12,15] */
/* 无需补齐 */
}a;

struct B{ /* 长度对比,按X长度对齐,开始位置,计算,存放位置 */
int i; /* 4<8,按4对齐,0, 0%4 =0; [0,3] */
int j; /* 4<8,按4对齐,4, 0%4 =0; [4,7] */
short s; /* 2<8,按2对齐,8, 8%2=0; [8,9]*/
char c1; /* 1<8,按1对齐,10, 10%1=0; [10]*/
/* 最后没有对齐,非4的整数倍数,补齐, [11] */
}b;

发表于 2018-03-05 22:20:42 回复(0)
满足两条规则,1每个成员的偏移量都必须是当前成员所占内存大小的整数倍,如果不是,编译器会在成员之间填上字节;2当所有成员计算完成之后,编译器判断当前结构体大小是否是结构体中最宽成员变量大小的整数倍,如果不是会在最后一个成员后做字节填充。该题如下:iVersion 偏移0,大小4; CTag 偏移4,大小2;cAdv 偏移6,大小2;iUser 偏移8,大小4;最后一个偏移12,大小2;总共大小14,填充2,变为4的整数倍,所以最后结果为16。
编辑于 2017-03-25 17:19:27 回复(1)
分析:内存对齐问题,相关知识可参考http://blog.chinaunix.net/uid-10995602-id-2918694.html
发表于 2014-11-13 22:57:45 回复(0)
最大对齐为4。字节对齐:计算机存储系统中以Byte为单位存储数据,不同数据类型所占的空间不同。计算机为了快速的读写数据,默认情况下将数据存放在某个地址的起始位置,如整型数据(int)默认存储在地址能被4整除的起始位置,字符型数据(char)可以存放在任何地址位置(被1整除),短整型(short)数据存放在地址能被2整除的起始位置。这就是默认字节对齐的方式

|----------int----------|

|char|char|char|char|

|----------int----------|
|char|char|char|char|

发表于 2017-12-21 20:42:22 回复(1)
结构体默认对齐方式为8,则iVersion取4字节对齐,CTag、CAdv和cEnd取2字节对齐,结构体大小为14,14不为4的整数倍,补空字节,增至16时符合所有条件,则sizeof(Thunder)为16。
发表于 2015-05-06 15:37:55 回复(4)

所以在编程的时候也要注意,最好把相同类型的放一起,这样能节省空间,该题中的两个int如果放一起写,总容量应该就是12了

发表于 2020-01-15 18:00:23 回复(0)
发表于 2020-04-21 15:13:39 回复(0)
对齐方式:前面的长度必须要为当前要添加的字符长度的整数倍,到最后还要补齐使得最终长度是最长字符的整数倍;
发表于 2018-07-24 21:55:17 回复(0)
成员变量        偏移量         所占内存
int                4                      [0:3]
char                1                    [4]
char              1                      [5]
int                  4                    [9:12]
char                1                    [13]
考虑整体对齐 选择基数为4,所以最后所占内存为【16】。
编辑于 2016-09-06 19:36:11 回复(1)
4 + 4 + 4 + 4 需要字节对齐 不足4个字节的部分 空出来凑够4个字节来占位
发表于 2016-08-12 23:39:00 回复(0)
这题目没说32位还是64位啊
发表于 2021-11-06 17:30:27 回复(1)
到最后还要补齐使得最终长度是最长的字符的整数倍
发表于 2022-03-14 18:43:11 回复(0)
结构体大小确定的原则:
1、每个变量自己先对齐——找到自己的位置。
      自对齐的原则是:按照变量声明的顺序,每个变量都只能以它长度的整数倍的地址作为起始存储地址。比如:char = 1;short = 2;int = 4;那么他们分别以1 的倍数、2的倍数、4的倍数作为起始位置,中间填不满的就作为空。声明顺序为,int ,char ,char  int  char ,按自身对齐原则计算,他们的长度为13

2、再取最大长度的变量的长度作为有效读取宽度,要使得总大小为有效读取宽度整数倍
     因此,有效读取宽度为 4, 自对齐的结果是13,不是4的整数倍,因此将其补满16.故而结果是16.
发表于 2016-09-13 02:43:28 回复(0)

你起码给个编译器默认对齐字节数是多少呀???1还是2还是4还是8还是16呀????
如果是1的话,答案是11
如果是2的话,答案是12
如果是4、8、16的话,答案是16

发表于 2023-12-07 18:36:22 回复(0)
结构体_THUNDER包含了两个int类型的变量和三个char类型的变量。在大多数系统中,int类型的变量占用4个字节,char类型的变量占用1个字节。
iVersion作为第一个变量,它的地址会被对齐到4字节边界,所以它占用的内存大小为4字节。接下来的cTag占用1个字节,但是由于cAdv也是char类型,它们可以连续存储,不需要额外的内存对齐,所以cTagcAdv一共占用2个字节。然后,iUser需要对齐到4字节边界,所以在cAdviUser之间会有2个字节的填充。iUser本身占用4个字节。最后,cEnd占用1个字节,但是为了使整个结构体的大小为4字节的倍数,会在cEnd后面添加3个字节的填充。所以,Nowcoder的大小为4(iVersion)+ 2(cTagcAdv)+ 2(填充)+ 4(iUser)+ 1(cEnd)+ 3(填充)= 16字节。
by bingai
发表于 2023-12-04 11:25:34 回复(0)