C中两个数组元素地址之间的偏移量
我有一个问题要我找出两个数组元素地址之间的偏移量(以字节为单位): 如果C以列主顺序存储数据,则C中两个数组元素地址之间的偏移量,c,arrays,offset,C,Arrays,Offset,我有一个问题要我找出两个数组元素地址之间的偏移量(以字节为单位): 如果C以列主顺序存储数据,则&myArray[3][2]与&myArray[0][0]之间的偏移量(以字节为单位)将为: 按主要顺序,我认为元素的布局如下: [0][0] -- [1][0] -- [2][0] -- [3][0] -- ..... -- [3][2] 所以在我看来,以字节为单位的偏移量是计算[0][0]和[3][2]之间的跳跃次数,并乘以8,因为这是一个双精度数组。然而,让我困惑的是,它使用&运算符来请求偏移
&myArray[3][2]
与&myArray[0][0]
之间的偏移量(以字节为单位)将为:
按主要顺序,我认为元素的布局如下:
[0][0] -- [1][0] -- [2][0] -- [3][0] -- ..... -- [3][2]
所以在我看来,以字节为单位的偏移量是计算[0][0]和[3][2]之间的跳跃次数,并乘以8,因为这是一个双精度数组。然而,让我困惑的是,它使用&运算符来请求偏移量。这会不会改变答案,因为它是在两个地址之间询问,还是过程仍然相同?我想是一样的,但我不是100%肯定
如果我的想法是正确的,那么这将是8*15字节吗?2d数组的内存布局将是一个连续的内存块。(根据您的问题) 那将在(你的问题)中详细说明 但是在
C
中,它的存储方式如下
--+--+--+--+--+--+
0| 1| 2| 3|4 |5 |
--+--+--+--+--+--+
现在你是完全正确的,你可以考虑在<代码> [0 ] [0 ] < /C>和<代码> [3 ] [2 ] < /C>之间跳转,但是有更好的方法来做到这一点而不考虑所有这些,你可以确信它们的偏移将是它们的地址差异。
你可以简单地得到他们的地址并减去他们ptrdiff_t ans=&a[3][2]-&a[0][0]
;(这基本上是两个要素之间的差距)
这就是答案printf(“answer=%td”,ans*sizeof(a[0][0]);
(一个间隙=sizeof(a[0][0])
)[在您的情况下是双间隙
]
或者更好的办法是
ptrdiff_t ans = (char*)&a[3][2] - (char*)&a[0][0];//number of bytes between them.
我将解释一下为什么
char*
在这里很重要:
(char*)&a[0][0]
和&a[0][0]
在值方面都包含相同的内容。(这不够一般)
但它在指针运算中很重要(解释是不同的)
当不使用CAST时,解释是数组元素的数据类型。这意味着现在考虑“代码>双< /代码> s的差异。当您抛出它时,它将结果在代码< char < /代码> -S.
中插入或差异。 为什么会这样呢?因为所有的数据存储器都是可寻址的,而字符是单字节的这比预期的要复杂得多,首先让我们看看
C
?†
C实际上没有多维数组。在C
中,它是作为数组数组实现的。是的,这些多维数组元素按行主顺序存储
为了进一步澄清,我们可以查看标准§6.5.2.1
考虑由声明定义的数组对象
int x[3][5];
这里x
是3x5
的int
s数组;更准确地说,x
是
三个元素对象,每个元素对象是一个由五个int
s组成的数组
表达式x[i]
,它相当于(*((x)+(i))
,x
转换为指向五个整数的初始数组的指针。然后i
将
根据x
的类型进行调整,这在概念上意味着
将i
乘以指针指向的对象的大小,
即一个由五个int对象组成的数组
当在中使用时,间接寻址用于生成一个包含五个整数的数组
表达式x[i][j]
,该数组依次转换为指针
到int
s的第一个,因此x[i][j]
产生一个int
因此,我们可以说double myArray[5][7];
这里myArray[3][2]
和myArray[0][0]
不是同一个数组的一部分
现在,我们在这里完成了-让我们进入其他内容:
来自标准第6.5.6.9节
减去两个指针后,两个指针都应指向
相同的数组对象,或数组对象的最后一个元素后一个元素;
结果是两个数组的下标不同
元素
但是这里的myArray[3]
和myArray[0]
表示两个不同的数组。这意味着myArrayp[3][2]
和myArray[0][0]
都属于不同的数组。它们不是最后一个元素。所以减法&myArray[3][2]&myArray[0][0]
将不由标准定义。
†Eric(Eric Postpichil)指出了这个想法。在行主遍历中,声明是
array[height][width]
,用法是array[row][column]
。在行主遍历中,除非您超过宽度并“wrap”,否则,单步到下一个数字将显示下一列到下一行。每行向索引中添加width
,每列添加1,使行成为“主要”索引
为了获得列主等效值,假设下一个值是下一行,当该行超过高度时,它会“换行”到下一列。这可以通过index=column*height+row
来描述
因此,对于高度为5的数组数组[5][7]
,索引[3][2]
产生2*5+3=13
让我们用一些代码进行验证。只需切换索引的顺序,就可以获得列的主要行为
#include <stdio.h>
int main() {
double array[7][5];
void *root = &array[0][0];
void *addr = &array[2][3];
size_t off = addr - root;
printf("memory offset: %d number offset: %d\n", off, off/sizeof(double));
return 0;
}
#包括
int main(){
双数组[7][5];
void*root=&数组[0][0];
ptrdiff_t ans = (char*)&a[3][2] - (char*)&a[0][0];//number of bytes between them.
int x[3][5];
#include <stdio.h>
int main() {
double array[7][5];
void *root = &array[0][0];
void *addr = &array[2][3];
size_t off = addr - root;
printf("memory offset: %d number offset: %d\n", off, off/sizeof(double));
return 0;
}