计算机系统基础笔记(5)——数据

前言

博主来发文章了 再不发这个月笔记数要做0了><
今天的内容比较少~之前的笔记等我五一补上@_@

数组

一、 一维数组

数组的存储和访问

  • 基本语法
    T A[L];
    • 元素数据类型为T ,长度为L
  • 内存中连续分配 L * sizeof(T) 个字节
    内存都是连续存储的 如图
    在这里插入图片描述
    基本的编址单元是字节,一个指针变量与处理器(32位还是64位)有关,与数据类型无关

下面是例子
typedef就是给数据类型起个别名 这里 zip_dig就是int的别名
在这里插入图片描述
在这里插入图片描述
对应的内存分配如图 方格下面对应的是地址 地址的差值与数据类型有关


数组的访问

  • 基本语法
    T A[L];
  • A可以被看做是第0个元素的指针,类型为 T *
    如图 指针的内容是地址 地址之间的差值取决于数据类型
    在这里插入图片描述
    其中数据类型判断要在内存中取几个字节的数据(也就是步长是多少),x代表起始地址

下面是例子

这是c代码 实现了数组的访问

在这里插入图片描述

下面是他的汇编代码

在这里插入图片描述
注意 最后一行才是真正的代码

这行代码实现了将目标数据地址存储在了32位的%eax存储器里(也是32位中的目标存储器)

目标数据存储器为 %rdi + 4%rsi
其中4为步长
%rdi存储了起始地址
%rsi存储了数组索引

数组的循环遍历

原理就是上面的组合
我们直接上图

黄色的是实现数组循环的c代码

在这里插入图片描述
在这里插入图片描述
绿色的是汇编代码

在L4循环中第一行实现了数组元素加1
(%rdi,%rax,4)表示一个数组元素
其中%rdi为首地址 %rax表示数组索引

L4循环的第二行实现了索引的加1

L3循环的第一行实现了索引与4的比较 以确保索引符合循环条件

L3循环的第二行实现了跳转(符合条件时进入循环)

rep为空操作指令 确保跳转指令不相连

二、多维数组(嵌套)

1.数组的分配

  • 基本语法
    T A[R][C];

    • R 行,C 列
    • T类型的元素需要 K 个字节
  • 数组大小:R * C * K bytes

  • 排列方式:行优先(就是一行的数据是连在一起的,故循环先写行的代码速度更快^^)

  • 数据分配的形象表示如图在这里插入图片描述


下面是例子

在这里插入图片描述

不同颜色表示不同行

2.访问嵌套数组的行

  • A[i]是一个包含C个元素的数组
  • 元素类型为T,需要K个字节
  • 起始地址为 A + i*(C*K)
    (首地址+(每行个数(列数) * 步长 *行数索引))

下面是例子
黄色为实现访问嵌套数组的行的c代码
在这里插入图片描述
汇编代码如下
在这里插入图片描述
访问实现:pgh(起始地址) + (20*index)(索引乘以步长乘以列数)

  • question:直接乘以五的话调用乘法 乘以4的话调用移位 两个的调用速度不同

故优先实现如下计算
pgh + 4*(index + 4*index)

3.嵌套数组元素的访问

  • A[i][j]数据类型为 T 的数组元素,需要 K 个字节
  • 地址:A + i(CK) + jK = A + (i*C + j)*K
  • 也就是首地址先索引到目标行(如上条) 再右移到目标列
    下面是形象的示例

在这里插入图片描述


下面是例子
黄色是实现了嵌套数组元素访问的C代码
在这里插入图片描述
在这里插入图片描述
这是汇编代码 第一二行实现了
行数索引列数(每行元素个数)+列数索引
第三行实现了首地址 加 步长 * (行数索引
列数(每行元素个数)+列数索引)

地址计算方法如下: pgh + 4*((index+4*index)+dig)

三、多层数组

1.多层数组的存储

  • 每个元素是一个指针:8字节
  • 每个指针指向一个int型数组
    在这里插入图片描述
    如图二 左边表示了指针元素的地址 右边表示了其表示的数组的地址和存储的元素

在这里插入图片描述

2.多层数组的元素访问

  • Mem[Mem[univ+8index]+4digit]
  • 需要进行两次存储器访问
    • 首先获得行数组的地址
    • 然后访问(行)数组中的元素

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

  • 多维数组和多层数组的比较: 从C语法上看相似,但是寻址方式不同(因为存储方式不同)
    在这里插入图片描述

四、数组长度

1.固定维度

  • 在编译时N的大小已经确定
    -在这里插入图片描述
    在这里插入图片描述
    所以这里直接使用立即数寻址就可以了

2.可变维度,显示索引

