tags:

views:

43

answers:

3

I need to print out a 3 by 3 matrix in C. I could think up of 3 different ways of doing it. Are all of them equally optimal or is one method better than the other?

Function 1: Passing an 2darray, using array subscripts

void printMatrix(int m[][3])
{
 int i,j;

 for(i=0;i<3;i++)
 {
  for(j=0;j<3;j++)
  {
   printf("%d\t",m[i][j]);
  }
  printf("\n");
 }
}

Function 2: Passing a dbl pointer, using ptr arithmetic

void printMatrix(int **m)
{
 int i,j;

 for(i=0;i<3;i++)
 {
  for(j=0;j<3;j++)
  {
   printf("%d\t", *(*(m+i)+j) );
  }
  printf("\n");
 }
}

Function 3: Passing a dbl pointer, using ptr arithmetic (again)

void printMatrix(int **m)
{
 int i,j;

 for(i=0;i<3;i++)
 {
  for(j=0;j<3;j++)
  {
   printf("%d\t",**m);
   (*m)++;
  }
  (*m)=(*m)-3;
  m++;
  printf("\n");
 }
}
+1  A: 

They are all pretty much the same thing internally. Arrays are essentially pointers with offsets. Personally, I think the first is easier to read so I would stick with that one.

Starkey
+1 - optimise for readabilty _first_. Any decent compiler will figure out the best way for you at this micro-optimisation level. Better return on investment will come at the macro level (algorithm selection and so forth).
paxdiablo
A: 

It doesn't matter! :-)

Really! The best method is the one you like best.

pmg
+2  A: 

Function 1 operates on a different data type than functions 2 and 3.

For function 1, the data has to be defined as int foo[3][3] or allocated as a block of 9 ints. With C89, the second 3 must be a compile-time constant, which could be problematic. This could be worked around by passing a simple int * and indexing using matrix[i * dim2 + j]. If you have C99, you can use variable length arrays and variably modified types to keep the nice matrix[i][j] notation, but the declarations may be a bit more complicated and there are some restrictions.

Functions 2 and 3 work on several pieces of data: an array of integer pointers which point to additional arrays of integers. The extra indirection may allow some ease of use and flexibility (for example, a triangular matrix) but may reduce performance.

The choice between function 2 and function 3 is pretty clear to me: use function 2. Changing a data structure for what should be a read-only operation should be avoided if possible, even if you put it back the way it was: it prevents concurrent use and you might do the "put it back" part incorrectly, leading to hard to diagnose problems. The expression *(*(m+i)+j) can be changed to m[i][j] even though it does something different.

jilles