数组的分配和访问

ByteZenithMaster
• 阅读 1923

高维数组中行向量的访问

  • A访问的是A数组的首地址(即第一个元素的地址)
  • 高维数组采用的均为行主序的内存排列方式
  • 若A为二维数组,则A【i】相当于访问A数组第i行的地址,得到的是一个指针(第i行第0个元素的地址)。此处极易错误理解成A【i】会给出第i行的所有元素!!
  • 机器指令得到第index行的起始地址

数组的分配和访问

  • 机器指令得到第index行dig列数组的值数组的分配和访问

    嵌套数组(多维数组)在C语言中,如何作为函数参数传递到函数内部并使用

  • 嵌套数组作为参数传递主要有三种方法:
  1. 以定长数组传递。将数组在函数参数表中声明为固定大小的数组(如16*16),这样声明之后,在函数内部直接当数组A为16*16大小的二维数组,使用时可直接用双中括号方法访问。但灵活性有欠缺,无论传入何种数组,都会当作此定长数组处理
  2. 传指针处理。通过指针传递,可以传递变长数组。在传参方式中,把高维数组退化为一维数组,使用一维数组下标的访问方法访问高维数组。通过行主序实现一维和高维下标的转换,先算出第i行间隔,再算出j列间隔,总间隔加在一起得到下标
  3. 更友好、更安全的传参方式,在最新版本gcc中提供支持。将A[N][N]变长数组,直接在参数表中传递进来。但是其维长信息必须在参数表声明A[N][N]数组前,以参数形式首先传入,这样编译阶段才能通过。在使用时直接通过双中括号方法访问。值得注意的是,n的定义一定要在声明A[N][N]数组前,在后边定义会导致编译不通过。数组的分配和访问

    数组访问的机器级实现:

  • 定长传递的数组
  1. 首先将rsi左移64位(i*64,每一列16个元素,每个元素占4个字节)
  2. a+64*i得到第i行首地址,+4*j得到最终结果数组的分配和访问

    由上可知,虽然在C语言内部并没有用到16这个常数,但是转换成汇编指令后,使用16作为汇编信息,获得第i行首地址时用到(16*4)。这也说明了,为何无论传进来数组是何种情况,在实际内部处理时,均当做此定长数组进行处理

  • 采用双中括号访问的变长数组

数组的分配和访问

  1. 采用这种方式传递变长数组时,尽管函数体中并未使用n,但转换成汇编语言中用到n进行汇编运算。因此n必须在声明数组前定义,否则编译会出错

多层数组

  • 与嵌套数组不同,是一种利用指针构造出来的复合数组。把所有指向一维数组的指针再使用一个数组存储起来,得到的结构叫做多层数组
  • 多层数组的三个特点
  1. 以指针数组定义的多层数组,其内部存储数据的空间,不一定是连续的空间,只需局部连续即可(每个指针内部连续),不必整体连续
  2. 多层数组中每一行长度不固定,不一定是矩形,更为灵活
  3. 相比嵌套数组,多层数组在存储内容之外,还需要空间存储各行向量的指针,会消耗额外内存空间。数组的分配和访问
  • 在对多层数组进行访问时,从C语言级别上看,与嵌套数组访问是相似的,采用双中括号方式访问
  • 但内部访问函数是不同的,多层数组首先访问univ下的index元素,得到指针即得到低维数组的首地址,进而得到元素
  • 从汇编级别看二者区别

数组的分配和访问

数组的分配和访问

  1. 多层数组访问过程中会经历两次内存读操作。读取指针数组中要读取指针的地址,来获得低维数组的首地址;读取低维数组中要获取的元素的地址,获取相应元素。因为多层数组不存储在一片连续的内存中间,我们要首先在uivn查到指针,再根据指针查对应位置的元素,要经过两次内存访问才能实现
  2. 嵌套数组只有最后取数据才涉及到读内存操作,之前都是计算偏移量,只计算地址,不读取地址。因为嵌套数组是连续存储的,其中每个内存位置可以由嵌套数组首地址结合下标来得到

