【C语言高阶篇】结构体 —— 什么是内存对齐?

这篇具有很好参考价值的文章主要介绍了【C语言高阶篇】结构体 —— 什么是内存对齐?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++

🎬 鸽芷咕:个人主页

 🔥 个人专栏:《C语言初阶篇》 《C语言进阶篇》
⛺️生活的理想,就是为了理想的生活!

前言

   🌈hello! 各位宝子们大家好啊,今天给大家带来的是结构体的内存对齐这部分知识,可以说是干货满满啦!
   ⛳️在我们C语言的面试题中,结构体最容易考的就是内存对齐这部分知识点了。今天就给大家详细讲解一下!
   📚本期文章收录在《C语言高阶篇》,大家有兴趣可以看看呐
  ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

💬 结构体内存对齐

  ⛳️大家可能会想结构体内存对齐这部分知识是干嘛用的呢?不要急,接下来就给大家 演示一下这部分内容到底能干嘛?
📚 代码演示:

#include<stdio.h>
struct S1
{
	char c1;//1
	int i;//4
	char c2;//1
};
struct S2
{
	int i;//4
	char c1;//1
	char c2;//1
};

int main()
{
	printf("%d", sizeof(struct S1));
	printf("%d", sizeof(struct S2));
	return 0;
}

  🌈在我们没学结构体内存对齐这部分知识前,我们肯定是按照以前计算内存大小的办法计算的。

  • printf(“%d”, sizeof(struct S1)); 计算类型大小而 S1 里面的类型有:

    • int char char 这三个加起来的大小不就是 4+1+1
    • 6 个字节嘛!结构体 S2S1
    • 包含的类型都是一样的那也就是 6 个字节了,可真的是这样吗?

📑 代码结果:
【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++

📝 诶这里S1的类型大小居然是 12,S2的类型大小居然是 8

  • 啊为什么会这样啊?这里就要用到结构体的内存对齐这个知识点了!
💭 ofsetof 宏的应用

📑 ofsetof是什么意思呢?

  • 它是用来计算结构体成员相较于起始位置的偏移量!
  • 在使用之前需要引入头文件#include <stddef.h>
    【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++

📖 问题引入:那么S1结构体每个元素的偏移量是多少?

  • 我们来用offsetof库函数来看一下

📚 代码演示:

#include <stdio.h>
#include <stddef.h>
struct S1
{
	char c1;
	int i;
	char c2;
};
int main()
{
	printf("%d\n", offsetof(struct S1, c1));
	printf("%d\n", offsetof(struct S1, i));
	printf("%d\n", offsetof(struct S1, c2));
	return 0;
}

📑 代码结果:

【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++

⛳️ 这里我们就可以看到结构体里面每个元素,相较于起始位置的偏移量

  • 🌱 那么我们就可以大概画出,结构体S1大概在内存中的存储位置
  • 🌱 假设我们结构体是从红箭头的位置开始存储的!
    【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++

⛳️ 这里哦!是不是就很直观呢?而画出来的结构体s1所占字节

  • 🌱 刚好是8个字节和我们前面计算的一模一样!
  • 🌱 这是为什么呢?
  • 🌱 这是因为结构体在存储是是有一定规则的
  • 🌱 下面就给大家讲讲结构体的内存对齐规则
✅ 结构体的内存对齐规则一

⛳️ 第一个成员在与结构体变量偏移量为0的地址处。

  • 🌱 也就是只要是在结构体里面的第一个成员。
  • 🌱 他都存储在结构体变量偏移量为0的地址处。

📑图片展示:
【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++

✅ 结构体的内存对齐规则二

⛳️ 其他成员变量要对齐到某个数字 (对齐数) 的整数倍的地址处。

  • 🌱 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
    • VS中默认的值为8
    • Linux中没有默认对齐数,对齐数就是成员自身的大小

📜说明:

⛳️ 这是什么意思呢?拿上一个结构体参考

  • 🌱 假如我们第一个成员类型为1 ,第二个为4
  • 🌱 而VS中默认的值为 848
  • 🌱 取他们之间的较小值4对齐数
  • 🌱所以第二个成员应该放在 (对齐数) 4的整数倍的地址处。

📑图片展示:
【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++

✅ 结构体的内存对齐规则三

