在纯C中传递二维数组

时间:2013-06-22 17:14:14

标签: c arrays graph

我正在尝试编写通用矩阵转置函数

void reverse(int** v , int vertexes )
{
    for(int i=0;i<vertexes;i++)
        for(int j=0;j<vertexes;j++) 
        {
            if(v[i][j] == 1 && v[j][i]==0){
                v[j][i] = -1;
                v[i][j] = 0;        
            }
        }

    for(int i=0;i<vertexes;i++)
        for(int j=0;j<vertexes;j++) 
        {
            if(v[i][j] == -1 )
                v[i][j] = 1;
        }
} 

主要功能是

void matrix_graph::process()
{

    int v[7][7] = {
        {0,1,0,0,0,0,0},
        {0,0,1,1,0,0,0},
        {1,0,0,0,0,0,0}, 
        {0,0,0,0,1,0,0},
        {0,0,0,0,0,1,0},
        {0,0,0,1,0,0,1},
        {0,0,0,0,0,1,0}
    };

    reverse(v,7);
}

我按预期得到了

error C2664: 'reverse' : cannot convert parameter 1 from 'int [7][7]' to 'int **'

我们可以做些什么吗?

我们能够做的最好的方法是访问传递的二维数组的ij(将v作为一维数组传递)

v[vertexes*i][j]

5 个答案:

答案 0 :(得分:5)

只需使用

void reverse(int vertexes, int v[vertexes][vertexes])

尝试使用int **不会立即使用内置的2D数组。如果你想坚持int **接口,那么你将不得不创建一个额外的临时行索引数组,如下所述

Passing two-dimensional array via pointer

或在这里

conversion of 2D array to pointer-to-pointer

答案 1 :(得分:3)

你应该小心,因为数组的数组与双指针相同。虽然数组衰减到指针是正确的,但使用指向指针作为数组数组的指针意味着你实际上将它用作指针数组。

而是将参数作为指向数组的指针,如

int (*v)[7]

答案 2 :(得分:0)

我认为使用堆内存可以解决问题。因此,而不是声明堆栈中的int[7][7] v,使用malloc将在堆中创建数组,并允许您在函数之外操作它。

int** v = (int**)malloc((sizeof(int*) * 7));

for (int i = 0; i < 7; i++)
{
    v[i] = (int*)malloc(sizeof(int)*7);
}
// then initialize v here...

答案 3 :(得分:0)

要摆脱错误并保留您的想法,您可以按如下方式调用您的函数:

reverse(&v[0][0],7);

并修改函数和原型:

void reverse(int* v , int vertexes ){
for (int i=0; i<vertexes; i++)
    for (int j=0; j<vertexes; j++){
    // do stuff 
    v[i*vertexes+j]; //equivalent of v[i][j]
    v[j*vertexes+i]; //equivalent of v[j][i]
}

答案 4 :(得分:0)

我认为这里的一个好设计是创建一个Matrix类,它将操作封装在矩阵上。我还建议不要使用指针指针来存储矩阵的数据,而是使用一维数组和索引转换,如:

int &Matrix::at( int i, int j )
{
    // check the constraints
    return m_array[i * m_width + j];
}

这简化了内存管理,并防止在处理不必要的复杂结构时处理错误。

C / C ++中的多维数组与指针指向指针的指针相同。事实上,多维数组是一个连续的内存区域,由编译器完成索引转换,而指针指针是指向其他维度的一维指针数组。在这种情况下,内存可能不是连续的,在这种情况下还有其他指针,在多维数组的情况下不存在。

总结一下,如果是数组:

int array[7][7] = { ... };
array[2][3] ===
    &array[0][0] /* start of the array */ +
    2 * 7 + 3    /* index transformation 2D to 1D*/

如果是指针:

int **pointer;
pointer[2][3] === *(*(pointer + 2) + 3)

这两个代码片段做两个完全不同的事情,你不应该将多维数组转换为多星指针,反之亦然。