How to get column of a multidimensional array in C/C++?

43,597

Solution 1

In C/C++, multidimensional arrays are actually stored as one dimensional arrays (in the memory). Your 2D matrix is stored as a one dimensional array with row-first ordering. That is why getting a column out of it is not easy, and not provided by default. There is no contiguous array in the memory that you can get a pointer to which represents a column of a multidimensional array. See below:

When you do p=matrix[0], you are just getting the pointer to the first element matrix[0][0], and that makes you think that you got the pointer to first row. Actually, it is a pointer to the entire contiguous array that holds matrix, as follows:

matrix[0][0]
matrix[0][1]
matrix[0][2]
.
.
matrix[1][0]
matrix[1][1]
matrix[1][2]
.
.
matrix[8][0]
matrix[8][1]
matrix[8][2]
.
.
matrix[8][8]

As seen above, the elements of any given column are separated by other elements in the corresponding rows.

So, as a side note, with pointer p, you can walk through the entire 81 elements of your matrix if you wanted to.

Solution 2

There is no difference between specifying matrix[81] or matrix[9][9]

matrix[r][c] simply means the same as matrix[9*r+c]

There are other containers better suited fort multidimensional arrays like boost::multi_array

http://www.boost.org/doc/libs/1_53_0/libs/multi_array/doc/index.html

Think of the bare array just like allocating a contiguous piece of memory. You, the programmer then has to handle this piece of memory yourself. The bare name of the array, e.g. matrix is a pointer to the first element of this allocated piece of memory. Then *(matrix+1) is the same as matrix[0][1] or matrix[1].

Solution 3

p is an array of int, matrix[0] is a pointer..

Solution 4

matrix itself is the nearest thing you can get to a column of the array, inasmuch as (matrix + 1)[0][0] is the same as matrix[1][0].

Share:
43,597
Qbik
Author by

Qbik

Updated on July 27, 2021

Comments

  • Qbik
    Qbik almost 3 years
    int matrix[9][9],*p;
    p=matrix[0]; 
    

    this works and gives first row of matrix, but how to get first column of matrix I've tried p=matrix[][0]; ? Also I don't understand why below code gets compiler error ?

    int matrix[9][9],p[9];  // it looks really ugly, byt why it doesn't work ?
    p=matrix[0];            // compiler gives "invalid array assigment"
    

    is it because multidimensional arrays are arrays of arrays - and we should interpret matrix[i][j] as j-th element of i-th nested array ?

  • Carl Norum
    Carl Norum about 11 years
    "Stored as one-dimensional arrays" is a bit of an odd way to put it. They're just arrays of arrays, so I'll grant that the memory layout is similar, but the semantics are a bit different.
  • meyumer
    meyumer about 11 years
    Semantics are different yes, I was referring to the memory layout. I will re-write that part.
  • zzk
    zzk about 11 years
    @Qbik *(matrix[0]) is an int, you can't assign an int to an int array
  • Qbik
    Qbik about 11 years
    now I get it ! I've printed *p and data was correct, but it was only pointer to single int
  • Qbik
    Qbik about 11 years
    @meyumer mistake, sorry, they are really next to each other in memory
  • Thomas Matthews
    Thomas Matthews about 11 years
    Are you positive that matrix[81] is the same as matrix[9][9]? My understanding is that matrix[9][9] is equivalent to int * matrix[9], which means that it is a container of pointers, not contiguous memory locations.
  • AxelOmega
    AxelOmega about 11 years
    When you asked I became unsure. So I looked it up and now I am sure. See here for example stackoverflow.com/questions/7784758/…
  • AxelOmega
    AxelOmega about 11 years
    I need to make a small correction to this. From a memory layout point of view there is no difference. But if the compiler has information about the original array declaration there is a difference on how it is interpreted. For example matrix[R][C] can be accessed linearly from a pointer int* mp (int*)matrix, the cast is needed to avoid warnings. You can access rows as int (row_ptr*)[C] = matrix then pointer arithmetic will ensure you move one whole row, e.g. (row_ptr+1) will point to the second row. Also value access has to be **(row_ptr+1). There are however no pointers in memory.