结构体内存对齐,位段,枚举相关问题.

这篇具有很好参考价值的文章主要介绍了结构体内存对齐,位段,枚举相关问题.。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文标签:    结构体内存对齐 结构位段问题 枚举

文章目录

目录

文章目录

一、结构体的内存对齐.

1.计算结构体大小

2.为什么存在内存对齐?

二、结构体的位段问题.

三、枚举

1.枚举类型定义

2.枚举的优点

为什么使用枚举?

总结


一、结构体的内存对齐.

1.计算结构体大小

知道了结构体的基本使用,我们可以深入探讨一个问题:计算结构体的大小.

这也是一个热门的考点:结构体内存对齐.

示例代码:

结构体内存对齐,位段,枚举相关问题.

 按照我们以往的理解, char 占一个字节, int 占四个字节, 应该是 6 个字节的大小,但是编译得到的结果是 12 个字节.由此我么引入了 结构体的内存对齐知识点.

结构体的成员在内存中存储是有自己的规则的,规则如下:

1.第一个成员在与结构体变量偏移量为 0 的地址处;
2.其他成员变量要对齐到 对齐数 的整数倍的地址处;


对齐数 = 编译器默认的一个对齐数 与 该成员大小的 较小值.( vs 默认的值为 8 .)


3.结构体总大小为对齐数中最大的那个对齐数 ( 每个成员变量都有一个对齐数 ) 的整数倍;
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处 , 结构体的整体大小就是所有最大对齐数( 含嵌套结构体的对齐数 )的整数倍.

  1. 第一句:示例代码中第一个成员 c1 .它相对于起始位置的偏移量就是 0.(也就是结构体的第一个成员就是从 0 偏移量的地址处开始存放.)此时 c1 占 1 个字节.

结构体内存对齐,位段,枚举相关问题.

2.第二句: vs 平台默认对齐数是 8,也就是用 8 和当前的 i (整型 4 个字节)比较,取较小值就是 4 .然后根据对齐规则,要将第二个变量的地址存放到对齐数 4 的整数倍的地址处,4 的整数倍地址就是 4 ;

而下一个变量 c2 占 1 个字节大小,将它与对齐数 8 比较,取较小值 1 也就是 c2 的对齐数,将 c2 从 1的整数倍处存放一个字节的内存.所以当前 c1,c2 i 一共占 9 个字节的空间

结构体内存对齐,位段,枚举相关问题.

 3.第三句:要算最终结构体的大小,就要算出每个结构体成员变量中的最大对齐数的整数倍. c1,i,c2的对齐数分别是 1,4,1 ,最大对齐数就是 4 ,所以结构体的总大小就要是 4 的整数倍,而当前结构体大小是 9 ,要使它是 4 的整数倍,就要再浪费掉 3 个字节的空间,最终就会得到结构体总大小就是 12 .

 结构体内存对齐,位段,枚举相关问题.

 例题:计算一下结构体的大小

struct s1
{
	char c1;
	int i;
	double d;
};

结构体内存对齐,位段,枚举相关问题.首先 c1 存放在 0 偏移量处, 然后 i 的对齐数是 4 ,所以要存放到 4 的整数倍处,占 4 个字节,然后变量 d 的对齐数是 8 ,当前地址也是 8 ,所以向下存放 8 的字节的空间.现在一共占 16 个字节的空间, 16 是所有变量的最大对齐数 8  的倍数,所有这个结构体大小就是 16 . 

 4.第四句:可以结合以下代码理解.

结构体内存对齐,位段,枚举相关问题.

根据第四个规则,首先将 c1 存放到 0 偏移量处,第二个结构体成员也是一个结构体,它的大小刚刚计算过了是 16 ,它如果要开始存储,就要对齐到它本身结构体成员中最大对齐数的整数倍处,它的成员最大对齐数是 8 ,所有要从 8 的整数倍地址处开始存放 16 个字节;

现在的偏移量是 24 它是 d 对齐数 8 的整数倍,再向下存放 8 个字节的空间.现在整体的总大小是 32 ,根据规则,它当前的总大小要是所有变量(包括嵌套的结构体成员变量)的最大对齐数的整数倍,如果不是则要继续浪费空间,而当前嵌套结构体的最大对齐数是 8 ,32 是 8 的整数倍,所有这个嵌套结构体的总大小就是 32 .

 结构体内存对齐,位段,枚举相关问题.

2.为什么存在内存对齐?

