240 likes | 574 Views
Основы информатики Массивы . Указатели. Заикин Олег Сергеевич http://sat.isa.ru/pdsat/files/teaching/ zaikin.icc@gmail.com. Массив. Массив – набор элементов одинакового типа расположенных в памяти подряд (друг за другом) обращение происходит с применением общего имени
E N D
Основы информатикиМассивы. Указатели. Заикин Олег Сергеевич http://sat.isa.ru/pdsat/files/teaching/ zaikin.icc@gmail.com
Массив • Массив – набор элементов • одинакового типа • расположенных в памяти подряд (друг за другом) • обращение происходит с применением общего имени • обращение к конкретному элементу осуществляется по индексу • Массив является структурой с произвольным доступом (в отличие от списка).
Динамика и статика Динамическим называется массив, размер которого может меняться во время исполнения программы. Динамические массивы делают работу с данными более гибкой, так как не требуют предварительного определения хранимых объемов данных, а позволяют регулировать размер массива в соответствии с реальными потребностями. Статическиминазывают массивы, размер которых в программе определен и не может меняться.
Размерность массива Массивы с одним индексом называют одномерными, с двумя — двумерными и т. д. Одномерный массив соответствует вектору, двумерный — матрице. Чаще всего применяются массивы с одним или двумя индексами, реже — с тремя, ещё большее количество индексов встречается крайне редко.
Массив Объявлениеодномерного статического массива типимя_массива[размер-константа]; int A[4];// одномерный статический массив целых чисел длины 4 // нумерация элементов от 0 до 3
Массив Объявлениедвумерного статического массива типимя_массива[размер1][размер2]; floatB[12][15]; // двумерный статический массив вещественных // чисел размера 12 на 15 // нумерация по строкам от 0 до 11, по столбцам от 0 до 14
Массив Доступ к элементу – с помощью [] Пример int A[10]; for (int i=0; i < 10; i++) A[i] = i*i; // присваивание элементу массива for (int i=0; i < 10; i++) cout << A[i] << ’ ’;// вывод элементов массива Вывод: 0 1 4 9 16 25 …81
Двумерный массив Одномерный массив одномерных массивов. Объявление Типимя_массива[размер1][размер2]; int B[3][10];// матрица с 3 строками и 10 столбцами B[2, 5] – неправильное обращение B[2][5] – правильное обращение char имя_массива[размер1][размер2] – массив строк
Инициализация статических массивов Формат тип имя_массива[размер] = {список_значений} значения в списке разделены запятыми int A[4] = {1, 2, 3, 4}; Для символьных массивов тип имя_массива[размер] = “строка” char str[7] = “Привет”; const char str[7] = “Привет”; // строка-константа
Инициализациястатического двумерного массива Формат тип имя_массива[размер1] [размер2] = {список_значений} в списке значения разделены запятыми int A[3][2] = {1,4, 2,4, 5, 8};
Динамические массивы в C++ Способ 1. Низкоуровневый (наследство от языка C) – через указатели Способ 2. Высокоуровневый, через vector (из библиотеки STL)
Указатели Указатель – переменная, которая хранит адрес другой переменной (адрес памяти). Указатель (англ. pointer) — переменная, диапазон значений которой состоит из адресов ячеек памяти или специального значения — нулевого адреса. Последнее используется для указания того, что в данный момент там ничего не записано. Аналогия с указателями у дороги – они содержат информацию о там, как и за какое время добраться до нужного места.
Указатели Две основные операции над указателями: присваивание и разыменование. Первая из этих операций присваивает указателю некоторый адрес. Вторая служит для обращения к значению в памяти, на которое указывает указатель. Нулевой указатель − это указатель, хранящий специальное значение, используемое для того, чтобы показать, что данная переменная-указатель не ссылается (не указывает) ни на какой объект В языках Си и C++ это 0 или макрос NULL.
Указатели Использование символа * перед именем переменной в объявлении превращает ее в указатель. Формат тип *имя_переменной; Пример int *a; // указатель на переменнуюцелочисленного типа
Указатели Унарный оператор &возвращает адрес памяти, по которому расположен операнд. // balptr получает адрес переменной balance int *balptr; int balance = 3200; balptr = &balance; Унарный оператор * (разыменование)возвращает значение переменной, расположенной по адресу, на который указывает операнд. // переменной value присваивается значение // переменной balance int value = *balptr;
Указатели Переменная num объявляется и инициализируется. После чего объявляется переменная-указатель pNum. Затем указателю pNum присваивается адрес переменной num. Таким образом обе переменные можно использовать для доступа к одному и тому же месту в памяти.
Указатели balance = 3200; balptr = &balance; value = *balptr;
Арифметика указателей С помощью указателей можно присваивать значения. *p = 101; // переменной, на которую указывает p, // присваивается значение 101 (*p)++; // инкремент значения переменной, на которую // указывает p int *p, num; p = # *p = 100; // значение num равно 100 (*p)++; // значение num равно 101
Арифметика указателей Операции: ++, --, + и – Пример. p – указатель на int переменную с адресом 2000. После выполнения p++p указывает на адрес 2004 (следующее int значение). Указатели можно сравнивать, используя операторы отношения ==, < и >. Смысл имеет сравнение указателей на разные элементы одного и того же массива.
Динамический массив Указатель можно рассматривать как динамический массив. С помощью операторов new/deleteможно выделять/освобождать память для динамического массива. Указатель ссылается на первый элемент массива (имя массива без индекса образует указатель на начало этого массива). Эквивалентно: ptr[4] и *(ptr+4) Позволяет обращаться к элементам массива по индексу.
Операторывыделения и освобождения памяти new тип[размер] возвращает адрес непрерывного участка памяти для объекта типа типразмерностью размер delete[] имя_указателя освобождает память, выделенную оператором new, начиная с адреса, на который ссылается указатель. Пример. int ar_sz=10; float*ptr = new float[ar_sz];// выделили область памяти ptr[1]=1; ptr[2]=2; delete[] ptr;// осовободили память
Массивы указателей Указатели могут храниться в массивах. Объявление 5-элементного массива указателей на int. Фактически - двумерный массив с размерами: 1 2 3 4 5 const int arr_size = 5; void main(){ int *arr[arr_size]; for (int i = 0; i < arr_size; i++){ arr[i] = new int[i+1]; for (int j = 0; j < i + 1; j++) { arr[i][j] = j + 1; cout << arr[i][j] << " "; } cout << endl; } } Вывод: 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
Массивы указателей Динамический двумерный массив. Выделение и освобождение памяти. int **arr; arr = new int*[3]; for(int i = 0; i < 3; i++) arr[i] = new int[2]; // освобождать память нужно так for(int i = 0; i < 3; i++) delete[] arr[i]; delete[] arr;
Утечки памяти Если не освобождать память, то может остаться «мусор» - фактически занятые на время выполнения программы участки памяти, к которым из программы нельзя обратиться. int *arr; arr = new int[5]; arr = new int[6]; // утечка памяти Выделенная память должна освобождаться. Каждому newдолжен соответствовать delete.