结构体大小计算(例题讲解)

目录

1.如何计算结构体大小?

 2.计算下题pointer分配的空间大小?(包含位段成员的结构体大小)

 3.下题输出结果是?

 4.计算下面联合体所在内存的大小

 5.下面输出结果为?

 6.下面输出结果为?(枚举)


1.如何计算结构体大小?

 首先得掌握结构体的对齐规则:
1. 第一个成员在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小之间的较小值。
VS中默认的值为8
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

概念就这些,上题目

1.在32位系统环境,编译选项为4字节对齐。那么sizeof(A)和sizeof(B)分别为多少?(sizeof求所占空间的大小,单位字节)

#pragma pack(4)//设置默认对齐数为4
struct A
{
	int a;
	short b;
	int c;
	char d;
};
struct B
{
	int a;
	short b;
	char c;
	int d;
};
#pragma pack()//取消默认设置的对齐数
int main()
{
	struct A a = { 0 };
	struct B b = { 0 };
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(b));
}

 struct A最大对齐数,及成员的对齐数

int a             大小为4个字节 == 默认对齐数为4  所以    对齐数为4

short b        大小2个字节 < 默认对齐数                        对齐数为2

char c         大小1个字节 < 默认对齐数                        对齐数为1

int d            大小4个字节 == 默认对齐数                      对齐数为4

故最大对齐数:4

struct B 同理可得,不在赘述

 图解

 故sizeof(a)=16,sizeof(b)=12

 2.计算下题pointer分配的空间大小?(包含位段成员的结构体大小)

#define MAX_SIZE 2+3
struct Test
{
	unsigned char a : 4;
	unsigned char b : 2;
	unsigned char c;
	unsigned char d : 1;
}*Record;
int main()
{
	struct Test* pointer = (struct Test*)malloc(sizeof(struct Test) *MAX_SIZE);
	//pointer分配的空间
	printf("%d", sizeof(struct Test) *MAX_SIZE);
}

 本题需要主要考察包含了位段成员的结构体大小计算及对宏的了解程度

位段成员包含char是按1个字节开辟内存的,第一个成员a开辟一个字节等于8个bit位,被a用去4个bit,还剩4个bit可以给b用去2个bit,故位段a,b共用一个字节

c不是位段重新开辟一个字节的内存,它直接占一个字节

位段d只占1个bit,但也要开辟1个字节的空间,故一起共开辟了3个字节的空间

sizeof(struct Test)*MAX_SIZE=3*2+3=9,pointer分配的空间为9个字节

 3.下题输出结果是?

int main()
{
	unsigned char puc[4];
	struct tagPIM
	{
		unsigned char a;
		unsigned char b : 1;
		unsigned char c : 2;
		unsigned char d : 3;
	}*p;
	p = (struct tagPIM*)puc;
	memset(puc, 0, 4);//memset:内存函数
	p->a = 2;
	p->b = 3;
	p->c = 4;
	p->d = 5;
	printf("%02x %02x %02x %02x \n", puc[0], puc[1], puc[2], puc[3]);
	return 0;
}

 图解

 由上图可知最后输出 02 29 00 00

 4.计算下面联合体所在内存的大小

union Un
{

	short s[7];
	int n;
};
int main()
{
	printf("%d",sizeof(union Un));
}

联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。

联合大小的计算
1.联合的大小至少是最大成员的大小。

2.当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

short s[7]  所占大小为14个字节  一个short类型大小为2个字节<默认对齐数8  则对齐数为2

int n        占4个字节<默认对齐数8         对齐数为4

得最大对齐数为4

由联合体大小计算可知:该联合体大小为16

 5.下面输出结果为?

int main()
{
	union 
	{
		short k;
		char i[2];
	}*s,a;//a为联合体变量
	s = &a;
	s->i[0] = 0x39;
	s->i[1] = 0x38;
	printf("%x\n",a.k);
}

 图解

 7.下面输出结果为?

typedef struct{//typedef对类型重定义
	int a;
	char b;
	short c;
	short d;
}AA_t;//AA_t为重定义的结构体类型
int main()
{
	printf("%d\n",sizeof(AA_t));
	return 0;
}

  如果你看了前面的题目这道题完全可以心算

int a 占0-3偏移

char b 4偏移处

5偏移处浪费掉

short c 6-7偏移

short d 8-9偏移

总共占了10个字节 0-9偏移

由于最大对齐数为4,结构体大小为最大对齐数的整数倍

故结构体大小sizeof(AA_t)=12

 6.下面输出结果为?(枚举)

enum A
{
	X1,
	Y1,
	Z1=255,
	A1,
	B1,
};
int main()
{
	enum A a = Y1;
	enum A b = B1;
	printf("%d %d\n", a, b);
}

 要知道上题答案,须知枚举类型定义

{}中的内容是枚举类型的可能取值,也叫枚举常量。

这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。 

简单来说如果都没赋初值值从0开始,依次递增1

如果部分赋了初值,后面一位的值为赋了值得那一位的值加1

以上题为例:

X1没赋初值         默认为0

Y1                        X1+1=1

Z1赋了初值255

A1                        Z1+1=256

B1                        A1+1=257

所以输出:1  257

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值