为什么存在内存对齐?
1.平台原因 : 不是所有的硬件平台都能访问任意地址上的任意数据的 , 某些硬件平台只能在某些地址处取特定的类型数据 , 否则抛出硬件异常.

2.性能原因 : 数据结构(尤其是栈)应该尽可能地在自然边界上对齐 , 原因在于:为了访问未对齐的内存 , 处理器需要作两次内存访问 , 而对其的内存访问仅需要一次访问.


总体来说 : 结构体内存对齐时拿空间来换取时间的做法.

二、结构体的位段问题.

位段的声明和结构是类似的 , 有两个不同:

  1. 位段的成员必须是:int,unsigned或signed int.
  2. 位段的成员名后面有一个冒号和一个数字.

示例代码:

struct S
{
	int a : 2;
	int b : 5;
	int c : 10;
	int d : 30;
};

只要在结构体成员变量的后面加上冒号和一个数字就是位段.

代码的意思是 a 成员占 2 个 bit 位,b 占 5 个 bit 位, c 占 10 个 bit 位, d 占 30 个 bit 位.那位段成员是怎么分配空间的呢?由此引入以下概念:

位段的内存分配:


1 . 位段的成员可以是int, unsigned int ,signed int或者是char(属于整型家族)类型.
2.位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的.
3.位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段  .

也就是说如果位段中的类型是 int ,它就是一个整型一个整型的来开辟空间,首先 a 开辟一个 int 的空间也就是 4 个字节,开辟 32 个 bit 的空间,而位段定义 a 只占 2bit 的空间,还剩下 30 个 bit ,而 b 的 5 个 bit 也会存放到 a 剩下的 30 个 bit 中,就还剩下 25 个 bit 位,接着 c 占 10 个 bit ,还剩 15 bit, 而 d 需要 30 个 bit ,而剩下的字节不够存放 d ,就会再开辟一个 4 字节的空间.所有就可以求出这个位段的大小是 8. 

结构体内存对齐,位段,枚举相关问题.

 在上面的代码中, c 成员用完 10bit 的后还剩下的 15 bit 不够存放 d 的 30bit ,所以要再开辟 4 个字节.但是那剩下的 15 bit是 d 用了再开辟 4 字节再用 15bit ,还是不用剩下的 15bit 只在新开辟的 4字节中存放?

这些因素在C语言中是不确定的,是不跨平台的,在不同的平台上可能实现是不一样的,所以要使用位段要先研究当前平台的规定,写出针对不同平台的代码.

位段的跨平台问题:
1.int位段被当成有符号数还是无符号数是不确定的.
2.位段中最大位的数目不能确定(16位机器最大16,32机器最大32).
3.位段中的成员在内存中从左向右分配,还是从右向左标准未定义.
4.当一个结构包含两个位段,第二个位段成员比较大,无法容纳第一个位段剩余的位时,是舍弃位重新开辟还是利用,也是不确定的.

结论:位段和结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题.

三、枚举

1.枚举类型定义

枚举:

 结构体内存对齐,位段,枚举相关问题.

1.虽然枚举类型定义和结构体的类型定义很相似,但是他们俩是不一样的.

结构体:

结构体内存对齐,位段,枚举相关问题.

2. 既然知道枚举类型是常量,那常量必然是有值的,我们可以将它的值打印出来.

打印枚举常量的值:

结构体内存对齐,位段,枚举相关问题.

 结论:这些常量的值是依次递增 1 的方式往下走.(默认是增长1).

3.既然是常量但是我们不能对它进行赋值,假设对枚举类型的常量赋值一个 int ,编译器就会报错.

因为枚举是一个类型,我们不能将类型赋值为另一个类型.

结构体内存对齐,位段,枚举相关问题.

 4.如果在枚举类型中给它的常量赋值(这里是在给它枚举类型中的常量赋值),它的下一个常量的值仍然是在当前常量的值的基础上递增 1.

结构体内存对齐,位段,枚举相关问题.

2.枚举的优点

为什么使用枚举?

我们可以使用 #define 定义常量,为什么非要使用枚举? 枚举的优点:

1.增加代码的可读性和可维护性.
2.和#define定义的标识符比较枚举有类型检查,更加严谨.
3.防止命名污染.
4.便于调试.
5,使用方便,一次可以定义多个常量.


总结

  • 结构体内存对齐
  • 位段问题
  • 枚举

