1

I was asked to write a program that gets a two dimensional array (a matrix), number of columns,and number of rows, and the program will return the transpose matrix (without using a [][], meaning only using pointer arithmetics)

The program I wrote, does indeed transpose the matrix, it is no problem. My problem is understanding how to return. here's my code:

int** transpose_matrix(matrix mat1,int number_of_rows,int number_of_columns)
{
    matrix mat2;
    int row_index,column_index;
    for(row_index=0;row_index<number_of_rows;row_index++)
    {
        for(column_index=0;column_index<number_of_columns;column_index++)
            **(mat2+(column_index*number_of_rows)+row_index)=**(mat1+(row_index*number_of_columns)+column_index);
    }
    // at this point, mat2 is exactly the transpose of mat1
    return mat2;
}

now here's my problem: I can't return a matrix, closest thing I can do is return the address of the first value of the matrix, but even if i do that, all the rest of the matrix will be unusable as soon as i exit transpose_matrix function back into void main...How can I return mat2?

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
Oria Gruber
  • 1,513
  • 2
  • 22
  • 44

2 Answers2

0

One, a two-dimensional array is not a double pointer.

Two, dynamic allocation. If matrix is a two-dimensional array type, then write something like this:

typedef int matrix[ROWS][COLUMNS];
typedef int (*matrix_ptr)[COLUMNS];

matrix_ptr transpose_matrix(matrix m, int rows, int cols)
{
    matrix_ptr transposed = malloc(sizeof(*transposed) * rows);
    // transpose, then
    return transposed;
}
  • @qPCR4vir Why are you shouting? –  Mar 19 '13 at 21:03
  • Anyway, I want to make +1 you, but I want to see the "// transpose, then " part first. – qPCR4vir Mar 19 '13 at 21:13
  • @qPCR4vir Sorry but that's not relevant. OP has already written the code for transposition, he was merely asking for a way to return an entire matrix. –  Mar 19 '13 at 21:17
  • @qPCR4vir Why wouldn't it? –  Mar 19 '13 at 21:20
  • Maybe Im wrong, but '**(transposed+i)' is '*((int**)transposed+i*COLUMNS)' ?? – qPCR4vir Mar 19 '13 at 21:26
  • @qPCR4vir What you wrote is a syntax error. `transposed` is a [pointer-to-array](http://c-faq.com/aryptr/ptrtoarray.html). –  Mar 19 '13 at 21:28
  • Yes that ias exactly the problem. The OP code is for pointer to int, and not for a pointer to an array of COLUMNS int (to an array of ROWS int could be better?? it is stransposed). – qPCR4vir Mar 19 '13 at 21:34
  • Guys I'm really new at all of this, can you explain to me what the argument is about? maybe I can learn something. And also, explain the code you wrote. Assume I'm stupid. (and the code for my transpose does work, the problem is with the return) – Oria Gruber Mar 19 '13 at 21:35
  • @qPCR4vir OP's code assumes that the matrix is represented as a 2D array. Unless you want to manually spell out ugly indexing like `ptr[rows * column + row]`, you can use a pointer-to-array and let the compiler do the indexing for you safely. Whether the pointer is to `int[ROWS]` or to `int[COLUMNS]` entirely depends on the code OP has so far. –  Mar 19 '13 at 21:39
0

OK: Here you have 3 thing:

  1. You cannot return a pointer to a local variable (it will be garbage after return and the stack (memory) where it was is reused).
  2. Array decay to pointer to the first element when passed.
  3. Pointer arithmetic: p+1 increment the adress in p by sizeof(*p), so p point to the next element, not to the next byte.

The simple fix for your code (this works for any matrix size) :

    int* transpose_matrix(int *mat1,int number_of_rows,int number_of_columns)
    {
        int *mat2=malloc(number_of_rows*number_of_columns*sizeof(int));
        int row_index,column_index;
        for(row_index=0;row_index<number_of_rows;row_index++)
        {
            for(column_index=0;column_index<number_of_columns;column_index++)
                mat2[column_index*number_of_rows+row_index]=mat1[row_index*number_of_columns+column_index];
        }
        // at this point, mat2 is exactly the transpose of mat1
        return mat2;
    }

...
    print(m,r,c); // I hope you have a print()
    int *t=transpose_matrix(m,r,c);
    print (t,c,r);
...
    // use t[max: c-1][max: r-1]
    free(t);

If we have only fixed size matrix (well with C99 we can use varable length array too!).

typedef int  Matrix[ROWS][COLUMNS];
typedef int TMatrix[COLUMNS][ROWS];
typedef int (*pMatrix)[COLUMNS]; 
typedef int (*pTMatrix)[ROWS];  

pTMatrix transpose_matrix(Matrix m , int rows, int cols)
{
    pTMatrix t = malloc(sizeof(*t)*cols);
    for (int r=0; r<rows ; ++r)
    for (int c=0; r<cols ; ++r)
      t[c][r]=m[r][c];
    return t;
}

Well, if rows and cols are fixed you dont need to pass it.... hmmm...

qPCR4vir
  • 3,521
  • 1
  • 22
  • 32
  • Okay, this seems to work, but I have another problem now, I need to print the transpose matrix, but you have declared m to be a pointer to an integer, so you've turned the 2d array into a 1d array, how do I print the transpose matrix? – Oria Gruber Mar 19 '13 at 21:56
  • Using the ugly indexing like ptr[rows * column + row], :-( – qPCR4vir Mar 19 '13 at 22:16