Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР15-С++24-мая-2012.doc
Скачиваний:
23
Добавлен:
23.09.2019
Размер:
1.07 Mб
Скачать

1.5.7. Динамические массивы

Если количество элементов массива определяется в процессе выполнения программы, используют динамическое выделение оперативной памяти компьютера.

Если до начала работы программы неизвестно, сколько в массиве элементов, в программе используют динамические массивы. Память под них выделяется с помощью оператора new во время выполнения программы. Адрес начала массива хранится в переменной, называемой указателем. Например.

int n=20;

int *a = new int[n];

Здесь описан указатель a на целую величину, которому присваивается адрес начала непрерывной области динамической памяти, выделенной с помощью оператора new. Выделяется столько памяти, сколько необходимо для хранения n величин типа int. Величина n может быть переменной.

Примечание: Обнуление памяти при ее выделении не происходит. Инициализировать динамический массив нельзя.

Обращение к элементу динамического массива осуществляется так же, как и к элементам обычного массива. Например: a[0], a[1], …, a[9].

Можно обратиться к элементу массива другим способом: *(a+1), …,*(a+9), *(a+i), т.к. в переменной – указателе a хранится адрес начала массива. Дляполучения адреса, например, 9 – го его элемента к этому адресу прибавляется 9·sizeof(int) (9 умножить на·длину элемента типа int), т.е. к начальному адресу a

прибавляется смещение 9. Затем с помощью операции *(разадресации) выполняется выборка значения из указанной области памяти.

После использования массива выделенная динамическая память освобождается с помощью оператора:

delete [ ] имя массива.

Так например, для одномерного массива a:

delete [ ] a; .

Время "жизни" динамического массива определяется с момента выделения динамической памяти до момента ее освобождения.

1.5.8. Динамические массивы

Если до начала работы программы неизвестно, сколько в массиве элементов, в программе используют динамические массивы. Память под них выделяется с помощью операции new или функции malloc во время выполнения программы. Адрес начала массива хранится в переменной, называемой указателем. Например.

Примечание. Обнуление памяти при ее выделении не происходит. Инициализировать динамический массив нельзя.

Обращение к элементу динамического массива осуществляется также, как и к элементам обычного массива.

Например, a[0], a[1], …, a[19], c[2][5] и т.д.

Другой способ обращения к элементу b[i][j] двумерного массива имеет вид:

*(*(b+i)+j).

Поясним это. Двумерный массив представляет собой массив массивов, т.е., это массив, каждый элемент которого является массивом. Имя двумерного массива также является константным указателем на начало массива. Например, int b[5][10] является массивом, состоящим из 5-ти массивов. Для обращения к b[i][j] сначала требуется обратиться к i-ой строке массива, т.е., к одномерному массиву b[i]. Для этого надо к адресу начала массива b прибавить смещение, равное номеру строки i: b+i (при сложении указателя b с i учитывается длина адресуемого элемента, т.е., i·(n·sizeof(int)), т.к. элементом массива b[i] является строка, состоящая из n элементов типа int). Затем требуется выполнить разадресацию: *(b+i). Получим массив из 10 элементов. Далее требуется обратиться к j-му элементу полученного массива Для получения его адреса опять применяется сложение указателя с j: *(b+i)+j (на самом деле прибавляется j·sizeof(int)). Затем применяется операция разадресации: *(*(b+i)+j). Т.о., получаем формулу для вычисления адреса элемента b[i][j]:

b+k·i·n+k·j=b+k·(i·n+j),

где k – длина в байтах одного элемента массива, b – адрес начала массива. Эта формула может быть использована в дальнейшем, например для организации передачи в подпрограмму двумерного массива переменной размерности.

Приведем универсальный способ выделения памяти под двумерный массив, когда обе его размерности задаются на этапе выполнения программы:

int i, m, n; //i – номер строки, m, n – количество строк и столбцов

puts("Введите m и n");

scanf("%d %d",&m, &n); // Ввод m, n

int **b=new int *[m]; //1

for (i=0; i<m; i++) //2

b[i]=new int[n]; //3

Здесь в операторе //1 объявляется переменная типа "указатель на указатель на int" и выделяется память под массив указателей на строки массива (m строк). В операторе //2 организуется цикл для выделения памяти под каждую строку массива. В операторе //3 выделяется память под каждую строку массива и i-му элементу массива указателей на строки присваивается адрес начала участка памяти, выделенного под строку двумерного массива. Каждая строка массива состоит из n элементов типа int.

Примечание. Для выделения динамической памяти для вещественного

двумерного массива достаточно в приведенном фрагменте программы в стоках //1, //3 имя типа int поменять на имя типа float.