【问题标题】:How to Calculate the Element Addresses of an N-Dimensional Array如何计算 N 维数组的元素地址
【发布时间】:2016-02-05 21:02:22
【问题描述】:

据我了解,分配的内存块是连续的,因此数组中的地址是数组数据大小的倍数(在某些系统上为 int = 4,等等)

我还看到对于数组 A 和索引 i,C 中的 A[i] == *(A+i)

二维数组就像一个数组数组,所以我想知道如果我疯得不使用[] 运算符,如何确定N 维数组的表达式。

如果数组是用指针创建的,那不是需要知道层的长度吗?

【问题讨论】:

  • 当你说“二维数组”时,你的意思是像int array[X][Y]这样的数组吗?一个指针数组,比如int *array[X]?指向数组的指针,例如 int (*array)[X]?还是指向指针的指针,例如int **array?虽然所有这些都可以通过简单的索引来访问,但它们在内存中的布局是不同的,因此如果您不想使用数组索引,则需要为每个表达式使用不同的表达式。
  • @JoachimPileborg 我的意思是像 int array[x][y]、int array[x][y][z]、int array[][]...[] 这样的数组。但现在想来,我都很好奇,因为我不知道他们的布局不同。

标签: c arrays pointers multidimensional-array operators


【解决方案1】:

对于

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);

【讨论】:

    【解决方案2】:

    假设您声明int a[m][n]; 如果您引用a[i][j],则它等效于(a[i])[j],正如您所指出的,它等效于(*(a+i))[j],它等效于*((*(a+i))+j)。就字节而言,整数按指向的对象的大小进行缩放,所以ia[0]的大小进行缩放,或者*a,也就是子数组的大小,也就是@ 987654329@。通过* 运算符对结果的取消引用本质上是一种类型转换,将其从指向子数组的指针(类型为int (*)[n])转换为指向子数组元素的指针,类型为@987654332 @。然后,当添加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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-04
      • 1970-01-01
      相关资源
      最近更新 更多