今天讲讲结构体存储问题

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

例如

我们可能会觉得是 结构体大小=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. Python面试【315+道题】

    第一部分 Python基础篇(80题) 为什么学习Python? 通过什么途径学习的Python? Python和Java.PHP.C.C#.C++等其他语言的对比? 简述解释型和编译型编程语言? P ...

  2. [C#]正则表达式的基本用法

    C#正则表达式的基本用法 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串.将匹配的子串替换或者从某个串中取出符合某个 ...

  3. jpa随手笔记

    jpa注解1.设置Pojo为实体@Entity //标识这个pojo是一个jpa实体 2.设置表名@Table(name = "users") //指定表名为users 3.设置主 ...

  4. MVC + EFCore 项目实战 - 数仓管理系统5 – 菜单配置及里程碑划分

    上次课程我们完成了需求的梳理. 我们根据梳理的需求把菜单配好,另外我们把项目里程碑也配置在系统中,开发和管理都在系统中,形成无文档化管理. 一.菜单配置 根据我们的归纳图,我们先将菜单配置好. 我们遵 ...

  5. 009.Nginx缓存及配置

    一 浏览器缓存 1.1 缓存概述 缓存对于Web至关重要,尤其对于大型高负载Web站点.Nginx缓存可作为性能优化的一个重要手段,可以极大减轻后端服务器的负载.通常对于静态资源,即较少经常更新的资源 ...

  6. Ethical Hacking - NETWORK PENETRATION TESTING(9)

    WEP Cracking Packet Injection What if the AP was idle, or had no clients associated with it? In this ...

  7. p40_数据交换方式

    一.为什么要数据交换 数据链路发展史: 二.数据交换方式 电路交换 报文交换 分组交换[数据报方式,虚电路方式] 三.电路交换 eg:电话网络(特点:**独占资源,**即使两个人不说话,链接也不会被别 ...

  8. Codeforces1379-题解

    很久以前,申蛤申请了一个cf号叫 wzxakioi 有一天,戌蛤带着申蛤用这个账号打了一场div3,然后它的rating超过了shzr 之后申蛤又用这个号打了三场div2,于是  CF1379C 题意 ...

  9. 根据 Promise/A+ 和 ES6 规范,实现 Promise(附详细测试)

    Promise 源码 https://github.com/lfp1024/promise promise-a-plus const PENDING = 'PENDING' const REJECTE ...

  10. Java中解决继承和接口默认方法冲突

    1)超类优先.如果超类提供了一个具体方法,同名而且有相同参数类型发默认方法会被忽略. 2)接口冲突.如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方 ...