Home > front end >  How to transpose a 2 dimensional array on C via call by reference?
How to transpose a 2 dimensional array on C via call by reference?

Time:10-15

As the title says, I am trying to transpose a 2 dimensional matrix by calling by reference. I have attached my code below. When I run the code, the 2 dimensional array is unchanged.

#include <stdio.h>

#define SIZE 4

void transpose2D(int ar[][SIZE], int rowSize, int colSize);

int main()
{

    int testArr[4][4] = {
        {1, 2, 3, 4},
        {5, 1, 2, 2},
        {6, 3, 4, 4},
        {7, 5, 6, 7},
    };

    transpose2D(testArr, 4, 4);

    // print out new array
    for (int i = 0; i < 4; i  )
    {

        for (int j = 0; j < 4; j  )
        {
            printf("%d ", testArr[i][j]);
        }

        printf("\n");
    }

    return 0;
}

void transpose2D(int ar[][SIZE], int rowSize, int colSize)
{

    for (int i = 0; i < rowSize; i  )
    {
        for (int j = 0; j < colSize; j  )
        {
            int temp = *(*(ar   i)   j);
            *(*(ar   i)   j) = *(*(ar   j)   i);
            *(*(ar   j)   i) = temp;
        }
    }
}

Have been stuck for a couple of hours, any help is greatly appreciated, thank you!

CodePudding user response:

To fix your function I suggest:

  • switch element only once, the previous version swapped elements for i=a, j=b and i=b,j=a, so the matrix remained unchanged
  • use a common a[i][j] syntax
  • let the non-square matrix be embedded into a larger matrix whose inner dimensions is set to stride.
  • using VLAs to make the interface a bit more generic
void transpose2D(size_t rows, size_t cols, size_t stride, int ar[][stride]) {
    assert(rows <= stride);
    assert(cols <= stride);
    for (size_t i = 0; i < rows; i  ) {
        for (size_t j = i   1; j < cols; j  ) {
            int tmp = ar[j][i];
            ar[j][i] = ar[i][j];
            ar[i][j] = tmp;
        }
    }
}

Exemplary usage:

int testArr[4][4] = {
        {1, 2},
        {5, 1},
        {6, 3},
    };

transpose2D(3, 2, 4, testArr);

The algorithm is still very inefficient due to terrible cache miss rates on access to a[j][i]. It can be fixes by tiling and transposing smaller 8x8 blocks, but it is a topic for another day.

CodePudding user response:

This will transpose the array/matrix, you could probably get rid of colSize as as you already have a macro defining the second size

#define SIZE 500

void transpose2D(int ar[][SIZE], int rowSize, int colSize)
{
    int tmp = 0;
    for (unsigned int i = 0; i < rowSize; i  )
    {
        for (unsigned j = i; j < colSize; j  )
        {
            tmp = ar[j][i];
            ar[j][i] = ar[i][j];
            ar[i][j] = tmp;
        }
    }
}
  • Related