首页 > 试题广场 >

若int占2个字节,char占1个字节,float占4个字节

[单选题]

int 2 个字节, char 1 个字节, float 4 个字节, sizeof(xc) 大小是:

struct stu {
    union{
        char bj[5];
        int bh[2];
    } _class;
    char xm[8];
    float cj;
}xc;



  • 16
  • 18
  • 22
  • 20
推荐
答案是 D
内存对齐规定:结构体的总大小为结构体最宽基本类型成员大小的整数倍
可见最宽的是float是4.,数组的形式只是多个数据放在一起而已。
联合体里面总共是5个字节,要为4的倍数所以为8个字节,
所以为8+8+4=20
编辑于 2015-08-12 11:28:06 回复(16)

struct stu

{

union{

char bj[5];      // 5 

int bh[2];        // 2

} class;                 // union 总大小为 5,但需要补齐为 int 的整数倍,所以实际大小为 5 + 1 = 6,后一项为 char,不需要对齐

char xm[8];           // (6) + 8 = 14, 不是 float 的倍数,需要对齐,所以最终:(6) + 8 + (2) = 16

float cj;                 // (16) + 4 = 20, 是 float 的倍数,不需要补齐,最终大小为 20

}xc

发表于 2015-09-06 14:24:27 回复(20)
结构体内存对齐规定:结构体的总大小为结构体最宽基本类型成员大小的整数倍,这道题目中最宽的是float,其占4个字节,但是此题目中还有一个联合体(联合体的大小取内部最大的字节数, union内部的数据成员中最大的数据成员为int,所以每个数据成员要为2的倍数

struct stu

{

union{

char bj[5];      // 1*5=5 

int bh[2];        // 2*2=4

} class;                 // union中最大的字节数是5,但需要补齐为 int 的整数倍,所以实际大小为 5 + 1 = 6,但是外面看struct的对齐数,最大的是float的4字节,所以按四字节对齐,这样union补齐成8字节(4的倍数)是8

char xm[8];           // (8) + 8 = 16,16是 float所占字节数 的倍数,不需要对齐

float cj;                 // (16) + 4 = 20, 是 float 的倍数,不需要补齐,最终大小为 20

}xc

发表于 2017-05-07 00:58:59 回复(6)
B
【解析】
union{ char bj[5];  int bh[2];  } class占用的大小是5字节;
xm[8]占用8字节;
cj占用4字节。
但由于内存对齐(align),需要将每个成员填充为int大小的整数倍。该struct的大小位6+8+4=18字节

编辑于 2015-07-24 13:41:16 回复(5)
记住结构体中每一个成员的起始地址要是 该成员大小的整数倍。
所以,这题不是8+8+4
而是( ((5+1)+ 8) + 2) + 4
发表于 2016-08-28 15:55:16 回复(8)
cyi头像 cyi

感觉应该选D 20。union 中有两个数据类型char和int, int 占两个字节,较大,因此union对齐应该是2的倍数,而union内部中char有5个元素,因此占用5个字节,要对齐为此占用6个字节;接下来是char元素8个,占用8个字节,加上前面的6个字节共14个字节;接下来float存储的时候,float占4个字节为此需要以4个字节对齐,现在的位置是14,不满足4的倍数,为此float从16开始,然后占用4个字节,共20个字节

发表于 2015-07-14 14:54:44 回复(4)
本题涉及两个知识点:
第一、
union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。
第二、
内存对齐规定:结构体struct的总大小为结构体最宽基本类型成员大小的整数倍
可见最宽的是float是4.,数组的形式只是多个数据放在一起而已。
联合体里面总共是5个字节,要为4的倍数所以为8个字节,
struct stu

{

union{

char bj[5];

int bh[2];

  } class;    //所以这个union class只需要可以存储下占用空间最多的成员的空间即可,char bj[5]占用5个字节,所以union class占              //用5个字节
  char xm[8];  //8字节

float cj;       //4字节

}xc;

5+(3)+8+4=20,其中3是自动补齐的空间
 

发表于 2018-04-25 15:52:28 回复(0)
union是取其中最大的字节,即char b[5]的5字节,但需要2字节的对齐(struct和union都有字节对齐的问题),所以union占了6字节,外面看struct的对齐数,最大的是float的4字节,所以按四字节对齐,这样union补齐成8字节(4的倍数),8+8+4=20字节。
发表于 2016-08-25 00:11:27 回复(3)
D, union取最大的空间,即5字节。注意存储是连续的5个char ,后面char [8],不存在内存对齐。再看float,float为4字节,前面占据的内存总数是13,因为float在内存里为4字节,13不是4的整数倍,所有存在内存对齐。此时float不是从13的位置开始存储,而是从16的位置开始(4的整数倍)。16+4=20,再检查是否需要内存补齐,而20为最大float的整数倍,所以不需要补齐。所有选D
发表于 2016-11-22 10:40:36 回复(0)
结果是5+(1)+8+(2)+4=20 
union的地址为0x22fe9c
xm地址为     0x22fea2
cj地址为     0x22feac
int main(int argc, char** argv) {
struct stu{
union{
char bj[5];
short bh[2];
}ca;
char xm[8];
float cj;
}xc; 
cout<<sizeof(xc)<<endl;
cout<<&xc.ca<<endl;
cout<<&xc.xm<<endl;
cout<<&xc.cj<<endl;
return 0;
}

发表于 2017-03-28 19:53:12 回复(2)

struct stu

{

union{

char bj[5];      // 5 

int bh[2];        // 2

} class;                 // union 总大小为 5,但需要补齐为 int 的整数倍,所以实际大小为 5 + 1 = 6,后一项为 char,不需要对齐

char xm[8];           // (6) + 8 = 14, 不是 float 的倍数,需要对齐,所以最终:(6) + 8 + (2) = 16

float cj;                 // (16) + 4 = 20, 是 float 的倍数,不需要补齐,最终大小为 20

}xc

发表于 2021-03-20 15:54:15 回复(0)
写一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?讲讲字节对齐吧。

直接入题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则

1、数据成员对齐规则:结构(struct)(或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要改成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机4字节,则要从3的整数倍地址开始存储。)

2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那么b应该从8的整数倍开始存储。)

