簡體   English   中英

指向未知大小的現有2d數組的指針?

[英]Pointer to existing 2d array of unknown size?

我有以下內容:

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

編輯

要回答評論,您可以使用復合文字,如下所示。 這樣你可以用[i][j]訪問它

#include <stdio.h>

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

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

struct matrix matrix2 = {3, 3, m2};

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

您可能對C99的可變長度數組感興趣。 此解決方案不直接回答您關於如何使用正確類型的data初始化結構的問題(不能); 但是你可以使用一個簡單的指針存儲數組的地址,然后在使用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;
}

示例會話:

$ gcc -std=c99 -Wall -o 2d-matrix 2d-matrix.c && ./2d-matrix
Address of matrix: 0x100402020
1 2 3
4 5 6
7 8 9
10 11 12
Address of matrix: 0x100402020
1 2 3
4 5 6
7 8 9
10 11 12
Address of matrix: 0x100402020
1 2 3
4 5 6
7 8 9
10 11 12

您可能不會像這樣初始化結構

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
}    

程序輸出是

1 2 
3 4 

1 2 3 
4 5 6 
7 8 9 

您還需要編寫一個函數來釋放結構的已分配內存。

編譯器必須支持可變長度數組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM