zoukankan      html  css  js  c++  java
  • 03 数组:为什么很多编程语言中数组都从0开始编号?

    03 数组:为什么很多编程语言中数组都从0开始编号?

    一、为什么很多编程语言的数组都是从0开始编号的?

    1. 从数组存储的内存模型上来看,“下标” 确切的说法就是一种”偏移”,相比从1开始编号,从0开始编号会少-次减法运算, 数组作为非常基础的数组结构,通过下标随机访问元素又是非常基础的操作,效率的优化就要尽可能的做到极致。
    2. 主要的原因是历史原因,C语言的设计者是从0开始计数数组下标的,之后的Java、JS等语言都进行了效仿,或者说是为了减少从C转向Java、JS等的学习成本。

    二、什么是数组?

    • 数组是一个线性数据结构,用一组连续的内存空间存储一组具有相同类型的数据。
    • 其实数组、链表、栈、队列都是线性表结构;树、图则是非线性表结构。

    三、数组和链表的面试纠错

    1. 数组中的元素存在一个连续的内存空间中, 而链表中的元素可以不存在于连续的内存空间。
    2. 数组支持随机访问,根据下标随机访问的时间复杂度是0(1);链表适合插入、删除操作,时间复杂
      度为O(1)。

    四、容器是否完全替代数组?

    容器的优势:对于Java语言,容器封装了数组插入、删除等操作的细节,并且支持动态扩容。对于Java,一些更适合用数组的场景:

    1. Java的ArrayList无法存储基本类型, 需要进行装箱操作,而装箱与拆箱操作都会有一定的性能消
      耗,如果特别注意性能,或者希望使用基本类型,就可以选用数组。
    2. 若数组大小事先已知,并且对数组只有非常简单的操作,不需要使用到ArrayList提供的大部分方
      法,则可以直接使用数组。
    3. 多维数组时,使用数组会更加直观。

    五、JVM标记清除算法

    GC最基础的收集算法就是标记-清除算法,如同他们的名字一样, 此算法分为“标记”、“清除” 两个
    阶段,先标记出需要回收的对象,再统- -回收标记的对象。不足有二,一是效率不高, 二是产生碎片内
    存空间。

    大多数主流虚拟机采用可达性分析算法来判断对象是否存活,在标记阶段,会遍历所有 GC ROOTS,将所有 GC ROOTS 可达的对象标记为存活。只有当标记工作完成后,清理工作才会开始。

    不足:

    • 效率问题。标记和清理效率都不高,但是当知道只有少量垃圾产生时会很高效。
    • 空间问题。会产生不连续的内存空间碎片。
    • 另外,对于数组访问越界造成无限循环,我理解是编译器的问题,对于不同的编译器,在内存分配时,会按照内存地址递增或递减的方式进行分配。老师的程序,如果是内存地址递减的方式,就会造成无限循环。

    六、数组的内存寻址公式

    一维数组:
    $$
    a[i]_address=base_address+i*typesize
    $$

    二维数组假设是,对于 $mn$ 的数组,$a[i]][j]$ (i < m,j < n)的地址为:
    $$
    a[i][j]_address=base_address + (i
    n+j)typesize
    $$
    三维数组假设是,对于 $m
    n*q$ 的数组

    $$
    a[i][j][k]_address=base_address + (inq + jq + k)typesize
    $$

  • 相关阅读:
    angular学习之通俗易懂篇-----constructor()与ngOnInit()
    vscode----快捷键
    angular学习之通俗易懂篇-----路由
    angular学习之通俗易懂篇-----双向数据绑定MVVM
    angular学习之通俗易懂篇-----数据绑定
    angular学习之通俗易懂篇-----新建组件并调用
    angular学习之-----常用命令行
    windows环境下node更新最新版本----简单粗暴
    首例爬虫禁令:法院裁定立即停止擅自爬取微信公众号相关数据行为取微信公众号相关数据行为
    Pycharm两种快速激活方式(附最新激活码和插件)
  • 原文地址:https://www.cnblogs.com/yuanhang110/p/12962086.html
Copyright © 2011-2022 走看看