传统的实现动态数组的方法
下面是n*n矩阵的示例

在这里插入图片描述
在这里插入图片描述
这里必须使用乘法 因为索引不固定

3.优化定长矩阵的访问

在这里插入图片描述
在汇编代码中 我们避免直接访问单个元素的地址 而是采用了每次增加 4N
这是初始地址 ajp = a + 4
j
ajp += 4*N

结构体

一、结构体的存储

  • 结构体被看做是一块连续的内存区域
  • 成员在内存中组织的顺序和声明的顺序一致
  • 编译器决定了结构体的大小和每个成员在内存中的位置
    在这里插入图片描述
    下面是rec结构体的存储示意图
    在这里插入图片描述

二、获得结构体的指针

  • 计算数组成员的指针 r->a[idx](黄色图)
    • 每个结构体成员的偏移量在编译期决定
    • 汇编代码(绿色图)计算的结果为r + 4*idx

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

三、链表遍历

函数代码如图
其实就是循环,给数组中的每个元素赋值val 大家看看就行
在这里插入图片描述
在这里插入图片描述
主要是在存储的时候会按下图存储(结构体类型的话是 8个字节)前面是数组int类型元素 后面是两个结构体元素
在这里插入图片描述
汇编指令用的跳转
在这里插入图片描述

四、结构体对齐(重点)

1.结构体对齐举例

这是一个结构体
在这里插入图片描述

  • 数据未对齐时如图
    在这里插入图片描述

  • 数据对齐规则

    • 若基本数据类型需要K个字节 则地址必须是K的整数倍(即首地址 + K * i ,i为整数)
      如图
      在这里插入图片描述

第一块黄色是char类型 只需要一个字节

第一个灰色部分是补充的字节 为了使地址满足int类型(4个字节)的要求(使 地址 = p + 4*1)

绿色部分是int类型的数据 数组含两个元素 故占8个字节

第二个灰色部分继续补充 使得地址满足double类型(8个字节)的要求

2.使用结构体对齐的原因

主要是物理原因

  • 物理上,内存是以连续4或8字节
    块的方式进行访问(依赖于系统)
  • 如果数据跨过四字的边界,数据
    的访问效率低
  • 当数据横跨2个内存页,虚拟内
    存在处理上十分复杂

3.结构体对齐规则

  • 结构体内每个成员都需要对齐
  • K 为结构体中所有元素中的最大对齐需求(就是所有类型中需要的最大的字节数)
    - 结构体的初始地址和大小必须为K的整数倍

下面是例子

  • 例子1:
    在这里插入图片描述
    在这里插入图片描述
    这里跟上面给过的例子相似,可以自己分析一下~
  • 例子2
    在这里插入图片描述
    在这里插入图片描述
    这里地址都是满足的,灰色部分的作用是补齐总字节数 使其满足最大对齐要求(8个字节的倍数)
    所以这里的总字节数为24

4.具体对齐案例(32位)

  • 1字节:char
  • 2字节:short
    • 地址的最低位必须为0 (二进制数)
  • 4字节::int, float, long, char *, …
    • 地址的最低2位必须为00 (二进制数)
  • 8字节:double
    • 地址的最低3位必须为000(二进制数)

5.访问结构体数组中的元素

  • 计算结构体元素的偏移量
  • 本例中成员 j 在结构体中的偏移量(相对于首地址)为8
    先移到结构体的数组元素,再在该结构体中根据对齐规则进行移动
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

下面是汇编代码
在这里插入图片描述

小技巧

为了节省空间 我们通常把尺寸大的成员放在结构体的前面 如图

在这里插入图片描述

在这里插入图片描述

联合体

一、联合体的空间分配

联合体大家应该知道 就是各种类型的成员共享一个空间
如图
在这里插入图片描述
在这里插入图片描述

  • 基于最大的成员分配空间
  • 一次只能使用其中的一个成员

二、字节序

  • 大端

    • 最高字节在最低地址
      如图
      如图 从右往左为从高地址到低地址 f0是小 f3是大在这里插入图片描述
  • 小端

    • 最低字节在最低地址
      如图 从右往左为从低地址到高地址 f0是小 f3是大
      在这里插入图片描述
  • 双端(ARM)

    • 可以通过某种方式进行配置

一个小问题^^

联合体中
在这里插入图片描述

  • 与 (float) u 相同吗?

  • 在这里插入图片描述

  • 与(unsigned) f 相同吗?
    在这里插入图片描述
    这个问题的解答等我二编的时候放上来吧^^

PS:作者最近有点忙 之前写了一篇浮点数的草稿还没发,等我五一冲刺一下@_@

  • 21
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值