繁体   English   中英

在纯C中传递二维数组

[英]Passing a 2-D array in pure C

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

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 **'

我们有什么可以做的吗?

我们最好的方法是访问传递的2-d数组(将v作为一维数组)的ij

v[vertexes*i][j]

只需使用

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

尝试使用int **不能立即用于内置2D数组。 如果要坚持使用int **接口,则必须创建一个额外的临时行索引数组,如此处所述

通过指针传递二维数组

或在这里

2D数组到指针到指针的转换

你应该小心,因为数组的数组是一样的双指针。 确实,数组会衰减为指针,但是将指向指针的指针用作数组数组意味着您实际上将其用作指针数组。

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

int (*v)[7]

我认为使用堆内存将解决此问题。 因此,与其声明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...

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

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]
}

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

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

这简化了内存管理,并避免了处理不必要的复杂结构中的错误。

在C A多维数组/ 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)

这两个代码片段执行两项完全不同的操作,您不应将多维数组转换为多星指针,反之亦然。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM