Reputation: 6147
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 ?
Upvotes: 5
Views: 52810
Reputation: 3548
C++23 solution using drop & stride views, to create a view on the column elements.
#include <ranges>
#include <print>
#include <vector>
int main()
{
const auto nrColumns = 3;
const auto nrRows = 3;
const int matrix[nrRows][nrColumns] = { 1, 2, 3, 11, 22, 33, 111, 222, 333 };
const auto values = std::span(matrix[0], nrRows * nrColumns);
const auto columnIndex = 1;
const auto columnView = values | std::views::drop(columnIndex) | std::views::stride(nrColumns);
for(const auto& value : columnView)
{
std::print("{0}, ", value);
}
}
Returns 2, 22, 222,
Try it yourself: https://godbolt.org/z/bG5Md4zs7
Upvotes: 1
Reputation: 11
Here's a program which builds a 10x10 array and prints the second column:
#include <iostream>
using namespace std;
int main()
{
int aa[10][10];
for(int i = 0; i<10; i++)
for(int j = 0; j<10; j++)
aa[i][j] = i*10+j;
int col = 2;
// pointer to a length-10 1d array
int (*p)[10] = (int (*)[10])&(aa[0][col]);
for(int i =0; i<10; i++)
cout << *(p[i]) << endl;
return 0;
}
The difference from aa[row][2] is using a pointer to a length-10 1d int array int (*p)[10]
, For more context about int (*p)[10]
, see this answer
p
saves the address of 1d array {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
. And p+1
saves the address of 1d array {12, 13, 14, 15, 16, 17, 18, 19, 20, 21}
. *(p[1])
or *(*(p+1))
access the first value of 1d array.
Upvotes: 1
Reputation: 31
I don't know if this is a efficient solution but by doing this way I'm able to get the column,
int arr[9][2] = { {2, 57}, {3, 66}, {4, 73}, {5, 76}, {6, 79}, {7, 81}, {8, 90}, {9, 96}, {10, 100}};
int c[18];
int co = 0;
for (auto & i : arr) {
for (int j : i) {
c[co++] = j;
}
}
for (int i = 0; i < co; ++i) {
if (i % 2 != 0)
std::cout << c[i] << " ";
}
Upvotes: 0
Reputation: 1
For static declared arrays you can access them like continuous 1D array, p = matrix[0]
will give you the 1st column of 1st row. Then the 1D array can be accessed like p[i]
, *(p+i)
, or p[current_raw * raw_size + current_column)
.
The things are getting tricky if a 2D array is represented with **p
as it will be interpreted as an array of pointers to 1D arrays.
Upvotes: 0
Reputation:
You can get the first column using a loop like
for(int i = 0; i < 9; i++)
{
printf("Element %d: %d", i, matrix[i][0]);
}
I think the assignment doesn't work properly because you're trying to assign something's that's not an address to a pointer.
(Sorry this is c code)
Upvotes: 8
Reputation: 5064
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.
Upvotes: 16
Reputation: 972
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]
.
Upvotes: 4
Reputation: 57678
If you want your matrix to contiguous locations, declare it as a one dimensional array and perform the row and column calculations yourself:
int contiguous_matrix[81];
int& location(int row, int column)
{
return contiguous_matrix[row * 9 + column];
}
You can also iterate over each column of a row:
typedef void (*Function_Pointer)(int&);
void Column_Iteration(Function_Pointer p_func, int row)
{
row = row * MAXIMUM_COLUMNS;
for (unsigned int column = 0; column < 9; ++column)
{
p_func(contiguous_matrix[row + column]);
}
}
Upvotes: 0
Reputation: 55392
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]
.
Upvotes: 1