使用** ptr传递多维数组

时间:2015-05-10 22:20:59

标签: c arrays pointers

就在今天,我正在考虑将多维数组传递给函数的不同方法。我所知道的方法总结为三个小函数:

void method_a(int m, int n, int (*ptr_arr)[n])
{
    int i, j;
    for (i = 0; i < m; i++)
    {
         for (j = 0; j < n; j++)
         {
            ptr_arr[i][j] = j + 1;
        }
    }
}

void method_c(int m, int n, int arr[][n])
{
    int i, j;
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            arr[i][j] = j + 3;
        }
    }
}

void method_b(int m, int n, int *ptr_arr)
{
    int i, j;
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            *((ptr_arr + i * n) + j) = j + 2;
        }


}

我还阅读了很多声明,以下内容相当于method_a()

void method_d(int m, int n, int **ptr_arr)
{
    int i, j;
    for (i = 0; i < m; i++)
    {
         for (j = 0; j < n; j++)
         {
            ptr_arr[i][j] = j + 1;
        }
    }
}

但它似乎不适用于静态数组。这是否仅适用于通过malloc()动态分配的数组。如果它也适用于静态声明的数组,有人会给出一个例子吗?

3 个答案:

答案 0 :(得分:2)

方法a,b和c是等价的并且应用于二维数组(声明为int arr[x][y])。方法d适用于完全不同的对象:指向一维数组的指针数组。

比迪阵列:

a 00 a 01 a 02 a 03

a 10 a 11 a 12 a 13

a 20 a 21 a 22 a 23

指针数组

a0 a1 a2

|  |  |________ a20 a21 a22 a23
|  |___________ a10 a11 a12 a13
|______________ a00 a01 a02 a03

在这种情况下,你有一个指向不同行的指针数组,并且这些行不需要在内存中连续

或者,如果你有一个二维数组,比如int arr[3][4];,你可以使用它轻松地构建一个指针数组:

int *ptarr[3];
...
for(i=0; i<3; i++) {
    ptarr[i] = &(arr[i][0]);
}

然后你可以用你的方法d

答案 1 :(得分:0)

简而言之,不,因为int **int *[N]是不同的类型。

您需要了解您正在处理的变量类型。许多人将在连续内存区域中声明的矩阵与指针数组混淆。恕我直言,这是因为两种方法的语法matrix[a][b]都相同。

但是,int **mat1不等同于int mat2[][N]mat2int[N]数组的数组。 mat1更少 - 只是指向整数的指针。你不知道有多少人。

如果在连续的内存区域(mat2)中声明了矩阵,要正确计算元素的位置,您需要知道尺寸,第一个除外。这是因为你需要知道有多少&#34;帧&#34; (在int[N]的情况下为mat2),在更改索引时需要跳过,最后一个按类型给出。例如。如果您有int mat[4][5],则要从[1][3]更改为[2][3],您需要知道,行中有6个整数。但是从[1][3][1][4]仅为int一个,因此不需要此维度的大小。这也是为什么任何矩阵可以衰减到适当类型的一个较小维度的指针,但只少一个矩阵的原因!

method_a中你有这些信息(它自然是类型)。如果您指向指针mat[x][y]的指针有不同的处理方式。它的工作原理如下:

int element;
int *row;
row = mat[x];
element = row[y];

请注意,有两个方向!您无法立即从xy计算元素位置。连续行的元素不必彼此相邻。只有指向他们的指针。他们也不必长度相同。

这就是将静态多维数组作为指针指针样式传递时出错的原因。

答案 2 :(得分:0)

最后一个方法的问题是编译器无法弄清楚数组的行有多大,因为你只有一个指向int的指针,而不是指向数组的指针。 / p>

如果查看第三种方法(标记为method_b的方法),在添加j之前将i * n相乘时,您将手动为编译器执行此操作。在method_a和method_b中,您在函数原型中提供了'n'的值。

在“method_d”代码中,编译器无法弄清楚'n'的值是什么,因此无法计算ptr_arr [i] [j]的数组偏移量。