Is it possible to slice a column from 2d array in C

Viewed 329

When I wish to slice a row from a 2-D array in c I can do the following:

void PrintArray(int *arr, int arr_size);
int main(){
    int arr[4][4] = {
            {10, 13, 56, 66},
            {23, 57, 59, 67},
            {36, 70, 74, 75},
            {40, 75, 80, 91}
    };
    PrintArray(arr[2], 4);
    return 0;
}

void PrintArray(int *arr, int arr_size) {
    int i;

    for (i = 0; i < arr_size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

Which prints:

36 70 74 75

I was wondering if it's possible to do the same column-wise in some elegant/efficient way.

I could transpose the matrix and do the same but it so cumbersome to do it that way.

Note:

I suspect that it might not be possible, but I was wondering if there is a more educated answer to whether it's possible or not.

2 Answers

If you cast your array as (int*), then you can define this function:

void PrintCol (int *arr, int col, int row_size, int arr_size) {
    int i;
    for (i = col; i < arr_size; i += row_size) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

And call it like this, assuming you want to print column offset 1.

PrintCol((int*)arr, 1, 4, 16);

Whose output should look like this:

$ gcc slice.c && ./a.out
13 57 70 75

One thing you should do is compare the PrintArray for loop with the one in PrintCol.

The only difference between the assembly generated should be the instruction for how i is assigned initially and how i is incremented.

In that sense, PrintArray is indeed more efficient but not by much. The cost of "transpose matrix plus PrintArray" will always(?) be more than "PrintCol".

No elegant or effective way as such exists, because arrays are essentially raw memory, but a matrix is an application-layer concept.

It just so happens that an array of 4 int[4] arrays can be accessed by letting array number n decay into a pointer to the first element, because that's how items are guaranteed to be laid out in memory (from LS address to MS address, "left to right"). But there is no particularly elegant trick to do the other way around, short of accessing each array item with arr[i][j].

Notably, you could chose to create a matrix either as mat [row][col] or mat[col][row] on the application layer. The left-most dimension/index of an array of arrays doesn't necessarily have to correspond to the mathematical definition of a matrix in the application.

Related