其他分享
首页 > 其他分享> > 结构体和联合体的一些问题

结构体和联合体的一些问题

作者:互联网

查漏补缺一些结构体问题

结构体在内存中的对齐规则

  1. 结构体变量的首地址,必须是结构体变量中最大基本数据类型成员所占字节数的整数倍。
  2. 结构体变量中的每个成员相对于结构体首地址的偏移量,都是该成员基本数据类型所占字节数的整数倍。
  3. 结构体变量的总大小,为结构体变量中最大基本数据类型成员所占字节数的整数倍。

不好理解,用例子来看

示例

示例1

struct node
{
	char a;
	int b;
	double c;
};

int main(void)
{
	struct node S1;

	printf("size of S1 is %d\n", sizeof(S1));

	return 0;
}

结果:
在这里插入图片描述

原因:
结构体中的成员是按照定义顺序一个一个放入内存的,但并不是紧密排列。
从结构体存储的首地址开始,每个元素放置到内存中时,都会认为内存是以它自己的大小来划分的,因此元素放置的位置一定会在自己的所占字节数的整数倍上开始。

就上个例子来说,当系统为a开辟空间后,再存放整型变量b时,会以四个字节为单位进行存储,但第一个四字节块已经被a占了,所以b会存到下一个四字节块中,同理double类型的变量c会以八字节进行存储,第一个八字节块有数据,就找下一八字节块。
在这里插入图片描述在这里插入图片描述

示例二

struct node
{
	char a;
	double b;
	int c;
};

该变一下b和c的类型,我这里相当于把double类型放到第二个位置
运行结果:
在这里插入图片描述

这说明了规则的第三条:
结构体变量的总大小,为结构体变量中最大基本数据类型成员所占字节数的整数倍。

当为最后一个int类型变量开辟空间后,发现总大小不是最大类型double所占字节数的整数倍,那就要补齐。
图示:
在这里插入图片描述

为什么要理解字节对齐问题

总结:

  1. 内存大小的基本单位是字节,但cpu并不是逐字节读写内存,而是以2,4或8的倍数的字节块来读写内存。因此,就会对基本数据类型的地址做出一些限制,即它的地址必须是2,4或8的倍数,要求他们按照这个规则排列,这就是对齐。
  2. 有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit 数据。显然在读取效率上下降很多。
  3. 不同的平台对齐方式可能不同,这就导致同样的结构在不同的平台大小可能不一样,互相发送的数据可能出现错乱。

结构体和联合体的区别

联合体和结构体有相同之处,但两者有本质的不同。
结构体中,各成员有各自的内存空间;
而联合体的成员共用一块内存,这块内存的大小是各成员中最大类型所占的字节大小。

这里说的共享不是指把多个成员同时装入一个联合体变量内,而是指该联合变量可被赋予任一成员值,每次只能赋一种值,赋入新值会冲去旧值。

示例:

struct node
{
	char a;
	int b;
	double c;
};

union node2
{
	char a;
	int b;
	double c;
};
int main(void)
{
	struct node S1;
	union node2 S2;
	printf("size of S1 is %d\n", sizeof(S1));
	printf("sizeof S2 is %d\n", sizeof(S2));
	return 0;
}

在这里插入图片描述

标签:字节,int,double,联合体,内存,一些,变量,结构
来源: https://blog.csdn.net/m0_56257585/article/details/120584476