3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。

下面举一个例子:

typedef struct bb
{
 int id;             //[0]....[3]
 double weight;      //[8].....[15]      原则1
 float height;      //[16]..[19],总长要为8的整数倍,补齐[20]...[23]     原则3
}BB;

typedef struct aa
{
 char name[2];     //[0],[1]
 int  id;         //[4]...[7]          原则1

 double score;     //[8]....[15]
 short grade;    //[16],[17]
 BB b;             //[24]......[47]          原则2
}AA;

int main()
{
  AA a;
  cout<<sizeof(a)<<" "<<sizeof(BB)<<endl;
  return 0;
}

 

结果是

48 24
ok,上面的全看明白了吗?快去找找其他的题来实践一下吧。
发表于 2017-10-18 15:49:01 回复(0)
本题涉及两个知识点:
第一、
union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。
第二、
内存对齐规定:结构体struct的总大小为结构体最宽基本类型成员大小的整数倍

    可见最宽的是float是4.,数组的形式只是多个数据放在一起而已。

    联合体里面总共是5个字节,要为4的倍数所以为8个字节,

发表于 2020-09-11 10:01:00 回复(0)

struct stu

{

union{

char bj[5];      // 5 

int bh[2];        // 2

} class;                 // union 总大小为 5,但需要补齐为 int 的整数倍,所以实际大小为 5 + 1 = 6,后一项为 char,不需要对齐

char xm[8];           // (6) + 8 = 14, 不是 float 的倍数,需要对齐,所以最终:(6) + 8 + (2) = 16

float cj;                 // (16) + 4 = 20, 是 float 的倍数,不需要补齐,最终大小为 20

}xc

这里解释下为什么union大小为5,补充字节后为6;
因为C/C++中的联合体结构空间要大到足够容纳最"宽"的成员;
而最宽的是5(5>2),补齐为int整数倍,实际大小为6.
即6+8=14,此时要对齐float的整数倍,即补充为14+2=16
16+4=20.
发表于 2019-03-25 21:38:19 回复(0)
发表于 2017-12-18 21:10:08 回复(5)
结构体内存对齐规定:结构体的总大小为结构体最宽基本类型成员大小的整数倍,这道题目中最宽的是float,其占4个字节,但是此题目中还有一个联合体(联合体的大小取内部最大的字节数, union内部的数据成员中最大的数据成员为int,所以每个数据成员要为2的倍数)
发表于 2021-06-13 09:34:33 回复(0)
结构体中有一个联合体,且内存中存放顺序按定义顺序来。因此,首先看联合体部分,定义的char数组有5个,因此占5个字节,int按题占两个字节,定义的数组,因此占4个字节。要满足最大成员的同时,还要满足最大成员变量类型的整数倍,因此取该联合体占字节数为6(6>5且为2的整数倍,若按常规int占4个字节,则联合体取8字节!),之后看整个结构体,联合体占据6个字节,此时偏移量为6,而定义的char数组为8字节,不是8的整数倍,因此补两个字节,此时偏移量为8,为8的倍数,放入char型数组,此时偏移量为16,然后观察float型,为其整数倍,直接放入,因此一共20个字节,整体对齐时,考虑所有的变量类型(包括联合体中的char,int)然后满足最大字节类型变量的整数倍,此处为float型,4字节,已经对齐。占字节20

编辑于 2018-07-24 20:53:32 回复(0)
【每次分配单位为最大基本类型成员字节,此题为4字节】 union占6字节(5按2对齐),即分配2x4字节(剩余2字节); 8个1字节的char从之前剩余内存开始分配,还需6字节,于是再分配2x4字节(剩余2字节); 4字节的float大于剩余内存,只能新分配4字节。 故总共分配5x4=20字节。
发表于 2018-06-02 10:12:53 回复(0)
公式1:前面的地址必须是后面的地址正数倍,不是就补齐
公式2:整个Struct的地址必须是最大字节的整数倍
发表于 2018-04-03 14:41:26 回复(0)
6+8+(2)+4=20
发表于 2016-05-08 19:57:17 回复(0)
其实里面涉及到的一个问题是 某个数据成员的起始地址相对于结构体的起始地址的偏移量需要是结构体中最长的基础数据成员(不包括数组)的整数倍。本例中,结构体内一共有三个数据成员包括联合体 char数组和float型变量。联合体的内存对齐规则是取联合体中最长的数据成员的长度,但似乎还需要为联合体中最长的基础数据成员长度的整数倍。联合体的长度为5,但需要为int型长度的整数倍,则需要补齐1位为6。但是整个结构体中最长的基础数据成员为float,是4个长,所以联合体的长度还要再补齐2个,成为8,即结构体中,联合体的最终内存长度为8。结构体中第二个数据成员char数组的起始地址相对于结构体的起始地址的偏移量为8,而char数组的长度也为8。这样结构体中第三个数据成员float型数据的起始地址相对于结构体的起始地址的偏移量为16,是4的整数倍,则不用补齐。最终计算的整个结构体的内存长度为((5+1)+2)+8+4=20。
发表于 2018-08-31 13:23:12 回复(1)