结构体基础回顾

本文详细介绍了结构体的声明方法,特殊声明,内存对齐规则及其原因,包括平台兼容性和性能优化,以及如何使用#pragmapack修改默认对齐数。
摘要由CSDN通过智能技术生成

目录

结构体的声明及使用

结构体的特殊声明

结构体内存对齐

1.对齐规则

2.为什么会对齐

平台原因

性能原因

3.修改默认对齐数


结构体的声明及使用

结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。例如要描述一个学生,需要使用年龄,成绩,名字等变量,这时声明一个结构体如下:

struct stu     //struct是结构体关键字
{
	int age;
	char name[20];
	int grade;
};

这个结构体的类型就是struct stu,要用该结构体声明变量时,要使用struct stu声明。

要访问结构体中的成员,需使用'.'操作符

int main()
{
	struct stu s;
	s.age = 12;
	return 0;
}

或者这么写

int main()
{
	struct stu s;
	struct stu* p = &s;
	p->age = 12;
	return 0;
}

结构体的特殊声明

结构体使用时也可以匿名使用。如

struct     //struct是结构体关键字
{
	int age;
	char name[20];
	int grade;
}s;

这样也可以声明一个结构体变量。

匿名的结构体类型,如果没有对结构体类型重命名的话,基本上只能使⽤⼀次。

struct     //struct是结构体关键字
{
	int age;
	char name[20];
	int grade;
}*p;
struct     //struct是结构体关键字
{
	int age;
	char name[20];
	int grade;
}s;
p = &s;

这段代码实际上是非法的 ,编译器会处理成两个不同的类型。

结构体内存对齐

1.对齐规则

结构体在内存中存储时有一套对齐规则。

1. 结构体中的第一个成员对齐到和结构体变量起始位置偏移量为0的地方。

2.其他成员要对齐到某个数字(对齐数)的整数倍处。

对齐数 = 该成员类型的大小和编译器默认对齐数之间较小的值。

vs默认对齐数是8,Linux中gcc没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩。

3.结构体最终的大小必须是成员中最大对齐数(每个成员都有对齐数,最大对齐数就是这些对齐数中最大的)的整数倍。

4.如果有嵌套结构体,嵌套的结构体对齐到自己的成员中最大对齐数的整数倍,整个结构体大小就是所有成员变量(包括嵌套的结构体)中最大对齐数的整数倍。

struct S
{
  double d;
  char c;
  int i;
};

以该结构体为例分析。

第一个成员d的类型大小为8,vs默认对齐数是8,因此对齐数取8

然后是c,类型大小为1,vs默认对齐数为8,取小值则为1,则对齐数为1,而偏移量为8处是1的倍数。

最后是i,类型大小为4,小于vs默认对齐数8,因此对齐数取4,那么i必须从偏移量为4的整数倍的地方开始存放,就应该从12处存放

这就是这个结构体在内存中的存储情况,可以看到他的大小为16个字节。

2.为什么会对齐

平台原因

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

性能原因

数据结构(尤其是栈)应该尽可能地在⾃然边界上对⻬。原因在于,为了访问未对⻬的内存,处理器需要作两次内存访问;⽽对⻬的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节,假设⼀个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果不是8的倍数会导致访问效率变低,因为8字节内容可能被存放在不同的两个8字节内存块中。

结构体对齐规则是拿时间换空间的做法。

3.修改默认对齐数

可以使用#pragma这个预处理指令。

#pragma pack(1)

将默认对齐数修改为1,若要恢复默认对齐数,再次使用

#pragma pack()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值