今天讲讲结构体存储问题

首先,结构体简单说是对不同类型的封装,一开始我们可能会想结构体在内存中的存储的大小是直接元素的和

例如

我们可能会觉得是 结构体大小=int(4个字节)+ short(2个字节)+char(1个字节) = 7个字节

其实这样想是错误的

结构体的存储默认是向元素里最大的数据类型对齐的

上面的话是什么意思呢,还是以上个例子为例,

也就是这个结构体中,以int(4个字节)对齐,也可以理解做就是一行有int(4个字节)那么大

假如一个小格子为一个字节,先把int放入内存中,也就是占了4个字节

然后放入short(2个字节)

最后是char(1个字节)

这样我们就把所有的元素都放进去了,然后因为是以最大字节对齐

所以在内存为了要放下这三个元素,是不是开辟了两个int(4个字节)也就是两行4个字节才能装得下这些元素

所以最终这个结构体struct的内存 = 4+4 = 8(字节)

我们用程序判断一下

结果和我们计算的一样

那如果我们把两个元素调换一下呢,结果还会一样吗,这次我们先用程序验证一下

咦,结果为12字节,这是为什么呢?

这次我们还是画图了解一下

与上次不一样,这次我们得先放short(2个字节)

接着放int(4个字节)

有人可能会觉得是一下的排放方法,把一个int(4个字节)分做两半,一半放下面两个空格,一般放上面两格,再放char(1个字节),如下图

可是,如果是这样的话,那结构体所占的大小也是应该和上面例子一样8字节,怎么会是12字节呢,问题究竟出在哪?

问题其实出在了我们把int分做两半了,我们可以这样想,int是个整体,我们能把它拆分吗,就好比一个人,让他一半来这里,

另一半去那边,明显是不能的嘛,一个人是个单独的整体,int也是一样,所以正确做法是在建一行存放int

那重新从第二部开始,把一个int(4个字节)放入

再放char(1个字节)

所以最终这个结构体struct的内存 = 4+4+4= 12(字节)

如果想要实现我们一开始想法的4+2+1 = 7(字节),我们得加入

附上各个数据类型所占字节数,大家可以随意搭配试试结构体的内存所占大小,练习一下

c语言学习笔记之结构体存储的更多相关文章

  1. C语言学习笔记--枚举&结构体

    枚举 枚举是一种用户定义的数据类型,它用关键字enum以如下语法格式来声明: enum 枚举类型名字 {名字0,名字1,...,名字n}: 枚举类型名字通常并不真的使用,要用的是大括号里面的名字,因为 ...

  2. C语言学习笔记10-结构体、枚举、联合体

    C语言学习笔记10-结构体.枚举.联合体    待传

  3. C#学习笔记之结构体

    1.概述 结构是一种与类相似的数据类型,不过它较类更为轻量,一般适用于表示类似Point.Rectangle.Color的对象.基本上结构能办到的类全都能办到,但在某些情况下使用结构更为合适,后面会有 ...

  4. 《PHP7底层设计与源码实现》学习笔记2——结构体对齐

    书里给了一段代码,假如有个结构体如下: struct test {     char a;     int b;     long c;     void* d;     int e;     cha ...

  5. contiki学习笔记---process结构体

    process,字面意义,进程,看看它的结构 struct process { struct process *next; #if PROCESS_CONF_NO_PROCESS_NAMES #def ...

  6. 【C#学习笔记】结构体使用

    using System; namespace ConsoleApplication { struct _st { public string name; public int age; } clas ...

  7. Go语言学习笔记十: 结构体

    Go语言学习笔记十: 结构体 Go语言的结构体语法和C语言类似.而结构体这个概念就类似高级语言Java中的类. 结构体定义 结构体有两个关键字type和struct,中间夹着一个结构体名称.大括号里面 ...

  8. GO语言学习笔记(一)

    GO语言学习笔记 1.数组切片slice:可动态增长的数组 2.错误处理流程关键字:defer panic recover 3.变量的初始化:以下效果一样 `var a int = 10` `var ...

  9. Go学习笔记07-结构体与方法

    Go学习笔记07-结构体与方法 Go语言 面向对象 结构的定义与创建 面向对象 Go语言只支持封装,不支持继承和多态. Go语言中只有struct,即结构体:没有class. 结构的定义与创建 pac ...

随机推荐

  1. 数据可视化基础专题(十四):pyecharts 基础(一)简单上手

    1.引言 文档位于 https://pyecharts.org/#/zh-cn/intro 示例位于 https://gallery.pyecharts.org/#/README echarts 官网 ...

  2. pytest框架的安装与使用

    pytest框架的安装与使用 一,pytest了解 pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高. ...

  3. 基于SSM框架的简单问答社区

    前言:学习了Spring.SpringMVC.MyBatis框架后,开发了一套简单的问答社区,前端采用Bootstrap开发框架. 版本信息 IDEA:2020.1.2 JDK:14.0.1 Mave ...

  4. Go的100天之旅-06数组和Slice

    目录 数组 Slice 数组 Go的数组和其它语言基本上一样,是长度固定的特定类型元素组成的序列,这基本上是所有语言数组的特性.和其它语言相比差异主要在声明和初始化的写法上,下面是简单声明一个数组: ...

  5. IDEA命令行缩短器助你解决此问题:Command line is too long. Shorten command line...

    生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...

  6. EF中延迟加载的那些事

    延迟加载又称懒加载,通俗一点就是关联了一个对象,不用的时候不去查这个对象,当调用的时候再组织sql去查出这个对象的相关内容. 一.在使用EF时,我们会发现借助于框架生成的实体类中的的导航属性通常是标记 ...

  7. MultipartFile

    转发:原博客 一.MultipartFile是什么? MultipartFile是一个接口并继承了InputStreamSource接口.MockMultipartFile.CommonsMultip ...

  8. HashMap 中 get,put 方法源码实现

    HashMap 是Map接口的一个实现类 1.线程 HashMap 非线程安全2.数据存储结构 hashMap采用Entity数组来存储 key-value对,每一个键值对组成一个Entity,键值对 ...

  9. 题解 洛谷 P4546 【[THUWC2017]在美妙的数学王国中畅游】

    首先发现有连边和删边的操作,所以我们肯定要用\(LCT\)来进行维护. 接下来考虑如何进行\(LCT\)上的信息合并. \(f=1\),则函数为\(f(x)=sin(ax+b)\) \(f=2\),则 ...

  10. 小书MybatisPlus第6篇-主键生成策略精讲

    本文为mybatis系列文档的第6篇,前5篇请访问下面的网址. 小书MybatisPlus第1篇-整合SpringBoot快速开始增删改查 小书MybatisPlus第2篇-条件构造器的应用及总结 小 ...