imprimir - C inicializar matriz dentro de la estructura
typedef struct c ejemplo (5)
Quiero tener una matriz de longitud variable dentro de una estructura, pero tengo problemas para inicializarla correctamente.
struct Grid {
int rows;
int cols;
int grid[];
}
int main() {
struct Grid testgrid = {1, 3, {4, 5, 6}};
}
Todo lo que intento me da un error ''error: inicialización no estática de un miembro de matriz flexible''.
Aquí está mi versión:
#include <stdio.h>
struct matrix {
int rows;
int cols;
int **val;
} a = { .rows=3, .cols=1,
.val = (int*[3]){ (int[1]){1},
(int[1]){2},
(int[1]){3} } },
b = { .rows=3, .cols=4,
.val = (int*[3]){ (int[4]){1, 2, 3, 4},
(int[4]){5, 6, 7, 8},
(int[4]){9,10,11,12} } };
void print_matrix( char *name, struct matrix *m ){
for( int row=0;row<m->rows;row++ )
for( int col=0;col<m->cols;col++ )
printf( "%s[%i][%i]: %i/n", name, row, col, m->val[row][col] );
puts("");
}
int main(){
print_matrix( "a", &a );
print_matrix( "b", &b );
}
No creo que esto sea posible o compatible. Como señala DigitalRoss , puede inicializar desde un literal en el caso de matrices static
... aunque todavía no estoy seguro de si esto está incluido en la extensión estándar o simplemente en una extensión común. Parece que no puedo encontrar una cláusula en el estándar que admita la inicialización literal de matrices flexibles aunque puedo ver que gcc lo admite explícitamente .
No tiene una matriz de longitud variable (VLA) en su estructura. Lo que tienes en tu estructura se llama miembro flexible de la matriz . El miembro de matriz flexible no tiene absolutamente nada que ver con VLA. Los miembros flexibles de la matriz en C existen para legalizar y soportar la vieja jerga de "struct hack", que se basa en la asignación dinámica de memoria para objetos struct con matrices finales de diferentes tamaños.
Los miembros de matriz flexibles no se pueden inicializar con inicializadores agregados, que es lo que parece intentar en su código. Lo que estás tratando de hacer aquí es simplemente imposible. No hay tal característica en C.
Mientras tanto, el texto del mensaje de error generado por el compilador parece sugerir que admite algo así como una extensión. Esto podría ser cierto, pero tenga en cuenta que esto no es de ninguna manera una característica estándar de C.
Puede hacer que funcione en gcc haciendo que la estructura sea static
o global, pero resulta que la inicialización de los miembros flexibles de la matriz no es conforme y por lo tanto es probable que no funcione, excepto con gcc. Aquí hay una manera de hacerlo que solo usa características que cumplen con C99 ...
#include <stdlib.h>
#include <stdarg.h>
typedef struct Grid {
int rows;
int cols;
int grid[];
} *Grid;
Grid newGrid(int, int, ...);
Grid newGrid(int rows, int cols, ...)
{
Grid g;
va_list ap;
int i, n = rows * cols;
if((g = malloc(sizeof(struct Grid) + rows * cols * sizeof(int))) == NULL)
return NULL;
g->rows = rows;
g->cols = cols;
va_start(ap, cols);
for(i = 0; i < n; ++i)
g->grid[i] = va_arg(ap, int);
va_end(ap);
return g;
}
.
.
.
Grid g1, g2, g3;
g1 = newGrid(1, 1, 123);
g2 = newGrid(2, 3, 1, 1, 1,
2, 2, 2);
g3 = newGrid(4, 5, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10,
11, 12, 13, 14, 15,
16, 17, 18, 19, 20);
Una versión que usa malloc:
#include <stdio.h>
#include <stdlib.h>
typedef struct Grid {
int rows;
int cols;
int *grid;
} Grid;
/* Should validate params */
Grid
buildGrid(int rows, int cols, int vec[]) {
Grid grid;
grid.rows = rows;
grid.cols = cols;
int i;
if ( (grid.grid = malloc(sizeof(vec))) == NULL ) {
/* do something.*/
}
for(i = 0; i < sizeof(vec) ; i++ ) {
grid.grid[i] = vec[i];
}
return grid;
}