I haven't tested this yet, and I don't know if it works, but the following should give you a starting point. Pointer arithmatic (sometimes) works with 2 dimensional arrays, and I think using pointers for a traversal of the array is a bit simpler than the alternative (given the needed comparisons in the following algorithm). For clarity's sake, I've used a simple bubble sort. You can certainly find a more efficient algorithm if you're worried about performance.
int array[ size1 ][ size2 ] = ...;
int *temp,
*ptr;
for (j = 0; j < size1 * size2 - 1; j++ )
for (i = 0, ptr = &array[ 0 ][ 0 ]; //reset ptr & i
i < size1 * size2 - 1; i++ )
{
if ( *(temp = ptr) > *(++ptr) )
swap( temp, ptr ); //user defined function
}