I'm assuming that the initial call to this function will always start with arrays of the same size.
Code:
#define SIZE 5
void foo ( int arr[SIZE][SIZE], int size ) {
int r, c;
if ( size == 0 ) return;
for ( r = 0 ; r < size ; r++ ) {
for ( c = 0 ; c < size ; c++ ) {
foo( arr, size-1 );
}
}
}
int main() {
int a[SIZE][SIZE];
foo( a, SIZE );
return 0;
}
Each recursive call to foo 'removes' the last row and last column from being processed.
The array is passed as a pointer, so all you're doing is just using less of the memory you're pointing at each time around.
If you want to shrink the array to some corner other than [0][0], then that's easy enough to achieve with a few extra parameters to define the effective bounds of the array.