Question

Supposing I have an array A[n][m], and I want to read or write to a row/column of A.

If I wanted to access the third row of the matrix, how can I reference it like

A[3][:] 

Is this possible in C++ without using a loop?

Was it helpful?

Solution

No, C++ has no operator similar to [:] in Fortran. Depending on whether you are storing things in row major or column major order, this can be done in similar ways however.

Firstly, arrays aren't really first class citizens in C++. It's much easier to work with either std::array (for small M, N as these are stack allocated), or std::vector.

Let's assume we're using a std::vector:

template <typename T>
using matrix<T> = std::vector<std::vector<T>>;

matrix<int> m = {{1,2,3}, {4,5,6}, {7,8,9}};

To get a single row out of this, we can simply use operator[]:

auto& row = m[0];  // Returns a std::vector<int>& containing {1, 2, 3}

Getting columns when it is in row major order is more difficult. If you require more sophisticated sort of operations, using a matrix library (like Eigen) might be a better way to go.

Edit: If you wanted to fill an entire row with zeros, this can be done easily with std::fill on the result:

//m defined as before
std::fill(std::begin(m[0]), std::end(m[0]), 0);

Note that this is still (obviously) linear in the size of the row. This could also easily be wrapped in a function:

template <typename T>
void clear_row(matrix<T>& m, std::size_t row, const T& new_value)
{
    std::fill(std::begin(m[row]), std::end(m[row]), new_value);
}

If you wanted to replace all the values in a row with a set of different values, you'd use iterators:

template <typename T, typename Iterator>
void modify_row(matrix<T>& m, std::size_t row, Iterator new_start)
{
    std::copy(std::begin(m[row]), std::end(m[row]), new_start);
}   

OTHER TIPS

You can only take the last dimension

int A[3][5];
int * x = A[2];
int y = x[3];

To get A[?][3] - you would need a loop

A 2D array is just an array of arrays.

So int A[10][20] declares an array of size 10, each of whose elements is an array of size 20, each of whose elements is an int.

The expression A[3] has type "array of 20 ints", and you can use it as such. It will decay into an int * pointing to the first element of the row (assuming you are thinking of them as rows).

There is no equivalent expression for the columns; you will need a loop for that.

if you define int A[5][10] , then A will have 5 * 10 * sizeof(int) continue space, , in this case , A[3][:] would be in 31'th location to 40'th location in this array !!

int* p = &(A[30]) ;

*(p+0) to *(p+9) will be A[3][0] to A[3][9] , you can directly access each element of A by the pointer p .

Edit :

typo , it should be :

int* p = &(A[3][0]) ;

Not with regular arrays. std::valarray supports std::slice, which does allow for row access (stride = 1) and column access (stride=row width)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top