⛳️ 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

  • 🌱 也还是拿上面的结构体举例,前两个成员我们已经确定内存了
  • 🌱 而第三个是 char 一个字节,那么岂不是放上一个字节就对啦!
  • 🌱 那么这就和我们计算的12个字节完全不一样了!

📚 其实最后一个成员就是这样存储的,但是由于:

  • 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  • 而这个结构体 3 个成员类型分别是 1 4 1,那么
  • 结构体总大小就是 4的倍数 12 所以最后 3个字节也会算进去

【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++

✅ 结构体的内存对齐规则四

⛳️ 在讲规则四之前我们需要计算这结构体的存储字节以及:

  • 结构体每个元素的对齐数是多少?

📚 代码演示:

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

  ⛳️相信只要把前三个规则掌握了那么计算这个结构体每个成员 对奇数 其实很简单!我们来一起算一下

  • double的存储字节是8 VS的默认对齐数是8
  • 那么区最小值也是 8
  • char的存储字节是1 VS的默认字节是8
  • 那么取最小值就是 1
  • int 的存储字节是4 VS的默认字节是8
  • 那么取最小值就是 4

🔥 而结构体的大小数所有成员最大的整数倍,那么就是8的倍数!知道这些算结构体的大小还不简单

📑图片展示:
【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++
而如果嵌套了结构体的情况该怎么计算呢?

  ⛳️ 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

📚 代码演示:

#include <stdio.h>
#include <stddef.h>
struct S3
{
	double d;
	char c;
	int i;
};

struct S4
{
	char c1;
	struct S3 s3;
	double d;
};

int main()
{
	printf("%d\n", sizeof(struct S4));
	return 0;
}

⛳️ 这时候就需要结构体的内存对齐规则四了:

  • 🌱 当嵌套了结构体时,嵌套的结构体对齐到自己的最大对齐数的整数倍处
  • 🌱 结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
    🌱 我们来带着大家算一下

US3的最大对齐数是 8 ,所以Ustruct S3 s3;就应该对齐到自己最大的对齐数的整数倍

  • 而结构体s3的大小是 16 个字节所以这里就会申请 16 个字节存放s3
  • 存储 s3 ,而double也是8个字节所以下一个对齐数也是 8 的倍数
  • 那么这样不就好计算起来了!

📑图片展示:
【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++

📜 所以这里结构体S4的大小就是32个字节大家可以运行看一下呢?看看看和博主算的对不对!

💬 结构体内存对齐练习

  ⛳️好了上面的四个规则我们学完了就可以过来做一下练习来巩固一下自己所学习的知识 ,俗话说学习学习,光学不练有什么用呢?

💭 练习一

⛳️在VS2013下,默认对齐数为8字节,这个结构体所占的空间大小是( )字节

typedef struct{
  int a;
  char b;
  short c;
  short d;
}AA_t;
💭 练习二

⛳️在VS2013下,默认对齐数为8字节,这个结构体所占的空间大小是( )字节

struct tagTest1
  {
    short a;
    char d; 
    long b;   
    long c;   
  };
  struct tagTest2
  {
    long b;   
    short c;
    char d;
    long a;   
  };
  struct tagTest3
  {
    short c;
    long b;
    char d;   
    long a;   
  };
  struct tagTest1 stT1;
  struct tagTest2 stT2;
  struct tagTest3 stT3;

  int main()
  {
  		printf("%d %d %d", 
			  sizeof(stT1), 
			  sizeof(stT2), 
			  sizeof(stT3));
  		return 0;
 }
💭 练习三

⛳️在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是( )

struct A
{
	int a;
	short b;
	int c;
	char d;
};

struct B
{
	int a;
	short b;
	char c;
	int d;
};

总结

✅ 归纳:
好了以上就是关于结构体的内存对齐的全部知识点了,学会这些计算结构体的大小还不是手到擒来呢
  结构体的内存对齐规则一
  结构体的内存对齐规则二
  结构体的内存对齐规则三
  结构体的内存对齐规则四
  知识点练习
☁️ 把本章的内容全部掌握,那么恭喜你又距离编程大牛又进了一步!
看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注

💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。
【C语言高阶篇】结构体 —— 什么是内存对齐?,《C语言进阶篇》,c语言,面试,开发语言,c++文章来源地址https://www.toymoban.com/news/detail-626978.html

