【c语言】自定义类型以及内存对齐的计算

前言

C语言的数据类型包括基本类型(内置类型)、构造类型(自定义类型)、指针类型和空类型(void)。详细介绍可以看笔者之前的写一篇文章:【c语言】数据在内存中的存储。今天我们主要来学习一下结构体、枚举和联合体。

一、知识点回顾

1.1 内置类型

char
short
int
long
long long – c99
float
double
Bool 布尔类型 – c99

1.2 自定义类型

struct
enum
union

二、 结构体的基础知识

结构是一些值的集合,这些值成为成员变量。结构的每个成员可以是不同类型的变量。

2.1结构体的声明
// 1. 正常初始化
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
}stu; //分号不能丢;同时可接变量,也可不加,另外单独初始化。
// 2. 匿名(省略标签)初始化
struct
{
	char name[20];  //名字
	int age;        //年龄
	char sex[5];    //性别
	char id[20];    //学号
}stu;               //结构体变量

2.2结构体的对齐规则
  1. 第一个成员在与结构体变量偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。(VS中默认的值为8)
  3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处;结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
2.3 为什么存在内存对齐
  1. 性能原因: 如果不做内存对齐,cpu在读取内存数据时,会增加许多耗时的动作。 而做了内存对齐后,虽然会产生一部分内存碎片,但极大提高了cpu访问内存数据的速度,属于空间换时间的做法。

  2. 平台原因(移植原因): 提高访问速度是内存对齐的原因之一,另外一个原因是某些平台(arm)不支持未内存对齐的访问。

2.4 内存对齐计算练习

题目:

int main()
{
	//练习1
	struct S1
	{
		char c1;
		int i;
		char c2;
	};
	printf("%d\n", sizeof(struct S1));

	//练习2
	struct S2
	{
		char c1;
		char c2;
		int i;
	};
	printf("%d\n", sizeof(struct S2));
   
	struct S3
	{
		double d;
		char c;
		int i;
	};
	printf("%d\n", sizeof(struct S3));
	//练习4-结构体嵌套问题
	struct S4
	{
		char c1;
		struct S3 s3;
		double d;
	};
	printf("%d\n", sizeof(struct S4));
    return 0}

答案:

这里是引用

解析:练习1和练习4;练习2和练习3自己练习。

在这里插入图片描述
在这里插入图片描述

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: C语言标准中关于结构体对齐的定义,可以用以下中文来解释: 结构体成员的对齐方式是指,为了使结构体的访问效率最高,编译器将结构体成员按照特定规则分配到内存中的位置。在分配时,编译器会将结构体成员的大小和相对位置考虑在内,以保证成员的对齐。这样可以避免在访问结构体成员时出现性能上的问题。 具体来说,C语言标准规定了以下几个对齐原则: 1. 结构体的首地址必须是其最宽基本类型成员的首地址; 2. 每个成员相对于结构体首地址的偏移量必须是该成员大小的整数倍; 3. 结构体的总大小必须是最宽基本类型成员大小的整数倍。 根据这些原则,编译器会在结构体成员之间插入填充字节,以保证成员的对齐。这样可以提高CPU读取内存的效率,减少内存访问次数和数据传输量,从而提高程序的性能。 ### 回答2: C语言标准中关于结构体对齐的定义主要包含以下几点。 首先,结构体对齐是为了保证结构体的成员在内存中的存储位置符合一定的规则,以提高计算机的访问效率。 其次,对于一个结构体变量,其起始地址必须是所有基本类型成员中的首字节地址,而非基本类型成员的起始地址可以是任意的。 接着,结构体的对齐要求由编译器根据具体实现来决定,可能受到硬件和操作系统的限制。 另外,编译器通常会在结构体的成员之间添加填充字节,以满足对齐要求。填充字节的数量取决于结构体成员的类型和前一个成员结束地址与对齐边界的差值。 最后,使用特定的编译指示(如#pragma pack(n))可以改变默认的对齐方式。这样做可能会降低对齐的效果,但可以满足某些特殊需求。 总结来说,C语言标准中关于结构体对齐的定义规定了结构体成员在内存中的存储方式。对齐规则由编译器根据实际情况来决定,并可通过编译指示进行修改。结构体对齐的目的在于提高计算机的访问效率,确保结构体成员存储位置的正确性。 ### 回答3: C语言标准中关于结构体对齐的定义主要有两个方面,分别是默认对齐方式和自定义对齐方式。 首先是默认对齐方式,默认情况下,结构体的对齐方式要求结构体的每个成员的地址都能够被结构体中最宽基本类型的大小整除,也就是说,结构体的对齐大小必须是其成员中最宽数据类型的大小或其整数倍。如果结构体中的成员包含指针类型或者更宽的基本类型,那么该结构体的大小会被这些类型的大小所影响。 其次是自定义对齐方式,在C语言标准中,可以通过在结构体定义前使用特定的编译器指令(如`#pragma pack`)来自定义结构体的对齐方式。通过设置对齐方式,可以控制结构体成员的对齐间距。例如,可以使用`#pragma pack(n)`来指定结构体的对齐方式为n字节。这种自定义对齐方式可以用于优化内存布局,减小内存开销。 总的来说,C语言标准对结构体对齐的定义要求保证结构体的成员能够按照其类型内存中正确对齐,同时允许使用自定义对齐方式以满足特定需求。对结构体对齐的规定有助于确保内存的有效利用和提高程序执行效率。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值