Есть ли в C++ заполнитель массива, подобный двоеточию Фортрана A[2][:]?


Предположим, что у меня есть массив A[n][m], и я хочу прочитать или записать в строку/столбец A.

Если бы я хотел получить доступ к третьей строке матрицы, как я могу ссылаться на нее как

A[3][:] 

Возможно ли это в C++ без использования цикла?

5 2

5 ответов:

Нет, C++ не имеет оператора, подобного [:] в Fortran. Однако в зависимости от того, в каком порядке вы храните данные-в строках или столбцах, - это можно сделать аналогично.

Во-первых, массивы на самом деле не являются первоклассными гражданами в C++. Гораздо проще работать либо с std::array (для небольших M, N, поскольку они распределены стеком), либо с std::vector.

Предположим, что мы используем 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}};

Чтобы получить одну строку из этого, мы можем просто использовать operator[]:

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

Получить столбцы, когда они находятся в главном порядке строк, сложнее. Если Вам требуются более сложные операции, использование библиотеки матриц (например, Eigen ) может быть лучшим способом.

Edit: если вы хотите заполнить всю строку нулями, это можно легко сделать с помощью std::fill в результате:

//m defined as before
std::fill(std::begin(m[0]), std::end(m[0]), 0);
Обратите внимание, что это все еще (очевидно) линейно по размеру строки. Это также может быть легко завернуто в функция:
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);
}

Если бы вы хотели заменить все значения в строке набором различных значений, вы бы использовали итераторы:

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);
}   

Вы можете взять только последнее измерение

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

Чтобы получить A[?][3] - Вам понадобится цикл

Двумерный массив-это просто массив массивов.

Таким образом, int A[10][20] объявляет массив размером 10, каждый из элементов которого является массивом размером 20, каждый из элементов которого является int.

Выражение A[3] имеет тип "array of 20 ints", и вы можете использовать его как таковой. Он распадется на int *, указывающий на первый элемент строки (предполагая, что вы думаете о них как о строках).

Для столбцов нет эквивалентного выражения; для этого вам понадобится цикл.

Если вы определяете int A[5][10], то A будет иметь 5 * 10 * sizeof (int) continue space, , в этом случае A[3][:] будет находиться в 31 '- м местоположении до 40 ' - го местоположения в этом массиве !!

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

*(p+0) to *(p+9) будет A[3][0] to A[3][9], вы можете напрямую обращаться к каждому элементу A по указателю р.

Правка:

Опечатка, это должно быть:

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

Не с регулярными массивами. std::valarray поддерживает std::slice, который допускает доступ к строкам (Шаг = 1) и доступ к столбцам (шаг=ширина строки)