Двумерный массив в C++ чаще всего делают через vector<vector<int>>.
По сути это просто массив массивов: каждый элемент внешнего массива —
это отдельная строка, которая сама является обычным массивом.
Поэтому всё работает почти так же, как с обычным vector:
можно создавать массив, обращаться к элементам, менять размеры,
добавлять строки и передавать его в функции.
#include <vector>
using namespace std;
vector<vector<int>> a; // пока пустой двумерный массив
vector<vector<int>> b(3, vector<int>(4));
// 3 строки, в каждой по 4 элемента
// сейчас b — это таблица 3 × 4
vector<vector<int>> c(2, vector<int>(5, 7));
// 2 строки, 5 столбцов, каждый элемент равен 7
vector<vector<int>> a(3, vector<int>(4, 0));
// a[i] — это целая строка
// a[i][j] — конкретный элемент
a[1][2] = 10; // изменить элемент во 2-й строке и 3-м столбце
int rows = a.size(); // число строк
int cols = a[0].size(); // число столбцов, если строки не пустые
a.push_back(vector<int>(4, 1));
// добавить новую строку [1, 1, 1, 1] в конец
a.resize(5);
// теперь строк станет 5
// новые строки будут пустыми
for (int i = 0; i < a.size(); ++i) {
a[i].resize(4);
}
// теперь в каждой строке по 4 элемента
int n, m;
cin >> n >> m;
// создаём таблицу n × m
vector<vector<int>> a(n, vector<int>(m));
// считываем элементы
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cin >> a[i][j];
}
}
// выводим таблицу
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (j > 0) cout << ' ';
cout << a[i][j];
}
cout << '\n';
}
void change(vector<vector<int>> &a) {
a[0][0] = 100; // массив изменится
}
void print(const vector<vector<int>> &a) {
// можно читать массив, но нельзя менять
}
vector<vector<int>> make_table(int n, int m) {
vector<vector<int>> a(n, vector<int>(m, 0));
return a;
}
a[i] // строка
a[i][j] // элемент
a.size() // число строк
a[0].size() // число столбцов, если строки не пустые