- •1. Краткие теоретические сведения
- •1.1. Понятие указателя
- •1.2. Объявление указателя
- •1.3. Операции над указателями
- •1.4. Передача параметра по ссылке
- •1.5. Динамическое выделение памяти
- •1.5.1. Динамическое размещение одномерного массива
- •1.5.2. Динамическое размещение двухмерного массива
- •1.5.3. Динамические массивы
- •1.5.4. Формирование динамических массивов с использованием библиотечных функций
- •1.5.5. Формирование динамических массивов с использованием операций new и delete
- •1.5.6. Динамические массивы
- •1.5.7. Динамические массивы
- •1.5.8. Динамические массивы
- •1.5.9. Освобождение выделенной динамической памяти.
- •1.5.10. Описание динамической строки
- •1.5.11. Объявление динамического массива
- •1.6. Связь указателей и массивов
- •1.7. Массивы указателей
- •1.8. Массивы и функции
- •1.9. Указатель на символьную строку
- •Второй пример
- •Увеличение указателя на символьную строку
- •Уменьшение количества операторов
- •Сканирование символьной строки
- •1.10. Заполнение массивов случайными числами
- •1.12. Примеры программирования задач
- •2. Задание
- •2.4. Задания для выполнения на занятиях
- •2.4.1. Задание 1. Динамические одномерные массивы
- •2.4.1.1. Варианты заданий
- •2.4.1.2. Пример обработки динамического массива для варианта 30
- •2.4.1.3. Программа
- •Int *a, *b; // указатели исходных одномерных массивов a и b
- •2.4.1.4. Тестирование
- •2.4.2. Задание 2. Динамические двумерных массивы
- •2.4.2.1. Варианты заданий
- •2.4.2.2. Пример для варианта 30
- •2.4.2.3. Программа
- •2.4.2.4. Тестирование
- •2.4.3. Задание 3. Динамические одномерные массивы Викентьева
- •2.4.3.1. Варианты заданий
- •2.4.4.1. Варианты заданий
- •4. Требование к отчету
- •4. Краткие теоретические сведения.
- •5. Вопросы для самоконтроля
- •Литература
- •1. Краткие теоретические сведения 2
- •1.1. Понятие указателя 2
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.