Passando matrizes multidimensionais como argumentos da função em C

votos
46

Em C eu posso passar uma matriz multidimensional para uma função como um único argumento quando eu não sei o que as dimensões da matriz vão ser?

Além disso a minha matriz multidimensional pode conter diferentes tipos cordas.

Publicado 06/08/2008 em 21:01
fonte usuário
Em outras línguas...                            


5 respostas

votos
19

Você pode fazer isso com qualquer tipo de dados. Basta torná-lo um ponteiro ponteiro-to-:

typedef struct {
  int myint;
  char* mystring;
} data;

data** array;

Mas não se esqueça que você ainda tem que malloc a variável, e fica um pouco complexo:

//initialize
int x,y,w,h;
w = 10; //width of array
h = 20; //height of array

//malloc the 'y' dimension
array = malloc(sizeof(data*) * h);

//iterate over 'y' dimension
for(y=0;y<h;y++){
  //malloc the 'x' dimension
  array[y] = malloc(sizeof(data) * w);

  //iterate over the 'x' dimension
  for(x=0;x<w;x++){
    //malloc the string in the data structure
    array[y][x].mystring = malloc(50); //50 chars

    //initialize
    array[y][x].myint = 6;
    strcpy(array[y][x].mystring, "w00t");
  }
}

O código para desalocar a estrutura é semelhante - não se esqueça de chamar free () em tudo que você malloced! (Além disso, em aplicações robustas que você deve verificar o retorno de malloc () .)

Agora vamos dizer que você quer passar isso para uma função. Você ainda pode usar o ponteiro duplo, porque você provavelmente vai querer fazer manipulações sobre a estrutura de dados, não o ponteiro para ponteiros de estruturas de dados:

int whatsMyInt(data** arrayPtr, int x, int y){
  return arrayPtr[y][x].myint;
}

Chame esta função com:

printf("My int is %d.\n", whatsMyInt(array, 2, 4));

Saída:

My int is 6.
Respondeu 06/08/2008 em 23:34
fonte usuário

votos
31

Passar um ponteiro explícita para o primeiro elemento com as dimensões da matriz como parâmetros separados. Por exemplo, para manipular matrizes dimensionada arbitrariamente 2-d de int:

void func_2d(int *p, size_t M, size_t N)
{
  size_t i, j;
  ...
  p[i*N+j] = ...;
}

que seria chamado como

...
int arr1[10][20];
int arr2[5][80];
...
func_2d(&arr1[0][0], 10, 20);
func_2d(&arr2[0][0], 5, 80);

Mesmo princípio se aplica para arrays de maior dimensão:

func_3d(int *p, size_t X, size_t Y, size_t Z)
{
  size_t i, j, k;
  ...
  p[i*Y*Z+j*Z+k] = ...;
  ...
}
...
arr2[10][20][30];
...
func_3d(&arr[0][0][0], 10, 20, 30);
Respondeu 16/12/2009 em 16:18
fonte usuário

votos
-2
int matmax(int **p, int dim) // p- matrix , dim- dimension of the matrix 
{
    return p[0][0];  
}

int main()
{
   int *u[5]; // will be a 5x5 matrix

   for(int i = 0; i < 5; i++)
       u[i] = new int[5];

   u[0][0] = 1; // initialize u[0][0] - not mandatory

   // put data in u[][]

   printf("%d", matmax(u, 0)); //call to function
   getche(); // just to see the result
}
Respondeu 03/01/2012 em 10:51
fonte usuário

votos
15

Você pode declarar a sua função como:

f(int size, int data[][size]) {...}

O compilador fará então todo aritmética de ponteiro para você.

Note que os tamanhos dimensões devem aparecer antes da própria matriz.

GNU C permite o encaminhamento de declaração argumento (no caso de você realmente precisa passar dimensões após o array):

f(int size; int data[][size], int size) {...}

A primeira dimensão, embora possa passar como argumento também, é inútil para o compilador C (mesmo para sizeof operador, quando aplicado sobre matriz passada como argumento sempre vai tratar é como um ponteiro para o primeiro elemento).

Respondeu 08/07/2014 em 03:33
fonte usuário

votos
0

Em C eu posso passar uma matriz multidimensional para uma função como um único argumento quando eu não sei o que as dimensões da matriz vão ser?

Não

Se por "único argumento" Você quer dizer que passa apenas a matriz sem passar as dimensões da matriz, não, você não pode. Pelo menos não para os verdadeiros arrays multidimensionais.

Você pode colocar a dimensão [s] em uma estrutura juntamente com a matriz e reivindicar você está passando um "argumento único", mas isso é realmente apenas embalagem vários valores em um único recipiente e chamando esse recipiente "um argumento".

Você pode passar uma matriz do tipo conhecido e número de dimensões, mas tamanho desconhecido, passando as próprias dimensões e a matriz como este:

void print2dIntArray( size_t x, size_t y, int array[ x ][ y ] )
{
    for ( size_t ii = 0, ii < x; ii++ )
    {
        char *sep = "";
        for ( size_t jj = 0; jj < y; jj++ )
        {
            printf( "%s%d", sep, array[ ii ][ jj ] );
            sep = ", ";
        }
        printf( "\n" );
    }
}

Você chamaria essa função como esta:

int a[ 4 ][ 5 ];
int b[ 255 ][ 16 ];

...

print2dIntArray( 4, 5, a );

....

printt2dIntArray( 255, 16, b );

Da mesma forma, uma matriz de três dimensões de, por exemplo, uma struct pixel:

void print3dPixelArray( size_t x, size_t y, size_t z, struct pixel pixelArray[ x ][ y ][ z ] )
{
    ...
}

ou um 1-dimensional doublematriz:

void print1dDoubleArray( size_t x, double doubleArray[ x ] )
{
    ...
}

MAS...

No entanto, pode ser possível passar "matrizes de ponteiros para matrizes de ponteiros para ... uma matriz do tipo X" construções que são muitas vezes rotuladas de forma errada como uma "matriz multidimensional" como um único argumento, desde que o tipo base Xtem um valor de sentinela que pode ser utilizado para indicar o fim da menor nível da matriz final, de uma só dimensão de tipo X.

Por exemplo, o char **argvvalor transmitido para main()um apontador para uma matriz de ponteiros para char. A matriz inicial de char *ponteiros extremidades com um NULLvalor de sentinela, enquanto cada charmatriz referenciado pela matriz de char *indicadores termina com um NULvalor de carácter '\0'.

Por exemplo, se você pode usar NANcomo um valor de sentinela porque os dados reais não vai sempre ser um NAN, você poderia imprimir um double **como este:

void printDoubles( double **notAnArray )
{
    while ( *notAnArray )
    {
        char *sep = "";
        for ( size_t ii = 0;  ( *notAnArray )[ ii ] != NAN; ii++ )
        {
            printf( "%s%f", sep, ( *notAnArray )[ ii ] );
            sep = ", ";
        }

        notAnArray++;
    }
}
Respondeu 13/12/2019 em 12:22
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more