You may be interested in the variable length arrays of C99. This solution does not directly answer your question about how to initialize the structure with a properly typed data (one can't); but you can use a simple pointer to store the array's address and then cast to the variable length array pointer when using struct matrix.
The user side would just call functions like printFroMat() which receive a single argument of type struct matrix; the code inside these functions (so to speak, the library implementation) would perform the somewhat unsightly casts, as demonstrated. The typedef makes the cast perhaps a little more understandable because it demonstrates where the variable name in a declaration would go.
Note that the funny sizeof(m2)/sizeof(*m2) etc. are not strictly necessary, you can just say 3. But the sizeof expression automatically stays in sync with the actual matrix size, which quickly becomes a real asset.
You can pass "arrays" (in fact: still just addresses, but of a known array type) together with their dimensions as parameters to functions, and index them the normal way (below in printMatrix). Example:
#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;
}
Sample session:
$ 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