Tablica to nie wskaźnik i jest to jedno z miejsc gdzie mozna sie na tym przejechać.
Po pierwsze - nie byłoby problemu gdybyś tablice wielowymiarową zadeklarował dynamicznie:
int n=10, m=15;
int ** t2d = new int*[n];
for (size_t i = 0; i < n; i++) {
t2d[i] = new int[m];
}
A jeśli faktycznie chcesz przekazać tablice alokowaną statycznie:
int tab[10][15];
To typ argumentu musi być wskaźnikiem na tablice 15 elementową, który można zapisać tak:
void f(int tab[][15])
lub tak:
void f(int(*tab)[15])
Musisz deklarować zewnętrzny rozmiar tablicy, bo taka tablica w pamieci wygląda jak tablica 1d - elementy sa rozlozone w pamieci w sposob ciagly, a kompilator pilnuje, żeby odwołania [0][2] dobierały sie do odpowiedniego elementu w tablicy 1d:
int tab[2][3];
int int int int int int
tab[0] | tab[1]
Dlatego nie da sie jej zrzutować na podwójny wskaźnik.
Jako ciekawostke w języku C można było zaalokować tablice 2d w ten sposob:
int(*t2d)[15] = malloc(sizeof(int) * 10 * 15);
i odwoływać się do niej normalnie dwoma parami nawiasow kwadratowych:
t2d[0][3] = 10;
EDIT: w C++ też można :D
int(*t2d)[3] = reinterpret_cast<int(*)[3]>(new int[2*3]);
ale to raczej jako ciekawostka, nie polecam :P