I tried to explain the bit about treating the two dimensional array as a
one dimensional array in the comment above my code. Here is a more thorough
explanation:
Yes, the original matrix is 2 dimensional. The problem is that, in order to
figure out where the elements of an array are, the compiler needs to be told
about the size of all but the first dimension. In this case, you could declare
(1) void flip(int mat[10][10], int size)
and you could also declare
(2) void flip(int mat[][10], int size)
but it wouldn't work with
(3) void flip(int mat[][], int size)
because the compiler needs to know how many elements are in a row in order to
locate elements in the nth row.
You don't see this problem with 1 dimensional arrays because it's OK to leave
out the dimension. A 1 dimensional array is just a bunch of items strung out
in a long line, and giving the size doesn't tell the compiler anything it
really needs.
As I said, (1) and (2) would work fine but then the function would only work
for matrices of size 10, and we always try to make our routines general
enough so that they can be used for different data.
My solution, above, is based on the fact that we know how data is laid out in
memory. Given an array like this:
a b c
d e f
g h i
we know that in memory, it's really just a one dimensional list like this:
a b c d e f g h i
so instead of passing in a 2 dimensional array, I took the address of (a),
told the compiler I was passing in a pointer to 1 or more integers, then I
used this pointer like a 1 dimensional array, and did all the math myself.
If the pointer is called mat, then mat[0] is the same as *mat, and then 'a'
is mat[0], 'b' is mat[1] and so forth. How about 'g'? In the original matrix,
it's at [2][0]; you need to skip 2 rows to get to it. Since we know each row
has 3 columns, we know it's in mat[6]. Similarly, to get to 'h', you skip
down 2 rows (that's 6) and 1 column (add 1 more) so you end up in mat[7].
Generalizing this, assuming the original array, call it 'matrix,' is square
(and it needs to be, for a diagonal to be meaningful) and both of its
dimensions are 'size', then matrix[row][col] is (row*size + col) away from
the beginning of the array, and this is exactly the subscript to use if the
array is 1 dimensional.
So what I did was treat the 2 dimensional array as a 1 dimensional array
and took it upon myself to do the math that the compiler does if it knows
the dimensions of the 2 dimensional array.
This is one of the bits of trickery that C allows you to do by being very
free with interconversions of arrays and pointers. It also works in older
versions of FORTRAN and (probably, for upward compatibility) C++, but not
in most other programming languages.
For those of you who feel really weird doing this kind of thing, I'm happy
to report that there's a less tricky solution available, which I'll present
in my next message.