- •Лекция 3.
- •3. Массивы и структуры данных
- •3.1 Массивы (часть 1 – одномерные массивы)
- •Упражнения
- •3.2 Массивы (часть 2 – продолжение)
- •3.3 Указатели и динамическая память
- •Создание указателей
- •Выделение памяти
- •Создание массива при помощи оператора new
- •Проверка значения, возвращаемого new
- •Освобождение памяти
- •Общая схема
- •Int n; // Размер массива
- •Операции над указателями
- •4. Функции
- •4.1 Объявление функций
- •4.2 Передача массива в качестве параметра
- •Упражнения
- •4.3 Локальные и глобальные переменные
- •4.4 Передача параметров по значению и по ссылке
Упражнения
В приведенных ниже упражнениях подразумевается, что массив вводится, как в выше приведенном примере. Все массивы – числовые типа double[].
-
Выведите на экран все элементы массива с четными индексами (т.е. A[0], A[2], A[4], ...).
-
Найдите количество положительных элементов в массиве.
-
Определите, есть ли в данном массиве два соседних элемента с одинаковыми знаками.
-
Переставьте элементы массива в обратном порядке без использования дополнительного массива.
-
Переставьте соседние элементы массива (0-й элемент поменять с 1-м, 2-й с 3-м и т.д.)
-
Циклически сдвиньте элементы массива вправо (0-й элемент становится 1-м, 1-й становится 2-м, ..., последний становится 0-м).
-
Найдите значение наибольшего элемента в массиве.
-
Дан массив, отсортированный по возрастанию (каждый элемент массива не меньше предыдущего элемента, например, {1, 2, 2, 3, 3, 3}). Найдите количество различных чисел в этом массиве.
3.2 Массивы (часть 2 – продолжение)
Как указано в п.3.1 массивы предназначены для хранения нескольких данных одного типа в одной переменной. В п.3.1 рассматривались одномерные массивы.
Но массивы, вообще говоря, могут быть и двумерные, трехмерные и т.п. Размерность массивов в С++ никак не ограничивается.
Вот пример объявления двумерного массива вещественного типа:
double Arr[2][2];
В приведенном примере объявлен массив Arr – это вещественный двумерный массив, состоящий из 2-х строк и 2-х столбцов. Обращаются к элементам такого массива как
Arr[0][0]
- обращение к первому элементу двумерного массива, а, например, к последнему, находящемуся во 2-ой строке и 2-ом столбце -
Arr[1][1].
В качестве индексов при обращении к элементам массива используются только целые данные.
При объявлении массив можно инициализировать:
double v1[3]={ 0.1, 3.456, 5.79 } , a1[2][2]={ {2.3, 3.46 } , { -23.1, 7.31} };
Двумерные массивы хранятся в памяти по строкам. Поэтому первая строка массива a1 будет 2.3, 3.46, а вторая соответственно - 23.1, 7.31.
Если при объявлении одномерных массивов используется инициализатор, то размерность массива можно не указывать:
int Arr[ ]={3, 6, 12};
В данном примере мы объявили глобальный целый массив Arr из трех элементов. Еще раз обратим внимание, что такое объявление без указания размеров массива возможно только для одномерных массивов.
3.3 Указатели и динамическая память
Часто размер используемого при решении задачи массива не задан на момент компиляции программы, а определить его можно только при выполнении программы. В этом случае используется механизм, называемый динамическим распределением памяти.
Для использования динамического распределения памяти необходимо создать переменную специального типа, называемую указателем, затем создать в памяти массив необходимого размера, доступ к которому будет осуществляться через этот указатель, и, наконец, освободить выделенную память после завершения работы с массивом.
Создание указателей
Указатель — это переменная специального типа. Она хранит не какое-то числовое значение, а адрес (номер первого байта в памяти компьютера), по которому хранится какая-то другая переменная. При создании указателя необходимо задать тип переменной, на которую он указывает. Синтаксис объявления указателя следующий:
имя_типа * идентификатор;
Пример:
int * pi;
float * pf, f;
double * ps, * pt;
В первой строке этого примера объявлена переменная (указатель) pi, являющаяся указателем на тип int (т.е. в ячейке памяти, на которую указывает pi должна хранится переменная типа int). Во второй строке объявлены переменная (указатель) pf, являющаяся указателем на тип float и переменная (обычная) f типа float. Обратите особое внимание на эту строчку: для того, чтобы объявить несколько указателей в одной строке, необходимо перед идентификатором каждого из них поставить символ *. А еще лучше объявлять в одной строке только одну переменную. В третьей строке данного примера объявляются два указателя на тип double: ps и pt.
Сразу после объявления значение указателя не определено, т.е. он может указывать в произвольную ячейку памяти, поэтому пользоваться им еще нельзя, т.к. в лучшем случае можно получить ошибку типа segmentation fault, а в худшем - программа станет работать непредсказуемо и определить источник ошибки будет крайне сложно.