How to get column of a multidimensional array in C/C++?
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]
.
Qbik
Updated on July 27, 2021Comments
-
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 ofmatrix
I've triedp=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 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 about 11 yearsSemantics are different yes, I was referring to the memory layout. I will re-write that part.
-
zzk about 11 years@Qbik *(matrix[0]) is an int, you can't assign an int to an int array
-
Qbik about 11 yearsnow I get it ! I've printed *p and data was correct, but it was only pointer to single int
-
Qbik about 11 years@meyumer mistake, sorry, they are really next to each other in memory
-
Thomas Matthews about 11 yearsAre you positive that
matrix[81]
is the same asmatrix[9][9]
? My understanding is thatmatrix[9][9]
is equivalent toint * matrix[9]
, which means that it is a container of pointers, not contiguous memory locations. -
AxelOmega about 11 yearsWhen you asked I became unsure. So I looked it up and now I am sure. See here for example stackoverflow.com/questions/7784758/…
-
AxelOmega about 11 yearsI 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 pointerint* mp (int*)matrix
, the cast is needed to avoid warnings. You can access rows asint (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.