C语言结构体大小;结构体嵌套结构体大小的计算方法分析

C语言结构体大小;结构体嵌套结构体大小的计算方法分析!

在了解结构体大小如何计算之前,我们首先得了解结构体的对齐规则:

  1. 第一个成员在与结构体变量偏移量为0的地址处;
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处;
    对齐数 = 编译器默认的一个对齐数 与 该成员大小的 较小值
    在vs环境下,默认值为8,而gcc没有默认对齐数,对齐数为环境自身大小;
  3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍;
  4. 如果有嵌套了结构体的情况,其那套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

结构体的内存对齐就是拿 空间 来 换取 时间 的做法,以此来提升效率!

例如计算以下结构体的大小:

#include<stdio.h>

void test()
{
	struct S
	{
		int a;
		char b;
		short c;
	};
	
	printf("结构体S的大小为:%d \n",sizeof(struct S));

}

int main()
{
	test();


	return 0;
}
	};

其中:a本身大小为4个字节,b的大小为1个字节,c的大小为2个字节,加起来应该是7个字节,但是我们看一下运行结果:
在这里插入图片描述
为什么结果会是8呢?这就涉及到我们上面所说的结构体内存对齐的原则了,如图:
在这里插入图片描述

我们知道,在a,b,c三个变量中,a是第一个成员,从0处对齐(图中红色部分),b的大小为1,紧接着的4也是1的倍数,因此在4的位置可以直接对齐(图中橙色部分),c的大小为2,5并不是2的倍数,所以向后偏移一位到6的位置对齐(图中绿色部分)。又因为a是最大的为4个字节,所以结构体S中最大对齐数为4,因此,结构体总大小为最大对齐数4的整数倍,正好0 ~ 7是4的整数倍8个字节;

再来看以下结构体的情况:

#include<stdio.h>

void test()
{
	struct S
	{
		int a;
		char b;
		int c;
		short d;
	};
	printf("结构体S的大小为:%d \n",sizeof(struct S));
}

int main()
{
	test();
	return 0;
}

其中,a的大小为4个字节,b的大小为1个字节,c的大小为4个字节,d的大小为2个字节;c为4个字节,d为2个字节,我们同样按照结构体大小对其的方式,来画出分析图:
在这里插入图片描述
从图中易知,a为第一个成员,在0处对齐,b大小为1,在4处对齐,c大小为4,5不是4的倍数,因此向后移动3位至8处对齐,d的大小为2,因此在紧接着c并且正好是2的倍数12处对齐,而整个结构体的大小为最大对齐数4的整数倍,14显然不是4的整数倍因此向后移动两位至16处,因此结构体大小为16;
运行结果验证:
在这里插入图片描述
下面我们再来看以下结构体内含有指针的情况:

#include<stdio.h>

void test()
{
	struct S
	{
		int a;
		char b;
		struct S* c;

	};
	printf("结构体S的大小为:%d \n",sizeof(struct S));
}

int main()
{
	test();
	return 0;
}

当结构体中含有指针的时候,主要是看当前 环境下指针的大小,32位下大小为4,64则为8,此时结构体对齐到自己的最大对齐数的整数倍处,我们观察代码易知,结构体指针(struct S* c)在32位下大小为4;因此画图分析:
在这里插入图片描述
由图中易知,第一个成员a大小为4,从0处对齐,第二个成员b大小为1,从1的整数倍4紧接着a对齐,第三个成员是指针,最大对齐数4,而5并不是4的倍数,因此向后移动3为至8处对齐;
因此整个结构体的大小为最大对齐数4的倍数,而0~11大小为12,正好是4的倍数,因此本结构体的大小为12;
以下为运行结果验证:
在这里插入图片描述

下面我们来看一下结构体嵌套结构体的情况:


#include<stdio.h>

void test()
{

	struct S
	{
		int a;
		char b;
		int c;

	};
	printf("结构体S的大小为:%d \n", sizeof(struct S));
	struct S1
	{
		int a;
		char b;


	};
	printf("结构体S1的大小为:%d \n", sizeof(struct S1));

	struct S2
	{
		int a;
		char b;
		struct S s;

	};
	printf("结构体S2的大小为:%d \n", sizeof(struct S2));

}

int main()
{
	test();
	return 0;
}

在上面的代码中,我定义了三个结构体,在由上述知识可以明显得出前两个未嵌套结构体的大小:
S: 12
S1:8

而此时的S2结构体实际上就是S1结构体中包含了一个S结构体变量,因此画图分析:
在这里插入图片描述
结构体嵌套结构体同样遵循内存对齐原则,最终易得,结构体大小为20:
在这里插入图片描述

在此感谢评论区大佬指出错误,误将指针作为嵌套结构体了,文章已做修改,再次感谢大佬指正!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值