Passing multidimensional arrays as function arguments introduces some headaches. Remember that in most contexts, an expression of array type will be implicitly converted to a pointer type, and its value will be the address of the first element of the array. So for example, a 10x20 array of int will be converted to a pointer to a 20-element array of int:
void swap(int (*surface)[20], size_t rows, size_t x1, size_t x2,
size_t y1, size_t y2)
{
int temp;
assert(x1 < rows && x2 < rows);
temp = surface[x1][y1];
surface[x1][y1] = surface[x2][y2];
surface[x2][y2] = temp;
}
int main(void)
{
int surface[10][20];
...
swap(surface, 10, 1, 1, 2, 2);
...
}
Here's where a big problem shows up. Based on its prototype, swap() can only deal with Nx20 arrays of int; the number of rows can vary, but the number of columns cannot, because T (*)[N]
is a different type from T (*)[M]
where N != M. Ideally you'd like a function that can deal with an arbitrary number of rows and columns. One way to accomplish that is to treat the array as a 1D array of T, and compute row and column offsets manually:
void swap(int *surface, size_t rows, size_t cols, size_t x1,
size_t x2, size_t y1, size_t y2)
{
int temp;
assert(x1 < rows && x2 < rows && y1 < cols && y2 < cols);
temp = surface[x1*cols+y1];
surface[x1*cols+y1] = surface[x2*cols+y2];
surface[x2*cols+y2] = temp;
}
int main(void)
{
int surface[10][20];
...
swap(&surface[0][0], 10, 20, 1, 1, 2, 2);
}
Here we pass the address of the first element (&surface[0][0]) and treat it as a simple pointer to int. That way we can deal with any number of rows and columns. Note that this will only work for actual 2D arrays (not arrays of pointers), since swap assumes that the array elements are laid out contiguously.