@sys_dev , if you are sure that a function with such a prototype will work correctly with the matrix that you described, then you can call it, for example, like this:
print((int **)&tmp[0][0], 3, 3);
The code of correctly working print() with such (foolish for a given case) prototype can be, say, like this:
void print(int **mt, int lines, int columns) { int *a = (int *)mt, i, j; // просто приведем тип к подходящему для доступа к последовательно расположенным в памяти элементам массива for (i = 0; i < lines; i++) for (j = 0; j < columns; j++) printf("%d%c", *a++, j == columns - 1 ? '\n' : ' '); }
And what to do if the print function still works with data that actually corresponds to its prototype?
Then the function expects a matrix, actually constructed as an array of pointers to rows. This is often done when creating "dynamic" matrices (i.e., an array of previously unknown size on the heap).
Typically, the code that creates such a matrix is something like
int **create_matrix (int n_lines, int n_cols) { int **res = (int **)malloc(sizeof(*res) * n_lines * n_cols); if (res) { int i; for (i = 0; i < n_lines; i++) if (!(res[i] = (int *)malloc(sizeof(**res) * n_cols))) return 0; } return res; }
And the function code print() will be, for example, like this:
void print(int **mt, int lines, int columns) { for (int i = 0; i < lines; i++) for (int j = 0; j < columns; j++) printf("%d%c", mt[i][j], j == columns - 1 ? '\n' : ' '); }
Then in the calling function you just need to make an array "adapter" (adapter), from pointers to tmp lines and pass it to print.
int *pt[3] = {&tmp[0][0], &tmp[1][0], &tmp[2][0]}; print(pt, 3, 3);
Naturally, this array can be filled dynamically (in a loop).
for (i = 0; i < 3; i++) pt[i] = &tmp[i][0];
UPDATE
And so it is still possible to write (at least in gcc 4.8.2 ).
#include <stdio.h> #include <stdlib.h> void print(int columns, int a[][columns], int lines) { int i, j; for (i = 0; i < lines; i++) { for (j = 0; j < columns; j++) printf("%d ", a[i][j]); puts(""); } } int main (int ac, char *av[]) { int t[3][4] = {{1,2,3,4}, {5,6,7,8}, {21,22,23,24}}; print(4, t, 3); return 0; }
Pay attention to the description of the int a[][columns] parameter in the print() argument list and the dynamic (by the current value also of the int columns parameter) its size!
It is with such a record that the compiler has enough information to calculate the addresses a[i][j] .