到了这里,关于【C语言高阶篇】结构体 —— 什么是内存对齐?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言——结构体类型(二)【结构体内存对齐,结构体数组】

    📝前言: 上一讲结构体类型(一)中,我们讲述了有关 结构体定义,创建,初始化和引用 的内容,这一讲,我们进一步学习结构体的相关知识: 1,结构体内存对齐 2,结构体数组 🎬个人简介:努力学习ing 📋个人专栏:C语言入门基础 🎀CSDN主页 愚润求学 🌄每日鸡汤:

    2024年01月24日
    浏览(54)
  • C语言如何计算结构体大小(结构体的内存对齐)

    结构体的内存对齐是有关结构体内容的很重要一个知识点,主要考察方式是计算结构体的字节大小。 当我们对计算结构体一无所知,我们不妨自己思索如何计算,是不是直接计算结构体成员变量占用内存的大小呢? 那我们先举个例子  观察发现结构体的大小计算跟我们想的

    2024年02月16日
    浏览(32)
  • 结构体占用内存大小如何确定?-->结构体字节对齐 | C语言

    目录 一、什么是结构体 二、为什么需要结构体 三、结构体的字节对齐 3.1、示例1 3.2、示例2 3.3、示例3  3.4、示例4 3.5、示例5 四、结构体字节对齐总结         结构体是将不同类型的数据按照一定的功能需 求进行整体封装,封装的数据类型与大小均可以由用户指定。 结

    2024年01月17日
    浏览(32)
  • 【C/C++】结构体内存对齐 ----- 面试必考(超详细解析,小白一看就懂!!!)

    【C/C++】结构体内存对齐 ----- 面试必考(超详细解析,小白一看就懂!!!),C++,C语言超详细解析,c语言,c++,面试,linux,算法

    2024年03月09日
    浏览(30)
  • 【C语言13】结构体的声明,定义与结构体的内存对齐

    通俗的说,结构体就是一个类的集合,如同整形数组是整形数字的集合体,结构体也是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 如果我们要表达一本书,那么这本书的元素有什么呢,书的名字,书的作者,书的创作日期~,而c语言中内置

    2024年02月13日
    浏览(57)
  • 深入了解C语言中的结构体类型与内存对齐

    在C语言中,结构体是一种 自定义的数据类型 , 它允许我们将不同类型的数据组合在一起,形成一个新的数据类型 。结构体的使用为我们解决了一些复杂数据的表示和处理问题,不仅限于单单的整型或者字符。本文将深入探讨结构体类型、结构体变量的创建和初始化,并详

    2024年04月11日
    浏览(30)
  • C语言结构体字节对齐(内存对齐)之#pragma pack和__attribute__((packed)的使用

    在不使用 #pragma pack 和 __attribute__((packed) 等选项来自定义字节对齐大小的情况下,关于正常字节对齐的描述,可参考博文: C/C++计算类/结构体和联合体(union)所占内存大小(内存对齐问题)_联合体占用的内存空间_SOC罗三炮的博客-CSDN博客 同学可以尝试将char f 注释,最后将

    2024年02月12日
    浏览(30)
  • 【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参

    本小节,我们学习结构的内存对齐,理解其对齐规则,内存对齐包含结构体的计算,使用宏 offsetof 计算偏移量,为什么要存在内存对齐?最后了解结构体的传参文章干货满满!学习起来吧😃! 结构体内存对齐指的是 结构体中各成员变量在内存中的存储位置按照一定规则对齐

    2024年02月04日
    浏览(35)
  • C语言自定义类型:结构体的使用及其内存对齐【超详细建议点赞收藏】

    结构是一些值的集合,这些值称为 成员变量 。 结构的每个成员可以是不同类型的变量 。 注意 : 成员列表可以是不同类型的变量; 成员后一定要有分号; 花括号后也有一个分号。 例如描述一个学生: 注意:上述代码没有创建变量,也没有初始化, 只是声明了一个结构体类

    2024年03月13日
    浏览(38)
  • 结构体(结构体内存对齐)+位段+枚举

    本期带大家一起来学习一下 结构体知识+位段知识+枚举知识 🌈🌈🌈 1.1 结构体的声明✈️✈️ 1.1.1 结构体的完全声明🚀 结构体是一种自定义的类型,🔦🔦 结构体是将不同类型的数据按照一定的功能需求进行整体封装 ,封装的数据类型与大小均可以由用户指定。 那么又

    2023年04月10日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包