抽空水的文章,看到这了给个三连呗.如有不足,还望指出.结构体内存对齐,位段,枚举相关问题.文章来源地址https://www.toymoban.com/news/detail-402999.html

到了这里,关于结构体内存对齐,位段,枚举相关问题.的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • C语言自定义类型 — 结构体、位段、枚举、联合

    C语言自定义类型 — 结构体、位段、枚举、联合

    本期主要对通讯录三篇博客文章进行补充 通讯录文章:通讯录系列文章 对 结构体 进行详细介绍,其次讲解位段、枚举、联合体 在C语言中,结构是一种用户自定义的数据类型,它可以由不同类型的数据成员组成,每个数据成员可以是不同的数据类型。 结构的作用是将多个不

    2024年02月14日
    浏览(10)
  • 【C语言:自定义类型(结构体、位段、共用体、枚举)】

    【C语言:自定义类型(结构体、位段、共用体、枚举)】

    C语言已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类型还是不够的, 假设我想描述学生,描述⼀本书,这时单⼀的内置类型是不⾏的。描述⼀个学生需要名字、年龄、学号、身高、体重等;描述⼀本书需要作者、出版社、定价等。C语言为

    2024年02月05日
    浏览(11)
  • C/C++之自定义类型(结构体,位段,联合体,枚举)详解

    C/C++之自定义类型(结构体,位段,联合体,枚举)详解

    专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶 C语言刷题 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 个人主页:点我进入主页   1.前言 2.结构体 2.1结构体声明 2.2结构体初始化 2.3结构体的自引用 2,4结构体的内存

    2024年02月08日
    浏览(11)
  • 一篇博客学会系列(2)—— C语言中的自定义类型 :结构体、位段、枚举、联合体

    一篇博客学会系列(2)—— C语言中的自定义类型 :结构体、位段、枚举、联合体

    目录  前言 1、结构体 1.1、结构体类型的声明 1.2、特殊的结构体类型声明 1.3、结构体的自引用 1.4、结构体的定义和初始化 1.5、结构体成员变量的调用 1.6、结构体内存对齐  1.6.1、offsetof 1.6.2、结构体大小的计算 1.6.3、为什么存在内存对齐?  1.7、 修改默认对齐数 1.8、结构

    2024年02月08日
    浏览(13)
  • 结构体内存对齐(面试重点)

    结构体内存对齐(面试重点)

    1.1 结构体的概念 结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 1.1.1 结构的声明 例如描述⼀个学⽣: 1.1.2 结构体变量的创建和初始化 运行结果如图: 1.2 结构的特殊声明 在声明结构的时候,可以不完全的声明。 比如: 上⾯的两个结构

    2024年01月25日
    浏览(10)
  • C语言之结构体内存对齐与内存的简单理解

    C语言之结构体内存对齐与内存的简单理解

    文章目录 内存单元的理解 结构体中内存对齐的规则 为什么会存在内存对齐 首先先要介绍一下C语言中一些常见的存储单元     bit       存放一个二进制位     Byte   1Byte = 8 bit     KB     1KB   = 1024 Byte     MB     1MB   = 1024 KB     GB     1GB   = 1024 MB     TB 

    2023年04月26日
    浏览(10)
  • C语言——结构体类型(二)【结构体内存对齐,结构体数组】

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

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

    2024年01月24日
    浏览(9)
  • 【C语言】位段枚举联合

    【C语言】位段枚举联合

    鹅,鹅,鹅,曲项向天歌。白毛浮绿水,红掌拨清波。 — 唐代·骆宾王《咏鹅》 这篇博客我们会详细介绍位段,以及枚举类型和联合类型 位段的声明和结构是类似的,有两个不同: 1.位段的成员必须是 int、unsigned int 或signed int 以及 char或unsigned char。 2.位段的成员名后边有一

    2024年02月15日
    浏览(10)
  • 【刷题笔记】结构体内存对齐举例+统计回文

    【刷题笔记】结构体内存对齐举例+统计回文

    题目: 下面存在两个结构体: 在#pragma pack(4)和#pragma pack(8)的情况下, 结构体的大小 分别是? 分析:         C/C++中结构体计算其大小涉及到内存对齐问题。(详细可以参考我这篇博客:结构体、位段、共用体、枚举相关内存知识(c语言)_柒海啦的博客-CSDN博客)         这

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

    C语言如何计算结构体大小(结构体的内存对齐)

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

    2024年02月16日
    浏览(12)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包