C 指向未知大小的现有二维数组的指针?

C 指向未知大小的现有二维数组的指针?,c,arrays,pointers,C,Arrays,Pointers,我有以下资料: struct matrix { int h; int w; int** data; }; int m1[2][2] = { {1, 2}, {3, 4} }; int m2[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; struct matrix matrix1 = {2, 2, m1}; struct matrix matrix2 = {3, 3, m2}; 这将

我有以下资料:

struct matrix {
    int h;
    int w;
    int** data;
};

int m1[2][2] = {
    {1, 2},
    {3, 4}
};

int m2[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

struct matrix matrix1 = {2, 2, m1};
struct matrix matrix2 = {3, 3, m2};

这将导致错误“从不兼容的指针类型初始化”。我应该使用什么指针类型?

正如您所声明的,矩阵不是指向指针的指针。使用简单指针指向其元素

#include <stdio.h>

struct matrix {
    int h;
    int w;
    int* data;
};

int m1[2][2] = {
    {1, 2},
    {3, 4}
};

int m2[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

struct matrix matrix1 = {2, 2, &m1[0][0]};
struct matrix matrix2 = {3, 3, &m2[0][0]};

int main(int argc, char **argv)
{
   int i, j;

   for (i=0; i<matrix2.h; i++)
      for(j=0; j<matrix2.w; j++)
         printf("%d ", matrix2.data[(i*matrix2.h)+j]);

    printf("\n");
}

2d数组不是指向指针的指针

如何使用void*

#include <stdio.h>

struct matrix {
    int h;
    int w;
    void *data;
};

int m1[2][2] = {
    {1, 2},
    {3, 4}
};

int m2[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

struct matrix matrix1 = {2, 2, m1};
struct matrix matrix2 = {3, 3, m2};

int main(void){
    int i, j;

    int (*matp)[matrix2.w] = matrix2.data;//Back from the void* to pointer to array

    for (i=0; i<matrix2.h; i++){
        for(j=0; j<matrix2.w; j++)
            printf("%d ", matp[i][j]);
        puts("");
    }
    printf("\n");

    return 0;
}
#包括
结构矩阵{
int-h;
int w;
作废*数据;
};
int m1[2][2]={
{1, 2},
{3, 4}
};
int m2[3][3]={
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
结构矩阵matrix1={2,2,m1};
结构矩阵matrix2={3,3,m2};
内部主(空){
int i,j;
int(*matp)[matrix2.w]=matrix2.data;//从void*返回到数组指针

对于(i=0;i您可能对C99的可变长度数组感兴趣。此解决方案不会直接回答您关于如何使用正确键入的
数据初始化结构的问题(您不能);但您可以使用一个简单的指针来存储数组的地址,然后在使用
struct matrix
时转换为可变长度数组指针

用户端只需调用
printFroMat()
之类的函数,这些函数接收类型为
struct matrix
的单个参数;这些函数中的代码(也就是说,库实现)将执行有点难看的强制转换,如所示。
typedef
使强制转换可能更容易理解,因为它演示了声明中变量名的位置

请注意,有趣的
sizeof(m2)/sizeof(*m2)
等并不是绝对必要的,您可以说
3
。但是
sizeof
表达式会自动与实际矩阵大小保持同步,从而很快成为真正的资产

您可以将“数组”(实际上:仍然只是地址,但属于已知的数组类型)及其维度作为参数传递给函数,并以正常方式(在下面的
printMatrix
中)对其进行索引。例如:

#include<stdio.h>
#include<string.h>


struct matrix {
    int h;
    int w;
    int *data; // first element of matrix
};

int m2[4][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9},
    {10, 11, 12}
};

void printMatrix(int dim1, int dim2, int mat[][dim2] )
{
    printf("Address of matrix: %p\n", (void *)mat);

    for(int i1=0; i1<dim1; i1++)
    {
        for(int i2=0; i2<dim2; i2++)
        {
            printf("%d ", mat[i1][i2]);
        }
        putchar('\n');
    }
}

void printFromMat(struct matrix mat)
{
    printMatrix(mat.h, mat.w, (int (*)[mat.w])mat.data);

    // or:
    typedef int (*mT)[mat.w];
    printMatrix(mat.h, mat.w, (mT)mat.data);
}

int main() 
{

    printMatrix(   sizeof(m2) /sizeof(*m2),   // number of highest-order elements
                   sizeof(*m2)/sizeof(**m2),  // number of second-order elements per highest-order
                   m2  );                     // address of the first sub-array

    struct matrix mat = { sizeof(m2) /sizeof(*m2), sizeof(*m2)/sizeof(**m2), *m2 };

    printFromMat(mat);


    return 0;
}

您不能像这样初始化结构

struct matrix matrix1 = {2, 2, m1};
struct matrix matrix2 = {3, 3, m2};
因为没有从类型
int(*)[2]
int(*)[3]
到类型
int**

我建议动态地为数组的副本分配内存

如演示程序所示,该方法可以如下所示

#include <stdlib.h>
#include <stdio.h>

struct matrix 
{
    size_t h;
    size_t w;
    int **data;
};

int m1[2][2] = 
{
    { 1, 2 },
    { 3, 4 }
};

int m2[3][3] = 
{
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};

struct matrix init( size_t h, size_t w, int a[h][w] )
{
    struct matrix matrix = { 0 };

    matrix.data = malloc( h * sizeof( int * ) );

    if ( matrix.data )
    {
        matrix.h = h;
        matrix.w = w;
        for ( size_t i = 0; i < h; i++ ) 
        {            
            matrix.data[i] = malloc( w * sizeof( int ) );
            if ( matrix.data[i] )
            {                
                for ( size_t j = 0; j < w; j++ ) matrix.data[i][j] = a[i][j];
            }
        }
    }        

    return matrix;
}

int main( void ) 
{
    struct matrix matrix1 = init( 2, 2, m1 );
    struct matrix matrix2 = init( 3, 3, m2 );

    for ( size_t i = 0; i < matrix1.h; i++ )
    {
        for ( size_t j = 0; j < matrix1.w; j++ ) printf( "%d ", matrix1.data[i][j] );
        printf( "\n" );
    }
    printf( "\n" );

    for ( size_t i = 0; i < matrix2.h; i++ )
    {
        for ( size_t j = 0; j < matrix2.w; j++ ) printf( "%d ", matrix2.data[i][j] );
        printf( "\n" );
    }
    printf( "\n" );

    // free allocated arrays of matrix1 and matrix2
}    
您还需要编写一个函数来释放为结构分配的内存


编译器必须支持可变长度数组。

首先检查
m1
m2
的类型…2d数组不是指向指针的指针…@SouravGhosh我不认为可以从typeof()中获取字符串…?@Dimpl请看LP的评论。有时在实现之前试着思考一下。这很有帮助。Meh。2d数组不是指向指针的指针…只是它有点像。请看。我问了这个问题,因为这个答案没有解决2d数组的所有值都在一个语句中赋值的情况。这是令人满意的,但不是t最优,因为我更喜欢使用[I][j]而不是[(I*3)+j]。谢谢,这非常好。在我的应用程序中,我只访问1个库函数中的矩阵,因此Peter A.Schneider的答案效果更好,但如果可以,我也会接受这个解决方案。我无法了解
int(*matp)[matrix2.w]的情况=matrix2.data;
,但它可以工作!我以前从未见过括号中的变量名。我认为这是最不坏的版本。缺点是必须在数组指针和void指针之间进行转换,并且void指针不是类型安全的。我开始编写一个答案,通过宏使用VLA创建一个结构,但它是安全的可读性差得多。另一种选择是一些指针数组解决方案,但这也不太好。@Dimpl它创建一个指向大小为
w
的1D数组的数组指针。然后对这种指针类型使用指针算术来访问2D数组中的每个数组。
matp[i][j]
意味着“给我数组
i
,在该数组中给我项目
j
”@Lundin谢谢。我倾向于使用int*进行声明,而使用*matp进行解引用,因此有点混淆。不过,也许可以使用宏来进行矩阵指针声明,以使代码更通用。
定义declare_matrix_ptr(name,matrix)int(*name)[matrix.w]=matrix.data
不太好看,但打字的机会较少。这有点涵盖了这一点,但我正在寻找一份浅显的副本。谢谢你的回答!我将matrix(或者确切地说是matrix*)作为一个参数传递。有没有办法进行内联转换?我尝试过(int(*)[mat mat w])mat data[r][c],但没有成功。尝试
((int(*)[mat w])(mat data))[r] [c]
[]
的演员比演员多。你只想演员
mat.data
,而不是
mat.data[r][c]
。也就是说,
((int(*)mat.w])mat data[r][c]struct matrix matrix1 = {2, 2, m1};
struct matrix matrix2 = {3, 3, m2};
#include <stdlib.h>
#include <stdio.h>

struct matrix 
{
    size_t h;
    size_t w;
    int **data;
};

int m1[2][2] = 
{
    { 1, 2 },
    { 3, 4 }
};

int m2[3][3] = 
{
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};

struct matrix init( size_t h, size_t w, int a[h][w] )
{
    struct matrix matrix = { 0 };

    matrix.data = malloc( h * sizeof( int * ) );

    if ( matrix.data )
    {
        matrix.h = h;
        matrix.w = w;
        for ( size_t i = 0; i < h; i++ ) 
        {            
            matrix.data[i] = malloc( w * sizeof( int ) );
            if ( matrix.data[i] )
            {                
                for ( size_t j = 0; j < w; j++ ) matrix.data[i][j] = a[i][j];
            }
        }
    }        

    return matrix;
}

int main( void ) 
{
    struct matrix matrix1 = init( 2, 2, m1 );
    struct matrix matrix2 = init( 3, 3, m2 );

    for ( size_t i = 0; i < matrix1.h; i++ )
    {
        for ( size_t j = 0; j < matrix1.w; j++ ) printf( "%d ", matrix1.data[i][j] );
        printf( "\n" );
    }
    printf( "\n" );

    for ( size_t i = 0; i < matrix2.h; i++ )
    {
        for ( size_t j = 0; j < matrix2.w; j++ ) printf( "%d ", matrix2.data[i][j] );
        printf( "\n" );
    }
    printf( "\n" );

    // free allocated arrays of matrix1 and matrix2
}    
1 2 
3 4 

1 2 3 
4 5 6 
7 8 9