如何计算 N 维数组的元素地址
How to Calculate the Element Addresses of an N-Dimensional Array
据我所知,分配的内存块是连续的,因此数组中的地址是数组数据大小的倍数(在某些系统上为 int = 4 等)
我还看到对于数组 A 和索引 i,A[i] == *(A+i)
在 C 中。
二维数组就像数组的数组,所以我想知道如果我疯狂到不使用 []
运算符,如何确定 N 维数组的表达式。
如果数组是用指针创建的,那不是需要知道关卡的长度吗?
假设您声明 int a[m][n];
如果您引用 a[i][j]
,它等同于 (a[i])[j]
,正如您所指出的,它等同于 (*(a+i))[j]
,这等同于*((*(a+i))+j)
。以字节为单位,整数按指向的对象大小缩放,所以i
按a[0]
或*a
的大小缩放,也就是sub的大小-数组,即 sizeof(int) * n
。通过 *
运算符对结果的取消引用本质上是一种类型转换,将其从指向子数组的指针(类型 int (*)[n]
)转换为指向子数组元素的指针, 输入 int *
。然后,在添加j
时,它被缩放了sizeof(int)
。外部取消引用,通过 *
运算符,实际上取消引用指针,读取值或修改它,具体取决于上下文。
编辑:这是一个您可以尝试的简单演示程序。它说明了我的解释:
#include <stdio.h>
int main()
{
int a[5][10];
printf("%d %d %d\n", sizeof(int[5][10]), sizeof(int[10]), sizeof(int));
printf("%d %d %d\n", sizeof(a), sizeof(a[0]), sizeof(a[0][0]));
printf("%d %d %d\n", sizeof(a), sizeof(*a), sizeof(**a));
void *p1 = a;
void *p2 = a + 1;
void *p3 = *(a + 1) + 3;
printf("%d %d\n", (int) (p2 - p1), (int) (p3 - p2));
printf("%d %d\n", 1 * (sizeof(int) * 10), 3 * sizeof(int));
return 0;
}
对于
int array2d[X][Y];
两个表达式是等价的:
array[1][2];
*((int *)array + 1*Y + 2);
对于
int array3d[X][Y][Z]
两个表达式是等价的:
array[1][2][3];
*((int *)arr + 1*Y*Z + 2*Z + 3);
所以,对于
int arraynd[X][Y][Z]..[N]
两个表达式等价:
arraynd[1][2][3]...[n];
((int *)array + 1*X*Y*Z*...*N + 2*Y*Z*...*N + 3*Z*...*N + ... + n);
据我所知,分配的内存块是连续的,因此数组中的地址是数组数据大小的倍数(在某些系统上为 int = 4 等)
我还看到对于数组 A 和索引 i,A[i] == *(A+i)
在 C 中。
二维数组就像数组的数组,所以我想知道如果我疯狂到不使用 []
运算符,如何确定 N 维数组的表达式。
如果数组是用指针创建的,那不是需要知道关卡的长度吗?
假设您声明 int a[m][n];
如果您引用 a[i][j]
,它等同于 (a[i])[j]
,正如您所指出的,它等同于 (*(a+i))[j]
,这等同于*((*(a+i))+j)
。以字节为单位,整数按指向的对象大小缩放,所以i
按a[0]
或*a
的大小缩放,也就是sub的大小-数组,即 sizeof(int) * n
。通过 *
运算符对结果的取消引用本质上是一种类型转换,将其从指向子数组的指针(类型 int (*)[n]
)转换为指向子数组元素的指针, 输入 int *
。然后,在添加j
时,它被缩放了sizeof(int)
。外部取消引用,通过 *
运算符,实际上取消引用指针,读取值或修改它,具体取决于上下文。
编辑:这是一个您可以尝试的简单演示程序。它说明了我的解释:
#include <stdio.h>
int main()
{
int a[5][10];
printf("%d %d %d\n", sizeof(int[5][10]), sizeof(int[10]), sizeof(int));
printf("%d %d %d\n", sizeof(a), sizeof(a[0]), sizeof(a[0][0]));
printf("%d %d %d\n", sizeof(a), sizeof(*a), sizeof(**a));
void *p1 = a;
void *p2 = a + 1;
void *p3 = *(a + 1) + 3;
printf("%d %d\n", (int) (p2 - p1), (int) (p3 - p2));
printf("%d %d\n", 1 * (sizeof(int) * 10), 3 * sizeof(int));
return 0;
}
对于
int array2d[X][Y];
两个表达式是等价的:
array[1][2];
*((int *)array + 1*Y + 2);
对于
int array3d[X][Y][Z]
两个表达式是等价的:
array[1][2][3];
*((int *)arr + 1*Y*Z + 2*Z + 3);
所以,对于
int arraynd[X][Y][Z]..[N]
两个表达式等价:
arraynd[1][2][3]...[n];
((int *)array + 1*X*Y*Z*...*N + 2*Y*Z*...*N + 3*Z*...*N + ... + n);