怎么初始化不知道大小的数组_面试之数组你不知道的一些小细节

前言

所谓金三银四,简单的说就是每年三月四月找工作好找,而且工资高。每当到了这个季节,很多人就开始跳槽找工作,刷面试题开始面试的人就多了起来。人们又开始面试造飞机,上班拧螺丝的节奏了。

在我们刷数据结构面试题的时候总会看见一道数组和链表有什么区别的题目,很显然这是一道考的非常频繁的问题,也是非常基础的一道数据结构问题,然而他的答案也非常的显而易见。

  • 数组在申请内存空间的时候需要连续的一片内存空间;而链表则不然,他只需要剩余的内存空间满足大小即可
  • 数组查询快,插入删除慢;链表查询慢,插入删除快

看到这里也许你们就结束了。但是你们有没有想过以下的问题:

  • 数组为什么可以快速访问
  • 数组为什么需要要是一片连续的内存
  • 数组为什么只能存储相同数据类型的数据
  • 数组下标为什么要从0开始

如果你没有想过,那么我就带你们来解开这些问题,然而这一切都要从一个寻址公式开始。

寻址公式

什么是寻址公式,寻址公式是数组为了寻址数据所对应的内存地址的公式,公式为:

address[i] = base_address + i * data_type_size

其中base_address是在初始化数组的时候申请内存时候给的初始地址,也就是数组会从这个地址开始写数据;i就是我们数组的下标;data_type_size表示数组中每个元素的⼤⼩。我们举的这个例⼦⾥,数组中存储的是int类型数据,所以data_type_size就 为4个字节;这个公式⾮常简单,我就不多做解释了。

为什么需要一片连续的内存

当数组初始化结束,那么从寻址公式可以得出,从base_addressbase_address + (i +1)* data_type_size的内存都会被数组使用,如果这片内存里面存在着其他数据将被覆盖,所以数组在初始化的时候就会寻找(i+1)*data_type_size大小的连续空内存

为什么存储同种类型的数据

同样我们可以从寻址公式里面看出来data_type_size是一个数组初始化后就不可变的数;假设一下,一个数组存储了多种数据类型的数据,那么在存储的时候会有两种情况;第一种:当前存储的数据字节数大于之前存储的字节数,那么就会出现内存缝隙,比如,内存起始地址为10,那存入一个2个字节的数据,根据寻址公式,可以算出开始地址就是10,然后占两个字节,地址到12结束;如果再存入一个4个字节的数据,这时候根据寻址公式,可以知道开始地址是14,那个这里就出现了两个字节的空闲内存。同理:第二种情况,当前存储的数据字节数小于之前存储的字节数,我们可以看出数据会被覆盖。因此存储同一种数据类型的数据,即不会出现内存分析,又不会出现数据覆盖

dcbac92eaf9acffee602f282ceaca31d.png

当前存储的数据字节数大于之前存储的字节数

1cf2f2576401ecb3b0dbd23b63b90380.png

当前存储的数据字节数小于之前存储的字节数

数组下标为什么要从0开始

很多人都会想为什么很多语言的数据结构中的数组都是从0开始的?我们假设数组下标从1开始,那么数组寻址的公式就是:

address[i] = base_address + (i-1) * data_type_size

从这个公式里面可以看出来,相比之前的公式多做了一次减法,所以可以看出从0开始至少从性能上是比从1开始要高。数组作为一个很底层的数据结构,追求极致的性能无可厚非

总结

数组为了实现快速访问,使用address[i] = base_address + i * data_type_size的寻址公式进行寻址;因此他的内存模型必须是一片连续的内存;又为了防止出现内存缝隙或者内存数据覆盖,所以寻址公式的data_type_size必须在一个定值;因此一个数组的数据类型必须一样;追求性能的极致,所以下标从0开始

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值