Таким образом, в лекционном примере приведен следующий код
int **a;
a = new int*[10];
for (int i = 0; i < 10; ++i){
a[i] = new int[5];
for (int j = 0; j < 5; ++j){
a[i][j] = i*10+5;
}
}
И у меня есть несколько вопросов о вышеупомянутом коде (и многомерных массивах в куче вообще):
Я знаю с массивами, выделенными в стеке, незаконно использовать переменную как размер стека как
cin >> n;
int a [n];
но является ли он законным для массивов, распределенных по кучам? Как и в, a = new int [n]?
Почему это двойной указатель, указывающий на этот массив? Обычно для 1D-массивов мы использовали один указатель как int * a = new int [10]? Если бы мне захотелось значение самого элемента массива, я бы почудился дважды как ** a? Или я все еще делаю * а?
Так сказать, у меня есть 2D-массив объектов некоторого класса. Как я могу получить доступ к полю члена var i-го, j-го элемента? Что делать, если я хочу вызвать функцию-член объекта в i-м, j-м элементе?
Вам не нужно инициализировать каждый элемент массива. Если вы этого не сделаете, содержимое массива будет неопределенным. Кроме того, вы можете инициализировать нуль с помощью new int[5]()
.
a = new int[n]
работает в куче, потому что на самом деле существует вызов во время выполнения, чтобы отметить новую память для использования в качестве данных, a
указывает a
. Он не может работать в стеке, потому что компилятор должен знать, насколько большой фрейм стека для любого конкретного вызова функции, поэтому значение должно быть вычислимым во время компиляции.
Вам нужен двойной указатель, потому что a является указателем на указатель на целое число. Он указывает на массив массивов, каждый из которых должен быть разыменован при доступе к значению. Обычно вы используете [i] [j] для доступа к определенному элементу, который эффективно удваивает отклонения.
**a
дает вам первый элемент первого ряда. Обычно для доступа к элементу используется a[i][j]
. Кроме того, упоминание new int[5]()
для инициализации нулями было бы хорошо упомянуть в ответе.
Если количество столбцов в матрице известно во время компиляции, вы можете просто выделить матрицу:
int nrow = 10; // number of rows assigned at run time
int (*a)[5]; // pointer to array of 5 ints
a = new int[nrow][5]; // allocate matrix
for (int i = 0; i < nrow; ++i) // initialize matrix
for (int j = 0; j < 5; ++j)
a[i][j] = i*nrow+j;
// ...
delete[] a;
std::vector<std::vector<int>> a(5, std::vector<int>(10));
чтобы получить 5x10 нулевой инициализированный 2D-массив. Ваша лекция устарела почти на 2 десятилетия.