当前位置: 首页 > Linux

数组分配与访问

时间:2023-04-06 19:00:07 Linux

高维数组A中的行向量访问,访问的是A数组的首地址(即第一个元素的地址)。高维数组采用行优先的存储方式。如果A是一个二维数组,那么A[i]就相当于访问了A数组第i行的地址,得到的是一个指针(第i行第0个元素的地址排)。这里很容易误会A[i]会给出第i行的所有元素!!机器指令获取索引行的起始地址。机器指令获取索引行挖列数组的值。嵌套数组(多维数组)在C语言中,如何将其作为函数参数传入函数以及将嵌套数组作为参数传递给main,有3种方法:传入一个定长数组。在函数参数表中声明数组为定长数组(如16*16)。这样声明后,数组A在函数内部直接看成一个16*16大小的二维数组,使用时直接用双中括号的方法即可。使用权。但是,缺乏灵活性。不管传入什么样的数组,都会被当作这个定长数组,作为指针传递。通过指针传递,可以传递变长数组。在传参方式中,将高维数组退化为一维数组,使用一维数组下标访问方式访问高维数组。通过row-majororder实现一维和高维下标的转换,先计算第i行区间,再计算j列区间,将总区间相加得到更友好更安全的下标参数传递方式,在最新版本的gcc支持中提供。直接在参数表中传递A[N][N]变长数组。但是它的维度长度信息必须在参数表声明A[N][N]数组之前作为参数传入,这样编译阶段才能通过。使用时直接通过双括号方式访问。值得注意的是,n的定义必须在A[N][N]数组的声明之前,后面的定义会导致编译失败。数组访问的机器级实现:定长传入的数组先将rsi左移64位(i*64,每列16个元素,每个元素占4字节)a+64*i得到首地址第i行,+4*j得到最终结果。由上可见,C语言中虽然没有使用常量16,但是将其转化为汇编指令后,将16作为汇编信息,得到第i行首地址(16*4).这也解释了为什么在实际内部处理时,无论传入数组的情况如何,都将其视为定长数组。当用双方括号访问的变长数组用这种方式传递一个变长数组时,虽然函数体中没有使用n函数,但它被转换成汇编语言,用于汇编操作。所以在声明数组之前必须先定义n,否则会出现编译错误。多层数组不同于嵌套数组。它们是使用指针构造的复合数组。将所有指向一维数组的指针存储在一个数组中,得到的结构称为多层数组。多层数组的三个特性由指针数组定义。是一个连续的空间,只需要局部连续(每个指针内部连续),不需要整体连续组除了存储内容外,还需要空间来存储各个指针行向量,这将消耗额外的内存空间。访问多层数组时,从C语言层面看,类似于嵌套数组访问,使用双中括号访问但内部访问函数不同,多层数组首先访问univ下的索引元素,获取指针就是获取低维数组的首地址,然后获取元素。从汇编层面来看,两者的区别在于多层数组访问过程中会经历两次内存读取操作。读取指针数组中待读指针的地址,得到低维数组的首地址;读取低维数组中待获取元素的地址,获取对应的元素。因为多层数组并不是存储在一个连续的内存中,所以我们需要先在uivn中找到指针,然后根据指针查看对应位置的元素。实现嵌套数组需要两次内存访问。只涉及最后一次取数据。对于内存读操作,之前计算了偏移量,只计算了地址,并没有读取地址。因为嵌套数组是连续存储的,所以通过嵌套数组的首地址加上下标就可以得到每一个内存位置。多层数组和嵌套数组的比较,从C语言的角度看没有区别,都是以双中括号的形式访问的。在编译汇编指令时,你会得到不同的汇编指令。C语言默认的高维数组是嵌套数组,但是支持自构造多维数组。即先构造一个指针数组,然后在每个指针中存储一个低维数组。Java支持的高维数组是多层数组,不支持嵌套数组。因为Java把数组本身看做是引用实现的,而多层数组的本质就是引用