- •1.1. Идентификаторы
- •1.5. Структура программы С++
- •1.6. Директивы препроцессора
- •1.8. Функции библиотеки math.h
- •1.9. Форматированный ввод/вывод данных
- •2.3. Целый тип данных
- •2.4. Символьный тип данных
- •2.8. Явное преобразование типов
- •3.2. Операция присваивания
- •3.7. Использование блоков
- •4.1. Оператор условной передачи управления if
- •5.4.4. Функция exit
- •5.4.5. Функция abort
- •6.3. Многомерные массивы
- •7.2.1. Унарные операции
- •7.2.2. Арифметические операции и операции сравнения
- •7.3. Инициализация указателей
- •7.4. Работа с динамической памятью
- •7.5. Создание одномерного динамического массива
- •8.2.2. Передача параметров по ссылке
- •8.2.3. Передача параметров по указателю
- •8.2.6. Передача переменного числа параметров
- •8.3. Встраиваемые функции
- •9.2. Функции для работы со строками
- •9.3. Алгоритмы работы со строками
- •10.2. Объявление и использование объединений
- •11.2. Функции для работы с файлами
- •13.3. Целесообразность использования рекурсии
- •14.1. Простые методы сортировки
- •14.1.1. Метод пузырька
- •14.2. Улучшенные методы сортировки
- •14.2.1. Метод Шелла
- •15.2. Поиск делением пополам
- •15.3. Интерполяционный поиск
- •17.2. Использование древовидных структур
- •19.6. Хеш-таблица на основе связанных списков
- •19.7. Метод блоков
- •3. Программирование циклических алгоритмов
- •5. Использование двумерных массивов
- •7. Программирование с использованием строк
- •9. Программирование с использованием файлов
- •12. Поиск по ключу в одномерном массиве
- •15. Работа с древовидными структурами данных
- •16. Вычисление алгебраических выражений
- •2. Выполнение программы
- •3. Отладка программы
cout << *um << endl; |
// Выводит: 1 |
um++; |
|
cout << *um << endl; |
// Выводит: 2 |
Сложение. Перемещение указателя на число байт, равное произведению размера типа данного, на которое ссылается указатель, на величину добавляемой или вычитаемой константы. Например:
int *um, a[5] = {1,2,3,4,5};
um = a; |
|
|
|
|
|
|
|
|
Р |
|
cout << *um << endl; |
// Выводит: 1 |
|
|
|
||||||
|
|
|
|
|||||||
|
um += 3; |
|
|
|
|
|
|
И |
||
cout << *um << endl; |
// Выводит: 4 |
|
|
|||||||
|
У |
|
||||||||
|
|
|
|
|
|
|
|
|
||
Вычитание. Разность двух указателей равна числу объектов соответст- |
||||||||||
вующего типа, размещенных в данном диапазоне адресов. Например: |
||||||||||
int *um, a[5] = {1,2,3,4,5}; |
|
Г |
|
|
||||||
|
um = &a[0]; |
|
|
|
|
Б |
|
|
|
|
|
un = &a[4]; |
|
|
|
|
|
|
|
||
|
k = un - um; |
|
|
|
|
|
|
|||
cout << k << endl; // |
Выводит: 4 |
|
|
|
||||||
|
|
|
|
|
|
к |
|
|
|
|
Операции сравнения. Сравниваютдресаобъектов. |
|
|
||||||||
|
|
|
7.3. Инициализация указателей |
|
|
|||||
|
|
|
|
т |
|
|
|
|
|
|
Инициализация пустым знач ни м. Например: |
|
|
|
|||||||
int *a = NULL; |
|
е |
|
|
|
|
||||
int *b = 0; |
о |
|
|
|
|
|
|
|||
|
|
и |
|
|
|
|
|
|
|
|
Присваиван е |
указателю адреса уже существующего объекта. Например: |
|||||||||
int k = 23; |
|
|
|
|
|
|
|
|
||
int *uk = &k; |
// ли |
int *uk(&k); |
|
|
|
|
||||
|
б |
|
|
|
|
|
|
|
|
|
int *us = uk; |
|
|
|
|
|
|
|
|
||
ти |
|
|
|
|
|
|
|
|
|
|
Присваиваниелуказателю адреса выделенного участка динамической |
||||||||||
памя : |
|
|
|
|
|
|
|
|
|
|
Б |
|
|
|
|
|
|
|
|
|
|
int *s = new int;
int *k = (int *) malloc(sizeof(int));
В примере использована операция sizeof, которая определяет размер указанного параметра в байтах.
7.4. Работа с динамической памятью
Динамическая память (heap) – специальная область памяти, в которой во время выполнения программы можно выделять и освобождать место в соответствии с текущими потребностями. Доступ к выделяемым участкам памяти осу-
43
ществляется через указатели. Для работы с динамической памятью в языке Си (библиотека malloc.lib) определены следующие функции:
void *malloc(size) – выделяет область памяти размером size байт. Возвращает адрес выделенного блока памяти. Если недостаточно свободного места для выделения заданного блока памяти, то возвращает NULL.
void *сalloc(n, size) – выделяет область памяти размером n блоков по size байт. Возвращает адрес выделенного блока памяти. Если недостаточно свобод-
|
Р |
ного места для выделения заданного блока памяти, то возвращает NULL. Вся |
|
выделенная память заполняется нулями. |
И |
void *realloc(*u) – изменяет размер ранее выделенной памяти, связанной |
с указателем u на новое число байт. Если память под указатель не выделялась, |
|||||
|
|
|
|
|
У |
то функция ведет себя как malloc. Если недостаточно свободного места для вы- |
|||||
деления заданного блока памяти, то функция возвращает значение NULL. |
|||||
|
|
|
Б |
|
|
void free(*u) – освобождает участок памяти, связанный с указателем u. |
|||||
В языке C++ для выделения и освобожденияГпамяти определены опера- |
|||||
|
|
туда |
|
|
|
ции new и delete. Имеются две формы операций: |
|
|
|||
|
к |
|
|
|
|
тип *указатель = new тип (зн чение) – выделение участка памяти в |
|||||
е |
|
|
указанного значения. |
||
соответствии с указанным типом и занесение |
|
||||
delete указатель – освобожд ние выделенной памяти. |
|||||
т |
|
|
|
|
|
тип *указатель = new ип[n] – выделение участка памяти размером n блоков указанного типа.
delete []указатель – освобождение выделенной памяти. |
||
|
и |
|
Операция delete не уничтожает значения, связанные с указателем, а раз- |
||
решает компи ятору спользоватьо |
данный участок памяти. |
|
б |
|
|
7.5.лСоздание одномерного динамического массива
следующиеДля создания одномерного динамического массива необходимо знать тип элементов массива и их количество. Например, для создания одномерного ди-
намБческого массива, состоящего из n действительных чисел, можно использовать функции:
umas1 = static_cast <double*> (malloc(n*sizeof(double)));
(освобождение памяти – free(umas1) )
или
umas1 = static_cast <double*> (сalloc (n,sizeof(double)));
(освобождение памяти – free(umas1) )
или
44
umas1 = new double(n*sizeof(double));
(освобождение памяти – delete umas1 )
или
umas1 = new double[n];
(освобождение памяти – delete []umas1 )
7.6. Создание двумерного динамического массива
Двумерный динамический массив рассматривается компилятором как
массив указателей на одномерные массивы (рис. 7.1). |
|
|
|
Р |
||||||
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
И |
|
|
|
|
|
|
|
|
|
У |
|
|
|
|
|
|
|
|
Г |
|
|
||
|
|
|
|
|
Рис. 7.1 |
Б |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
е |
|
массив указателей, затем |
||||
Вначале выделяется память под одномерныйа |
||||||||||
каждый указатель получает адр с созданногокодномерного динамического мас- |
||||||||||
сива. Освобождение памяти осущ ствля тся в обратном порядке. |
|
|||||||||
double **umas2; |
|
|
// Объявление указателя на массив |
|||||||
umas2 = new double*[n]; |
// Выделение памяти |
|
||||||||
|
и |
т |
// под массив указателей |
|
||||||
|
л |
|
|
// Выделение памяти |
|
|||||
for(i=0; i<n; i++)о |
|
|
||||||||
б |
|
|
|
|
|
|
|
|
|
|
umas2[i] = new double[m];// под одномерные массивы |
||||||||||
и |
|
… |
// Работа с массивом |
|
|
|
|
|||
|
|
|
|
|
|
|||||
for(i=0; i<n; i++) |
// Освобождение памяти, выделенной |
|||||||||
delete []umas2[i]; |
// под одномерные массивы |
|
||||||||
Бdelete []umas2; |
|
// Освобождение памяти, выделенной |
||||||||
|
|
|
|
// под массив указателей |
|
|
||||
umas2 = NULL; |
// Очистка указателя |
|
|
|
45
8. Функции пользователя
8.1. Понятие функции
Функция – последовательность операторов, оформленная таким образом, что ее можно вызвать по имени из любого места программы.
Функция описывается следующим образом:
тип_возвращаемого_значения имя_функции (список_параметров)
Первая }строка данного описания называется заголовком функцииР. Тип
{
Тело_функции
возвращаемого значения может быть любым, кроме массива илиИфункции. Если функция не возвращает значение, то указывается тип void. В С++ по умолчанию тип возвращаемого результата − int.
|
|
|
|
У |
Список параметров представляет собой набор конструкций следующей |
||||
формы: |
|
|
Г |
|
тип_параметра имя_параметра |
Б |
|
||
Например: |
|
|
|
|
|
|
|
|
|
int sum(int a, double b, char c) |
|
|
||
|
|
а |
|
|
Если функция не получает ни а их данных, то скобки остаются пустыми: |
||||
int fun() |
к |
|
|
|
|
|
|
|
|
Широко использую ся про |
о ипы функций (их предварительное объяв- |
|||
|
е |
|
|
|
ление). Прототип аналогичен заголовку функции, за исключением того, что
имена формальных параме р в не указываются (остаются только типы), и в |
||
конце ставится точка с запяттй: |
||
int sum(int, doubleо, char); |
||
Широкое испо ьзование прототипов вызвано следующим: |
||
|
и |
|
имеющие прототипы функции могут быть вызваны из других модулей; |
||
спользованиел |
прототипов позволяет размещать функции в произ- |
|
вольном порядке (а не до первого их использования); |
||
б |
|
|
Биразмещение прототипов в одном месте делает программу более читабельной.
Правила оформления тела функции такие же, как и для любого другого участка программы. Все объявления носят локальный характер, т. е. объявленные переменные доступны только внутри функции.
Не допускается вложение функций друг в друга.
Выход из функции происходит при достижении закрывающей функцию скобки или после выполнения оператора return.
46