多层数组和嵌套数组的比较

  • 从C语言角度没有区别,都采用双中括号形式访问
  • 编译汇编指令时会得到不同的汇编指令。
  • C语言中默认的高维数组是嵌套数组,但支持自己构造多维数组。即先构造指针数组,然后在每个指针中存储一个低维数组。而Java支持的高维数组是多层数组,不支持嵌套数组。因为Java把数组本身看做由引用实现,而多层数组的本质就是引用
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
STM32 HAL库 IIC 协议库函数
/\第1个参数为I2C操作句柄第2个参数为从机设备地址第3个参数为从机寄存器地址第4个参数为从机寄存器地址长度第5个参数为发送的数据的起始地址第6个参数为传输数据的大小第7个参数为操作超时时间\/HAL\_I2C\_Mem\_Write(&hi2c2,salve\_add,0,0,PA\_BUFF,sizeo
Wesley13 Wesley13
3年前
java 基础知识
遍历遍历就是把这个数组的每个元素显示出来遍历的方法就是先定义这个数组的大小,然后用FOR循环来完成数组,例如doublescorenewdouble5;ScannerinputnewScanner(System.in);for(inti0;i<score.l
先知 先知
4年前
C 语言代码大全
1两个数组的合并题目描述已知数组a中有m个按升序排列的元素,数组b中有n个按降序排列的元素,编程将a与b中的所有元素按降序存入数组c中。输入输入有两行,第一行首先是一个正整数m,然后是m个整数;第二行首先是一个正整数n,然后是n个整数,m,n均小于等于1000000。输出输出合并后的mn个整数,数据之间用空格隔开。输出占一行。样例输入4
Jacquelyn38 Jacquelyn38
4年前
这些JS工具函数够你用到2020年底了
前言活不多说,自己平时搜集的干货函数奉上。干货函数找出数字在数组中下一个相邻的元素let i  "";let rr  ;const name  (n, arr1)    let num  Number(n);    for (let i  0; i < arr1.length; i)         const elemen
Karen110 Karen110
4年前
人工智能数学基础-线性代数4:矩阵及矩阵运算
一、矩阵定义矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,定义如下:由m×n个数aij排成的m行n列的数表称为m行n列的矩阵,简称m×n矩阵。记作:这m×n个数称为矩阵A的元素,简称为元,数aij位于矩阵A的第i行第j列,称为矩阵A的(i,j)元,以数aij为(i,j)元的矩阵可记为(aij)或(aij)m×n,m×
Wesley13 Wesley13
3年前
Java中的数组(Array)
数组对于每一门编程语言来讲都是最重要的数据结构之一,当然不同的编程语言对数组的实现以及处理也不尽相同。数组的概念:把有限个相同类型元素变量放在一个整体,这个整体就叫做数组。数组中的每一个元素被称为数组元素,通常可以通过数组元素的索引(也叫下标,可以理解为一种编号,从0开始)来访问数组元素,包括数组元素的赋值(set)和取值(get)。
Wesley13 Wesley13
3年前
C++中二维数组作为函数参数
在平时,我们经常会遇到将整个数组作为函数参数的情况,一维数组的情况,就是用数组名当形参和实参,传递的是数组的首地址。二维数组我们用的也很多,但是总是有各种问题,今天我总结一下有个很重要的一点,字符串“China”在编译器眼里就是一个地址!操作字符串是通过它在内存中的存储单元的首地址进行的,这是字符串的终极本质如果"China",存储在内存中的0
Stella981 Stella981
3年前
Android JNI开发系列(七)访问数组
JNI访问数组JNI中的数组分为基本类型数组和对象数组,它们的处理方式是不一样的,基本类型数组中的所有元素都是JNI的基本数据类型,可以直接访问。而对象数组中的所有元素是一个类的实例或其它数组的引用,和字符串操作一样,不能直接访问Java传递给JNI层的数组,必须选择合适的JNI函数来访问和设置Java层的数组对象。
Stella981 Stella981
3年前
Seeker的奇妙求职历险(网易互联网笔试)
素数的个数给出一个包含n个正整数的数组a,把a\i\拆分为若干个和为a\i\的素数,求拆分后最多能有多少个素数。第一行数据为n,表示数组长度,第二行为n个元素。输入3111输出01不可拆分输入135761为0个,3为1个,5为(2,3
小万哥 小万哥
1年前
C 多维数组、特殊字符和字符串函数详解
C多维数组数组,也称为单维数组。这些非常棒,是您在C语言编程中会经常使用的东西。然而,如果您想要将数据存储为表格形式,例如带有行和列的表格,则需要熟悉多维数组。二维数组二维数组也称为矩阵,具有行和列的结构。cintmatrix231,4,2,3,6
小万哥 小万哥
1年前
NumPy 数组迭代与合并详解
NumPy数组迭代NumPy数组迭代是访问和处理数组元素的重要方法。它允许您逐个或成组地遍历数组元素。基本迭代我们可以使用Python的基本for循环来迭代NumPy数组。一维数组迭代:pythonimportnumpyasnparrnp.array(1