Text
                    СРЕДНЕЕ ПРОФЕССИОНАЛЬНОЕ ОБРАЗОВАНИЕ
__________________________________________________________________

Л.В. Гурьянов, Л.С. Гурьянова, Е.В. Гришин,
Е.А. Дзюба, С.В. Самуйлов

ОСНОВЫ
СТРУКТУРНОГО ПРОГРАММИРОВАНИЯ
НА C++
УЧЕБНОЕ ПОСОБИЕ ДЛЯ СПО

Рекомендовано Учебно-методическим отделом СПО в качестве
учебного пособия для использования в учебном процессе образовательными
учреждениями среднего профессионального образования по укрупненной группе
профессий и специальностей «Информатика и вычислительная техника»

Москва
Ай Пи Ар Медиа
2026

Саратов
Профобразование
2026


УДК 004.432(075) ББК 32.973 О-75 Авторский коллектив Пензенского государственного университета: Гурьянов Л.В. — канд. техн. наук, доц. кафедры математического обеспечения и применения ЭВМ; Гурьянова Л.С. — ст. преподаватель кафедры радиотехники; Гришин Е.В. — ассистент кафедры математического обеспечения и применения ЭВМ; Дзюба Е.А. — ст. преподаватель кафедры математического обеспечения и применения ЭВМ; Самуйлов С.В. — канд. техн. наук, доц. кафедры математического обеспечения и применения ЭВМ Рецензент: Иванчуков А.Г. — канд. техн. наук, заместитель начальника отдела разработки ПАК заказных проектов АО «ИнфоТеКС» О-75 Основы структурного программирования на C++ : учебное пособие для СПО / Л.В. Гурьянов, Л.С. Гурьянова, Е.В. Гришин [и др.]. — Москва : Ай Пи Ар Медиа ; Саратов : Профобразование, 2026. — 94 с. — (Среднее профессиональное образование). — Текст : электронный. ISBN 978-5-4497-4881-2 (Ай Пи Ар Медиа) ISBN 978-5-4488-2700-6 (Профобразование) Учебное пособие включает в себя лабораторные работы по разработке консольного приложения на языке С++ с использованием одномерных и двумерных массивов, строк как массивов символов, так и объектов класса string. Задания помогут закрепить базовые понятия программирования и синтаксис языка программирования С++. Большое внимание уделяется использованию динамических структур данных (массивы, списки, очереди и др.) в многофайловых программах на С++. Все лабораторные работы сопровождаются методическими материалами — примерами программ, которые помогут студентам успешно выполнить лабораторные задания в установленные сроки. Подготовлено в соответствии с Федеральным государственным образовательным стандартом среднего образования. Предназначено для студентов укрупненной группы профессий и специальностей «Информатика и вычислительная техника», изучающих дисциплины «Программирование», «Основы программирования на языке C++», «Алгоритмы и структуры данных» и другие курсы, связанные со структурным программированием на C++. Учебное электронное издание ISBN 978-5-4497-4881-2 (Ай Пи Ар Медиа) ISBN 978-5-4488-2700-6 (Профобразование) © ООО Компания «Ай Пи Ар Медиа», 2026 © ООО «Профобразование», 2026
Учебное издание Гурьянов Лев Вячеславович Гурьянова Людмила Станиславовна Гришин Евгений Валентинович Дзюба Елена Анатольевна Самуйлов Сергей Владимирович Редактор М.В. Леман Технический редактор, компьютерная верстка А.В. Неверова Обложка Я.А. Кирсанов, С.С. Сизиумова, фотобанк Freepik Подписано к использованию 09.10.2025. Объем данных 6 Мб. ООО «Профобразование» 8-800-511-14-70 (бесплатный звонок по России) E-mail: office@profspo.ru, sale@profobr.pro
СОДЕРЖАНИЕ Введение .................................................................................................................... 5 Лабораторная работа № 1. Управляющие структуры .......................................................................................... 6 Лабораторная работа № 2. Простое консольное приложение .......................................................................... 12 Лабораторная работа № 3. Массивы, одномерные массивы ............................................................................. 19 Лабораторная работа № 4. Двумерные массивы ................................................................................................ 27 Лабораторная работа № 5. Функции ................................................................................................................... 33 Лабораторная работа № 6. Перегрузка и шаблон функции .............................................................................. 41 Лабораторная работа № 7. Строки как массивы символов ............................................................................... 47 Лабораторная работа № 8. Строки — объекты класса string ............................................................................ 56 Лабораторная работа № 9. Динамические структуры данных, массивы ......................................................... 62 Лабораторная работа № 10. Динамические структуры данных (списки, очереди, стеки) .............................. 73 Список литературы............................................................................................... 94 4
ВВЕДЕНИЕ На сегодняшний день С++ является одним из самых популярных и распространенных языков, поэтому подходит для создания приложений для самых разных целей. В предложенном учебном пособии раскрываются базовые понятия программирования и синтаксис языка программирования С++. На простых примерах объясняется использование управляющих структур для алгоритмизации задач структурного программирования. Задания лабораторных работ включают разработку консольного приложения на языке С++ с использованием одномерных и двумерных массивов, строк как массивов символов, так и объектов класса string. Отдельные лабораторные работы выделены для изучения и приобретения навыков программирования функций, их перегрузки и шаблонов функций. Большое внимание уделяется использованию динамических структур данных (массивы, списки, очереди и др.) в многофайловых программах на С++. Все лабораторные работы сопровождаются методическими материалами — примерами программ для успешного выполнения лабораторных заданий в установленные сроки. После успешного прохождения лабораторных работ по программированию на языке С++ обучающийся учреждений СПО:  узнает:  о практическом применении языка C++ и решении задач, приближенных к реальным прикладным кейсам;  об абстракциях основных структур данных (переменные, операторы, функции, массивы, указатели, структуры, классы, строки), методах их обработки и способах реализации;  будет уметь:  выполнять основные операции над массивом;  писать код на языке С++;  создавать простые приложения на языке C++;  работать с базовыми структурами данных, такими как массивы, функции, связные списки и т.п. 5
ЛАБОРАТОРНАЯ РАБОТА № 1. УПРАВЛЯЮЩИЕ СТРУКТУРЫ Цель работы Познакомиться с определениями структурного программирования, теоремой о структурировании программ. Получить навыки приведения алгоритма к структурированному виду, а также написания кода на языке С++ с использованием управляющих структур. Подготовка к работе Изучить реализацию управляющих структур в языке С++. Требования Написать код С++, реализующий заданную структуру программы. Отчет должен содержать:  заголовок: группа, ФИО студента;  исходную схему и соответствующий ей код (табл. 1, 2). Варианты заданий Варианты заданий приведены в табл. 1, 2. Таблица 1 Варианты заданий лабораторной работы 1 (для студентов с нечетными номерами в списке группы) Структура программы Структура программы Код 6 Код
Структура программы Структура программы Код Код Таблица 2 Варианты заданий лабораторной работы 1 (для студентов с четными номерами в списке группы) Структура программы Структура программы Код 7 Код
Структура программы Структура программы Код Код Методические указания Рассмотрим пример написания кода С++ по заданной структуре программы. Исходная схема программы приведена на рис. 1. Рис. 1. Структура программы 8
Шаг 1. В исходной схеме выделим основную управляющую структуру, отвечающую за процесс обработки данных. При этом остальные действия схемы будем рассматривать как элементы функциональных блоков, имеющих один вход и один выход (рис. 2). If (x>0){ …; } else{ …; } cout<<x<<k; Рис. 2. Выделение основной управляющей структуры Таким образом, исходная схема представляет собой управляющую структуру «ЕСЛИ_ТО_ИНАЧЕ» с вложенными в нее операторами обработки данных. Шаг 2. В полученной управляющей структуре раскроем функциональные блоки, выделенные на шаге 1 (рис. 3). If (x>0){ do x--; k++; while(x>0); } else{ x=0; k=0; } cout<<x<<k; Рис. 3. Операторы функциональных блоков 9
Обратите внимание на реализацию структуры «ЦИКЛ_ДО». В исходной схеме при истинности условия завершения цикла (x<=0) осуществляется выход из цикла. В операторе do while языка С++, реализующем эту структуру, при истинности условия завершения цикла осуществляется продолжение цикла. Поэтому в реализации схемы программы в операторе do while используется условие, противоположное исходному: do … while(x>0). Литература 1. Лингер Р., Миллс Х., Уитт Б. Теория и практика структурного программирования. — Москва : Мир, 1982. — 406 с. 2. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. — http://cph.phys.spbu.ru/documents/ First/books/7.pdf (дата обращения: 06.10.2025). Контрольные вопросы 1. Продолжите определение: «Любая программа строится из трёх базовых управляющих структур: …» 2. Продолжите определение: «Все управляющие структуры должны иметь один вход и …» 3. Какая из трех переменных может принимать значение 12.5: a) int x; b) float f; c) char c; 4. Переменной z типа bool можно присвоить следующие значения: a) true; b) false; c) "истина"; d) 1 5. Определите результат – значение переменной n следующего фрагмента программы: int n = 1, i = 1; while (i <= 2) n *= i++ 10
6. Найдите ошибку в фрагменте кода программы и укажите символы для ее исправления: while c <= 5 { product *= х; ++c; } 7. Определите значение, которое будет выведено на экран: int x =-1, y = 1; std::cout << (abs(x - y) <= 1) && (abs(x + y) <= 1); 8. Какой оператор следует использовать для реализации этой схемы? 9. Дайте реализацию схемы из вопроса 8 с помощью оператора for. 10. Определите значение, которое будет выведено на экран: int x = 1, y = -1; std::cout << (x - y <= 1) && (x + y <= 1); 11
ЛАБОРАТОРНАЯ РАБОТА № 2. ПРОСТОЕ КОНСОЛЬНОЕ ПРИЛОЖЕНИЕ Цель работы Познакомиться с созданием проекта консольного приложения C++, его отладкой и выполнением в среде разработки Microsoft Visual Studio. Подготовка к работе Изучить структуру главной программы, операторы ввода/вывода — cin/cout, форматирование вывода. Требования Реализовать простое приложение С++ в среде разработки. Приложение должно выводить на консоль исходные данные и полученные результаты. Электронный отчет должен содержать:  заголовок: группа, ФИО студента, номер и текст варианта задания;  исходный код приложения и скриншоты выполнения программы. Варианты заданий Напишите программу, которая осуществляет обработку информации по одному из условий, заданных ниже. 1. Вывод таблицы истинности для логической операции: a) ИЛИ b) И c) НЕ d) Исключающее ИЛИ. Если операнды имеют различные значения, то значение операция Исключающее ИЛИ — true, в противном случае — false; 2. Преобразование числа из денежного формата в дробное число. Например, 25 рублей 50 копеек преобразуется в число 25.5. 3. Преобразование временного интервала, заданного в минутах, в количество часов и минут. Например, число 150 преобразуется в 2 часа 30 минут. 12
4. Присвоить переменной К значение 1, если два числа из трех чисел x, y, z являются положительными и кратными 3, и значение 0 в противном случае. 5. Найти наименьшее из трех чисел x, y, z. 6. Присвоить переменной К значение true, если точка с координатами x, y принадлежит заданной области (рис. 4), и значение false в противном случае. a) y b) 1 y 1 x 0 -1 x -1 1 0 -1 d) 1 e) 1 0 -1 1 0 -1 y f) 1 x -1 1 x -1 -1 y y c) 1 y 1 x -1 0 -1 1 x -1 0 1 -1 Рис. 4. Область для определения положения точки с координатами x, y 7. Для заданного натурального числа N определить: a) количество цифр 7 в этом числе; b) произведение цифр заданного натурального числа; c) определить число, получаемое выписыванием в обратном порядке цифр заданного натурального числа; d) является ли заданное натуральное число палиндромом, т.е. таким, десятичная запись которого читается одинаково слева направо и справа налево; e) сколько чисел натурального ряда необходимо перемножить, чтобы их произведение превысило заданное натуральное число. 8. Определить десятичный эквивалент целого положительного двоичного числа К. 9. Определить двоичный эквивалент целого положительного десятичного числа N. 13
10. Программа выводит на экран рисунок, состоящий из символов '' и '': a)  b)  c)  d)                  Методические указания Рассмотрим примеры исходного кода С++ для реализации простых алгоритмов в консольном приложении Microsoft Visual Studio. Пример 1. Нахождение максимального числа из трех заданных целых чисел. Структура алгоритма и соответствующий ей исходный код на языке С++ приведены на рис. 5. Для сокращения количества проверок, таких как a>b, b>c, a>c, в алгоритме используется дополнительная переменная max. Оператор ? позволяет присвоить переменной max большее из двух чисел без использования оператора if. Рис. 5. Программа нахождения наибольшего из трех чисел 14
Пример 2. Нахождение всех делителей целого числа. Структура алгоритма и соответствующий ей исходный код на языке С++ приведены на рис. 6. Условию num % div = 0 в программе соответствует следующее логическое выражение: !(num % div). Организацию цикла в программе можно реализовать и с помощью оператора for, например так: int half, div; for (half = num/2, div=2; div<=half; ++div) if (!(num % div)) std::cout <<div<<std::endl; Рис. 6. Программа нахождения всех делителей целого числа Литература 1. Введение в программирование на языке С++ : лабораторный практикум / Л.В. Гурьянов, Л.С. Гурьянова, Е.А. Дзюба, Д.В. Такташкин. — Пенза : Изд-во 15
ПГУ, 2010. — 170 с. — URL: http://elib.pnzgu.ru/library/10345800 (дата обращения: 06.10.2025). 3. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. — URL: http://cph.phys.spbu.ru/ documents/First/books/7.pdf (дата обращения: 06.10.2025). Контрольные вопросы 1. Что характеризует консольное приложение? 2. Назначение препроцессорного оператора #include <iostream>? 3. Какие операторы можно использовать для ввода/вывода данных? 4. Назначение оператора cout << endl? 5. Какие операторы можно использовать для форматирования ввода/вывода данных? 6. Определите значения переменных product и x после выполнения оператора: product *= х++; Начальные значения переменных: 5. 7. Выполните трассировку программы и определите результат, если пользователь ввел с клавиатуры значения: 1, 7, 2. Дайте геометрическую интерпретацию работы программы, если значение переменной s рассматривать, как площадь геометрической фигуры. #include <iostream> int main() { int s, x, x0, x1, d, n; cin >> x0 >> x1 >> d; n = (x1 - x0) / d; x = x0; s = 0; while (n > 0) { s += d*x; x += d; n--; } cout<<s; } 16
8. Выполните трассировку программы и определите результат, если пользователь ввел с клавиатуры значения: 5; 8. Можно ли использовать программу для определения, простое число или нет? #include <iostream> int main() { int n, f = 1, i = 2; cin>> n; while (i <= sqrt(n)) { if (n % i == 0) { f = 0; break; }; i++; } cout<<f; } 9. Программа должна вычислять значение наибольшего общего делителя. Проверьте работу программы для значений m и n: 4, 2; 12, 8. #include <iostream> int main() { int m, n, p; cin>> m >> n; //m > n do{ p : = m mod n; if (p != 0) { m = n; n = p; } while ( p != 0); cout << n; } 17
10. Определите вид арифметического выражения, значение которого (переменная р) вычисляет программа. #include <iostream> int main() { int s, i, k=1, n=1, p=1; for (i = 1; i < 5; i++) { s = 0; while (k <= n) { s += k; k++ }; n = i + k; p *= s; } cout<<p; } 18
ЛАБОРАТОРНАЯ РАБОТА № 3. МАССИВЫ, ОДНОМЕРНЫЕ МАССИВЫ Цель работы Познакомиться с понятием структуры данных — массивом, особенностями и способами применения этой структуры в обработке данных. Подготовка к работе Изучить операторы объявления и инициализации одномерного массива, операции ввода/вывода значений массива в программах C++ в среде разработки Microsoft Visual Studio. Требования Реализовать простое приложение С++ обработки значений одномерного массива. Приложение должно выводить на консоль исходные данные и полученные результаты. Электронный отчет должен содержать:  заголовок: группа, ФИО студента, номер и текст варианта задания;  исходный код приложения и скриншоты выполнения программы. Варианты заданий 1. В массиве А, состоящего из N элементов, найти индекс первого положительного числа, оканчивающегося на 0 и не превосходящего сумму заданных X и Y. Если такого элемента нет, то выдать соответствующее сообщение. 2. Найти среднее арифметическое значений элементов массива, расположенных между наибольшим и наименьшим значениями массива, включая эти значения. 3. Найти количество элементов массива, начиная со второго, значение которых больше суммы индексов элементов, стоящих перед ними. 4. Назовем элемент Аi (i = 2, …, N–1) особым, если слева от него расположены элементы меньше его, а справа — больше. Найти количество таких элементов. 19
5. Присвоить переменной F значение true, если элементы массива составляют строго возрастающую арифметическую прогрессию, и false в противном случае. 6. Сколько значений элементов встречаются в массиве более одного раза? Какие это значения? 7. Сформировать массив В из таких элементов массива А, которые превышают среднее значение массива А. 8. Записать в массив В положительные элементы массива А, отрицательные элементы — в массив С.  a i  / 2 для всех таких значений x i и a i (i = 1, 2, …, N), что подкоренное выражение больше нуля, и сформировать из них массив. 9. Вычислить значения функции z i   xi 10. Решить уравнение a i  x i  b i для заданных пар значений ai и bi, для i = 1, 2, …, N; и сформировать массив из полученных неотрицательных значений. 11. Даны два массива X(N) и Y(M). Сформировать массив Z(N+M) из положительных элементов массивов X и Y. Если положительных элементов меньше N+M, то оставшимся элементам массива Z присвоить значение 1. 12. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если все элементы массива А встречаются в массиве В, и false в противном случае. 13. Найти индекс последнего положительного значения в массиве, которое делится без остатка на 10 и превосходит произведение заданных В и С. Если такого элемента нет, то выдать соответствующее сообщение. 14. Найти последовательность положительных значений элементов массива (элементы следуют друг за другом), максимальной длины. Если такой последовательности нет, выдать соответствующее сообщение. 15. Записать в начало массива А элементы, имеющие нечетные значения, а в конец массива — четные значения. 16. Назовем элемент Аi (i = 2, …, N–1) особым, если слева от него расположены элементы меньше его индекса, а справа — больше. Найти количество таких элементов. 17. Присвоить переменной F значение true, если элементы массива составляют строго убывающую арифметическую прогрессию с заданным шагом, и false в противном случае. 20
18. Поменять местами минимальный и максимальный элементы массива, если индекс минимального элемента больше индекса максимального. В противном случае выдать соответствующее сообщение. 19. Сформировать массив В из таких элементов массива А, сумма которых не превышает заданное значение С. Если таких элементов в массиве А нет, то выдать соответствующее сообщение. 20. Даны два массива X(N) и Y(M). «Обменять» максимальный элемент массива X и минимальный элемент массива Y и наоборот. 21. Даны два массива X(N) и Y(M). Вставить на первое место массива X максимальный элемент массива Y, а на его место поставить последний (вытесненный в результате вставки) элемент массива X. 22. Даны два массива X(N) и Y(M). Сформировать массив Z(N+M) из отрицательных элементов массивов X и положительных массива Y. Если таких элементов меньше N+M, то оставшимся элементам массива Z присвоить значение 0. 23. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если хотя бы один элемент массива А встречается в массиве В, и false в противном случае. 24. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если 30 % элементов массива А встречается в массиве В, и false в противном случае. 25. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если сумма элементов массива А превосходит хотя бы один элемент массива В, и false в противном случае. 26. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если произведение четных по номеру элементов массива В не превосходит сумму нечетных по номеру элементов массива А, и false в противном случае. 27. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если хотя бы один элемент массива А не превосходит произведение элементов массива В, больших заданного Х, и false в противном случае. 28. Сформировать массив В из таких элементов массива А, среднее арифметическое которых не превышают заданного значения произведение С×D. Если таких элементов в массиве А нет, то выдать соответствующее сообщение. 29. Даны два массива X(N) и Y(M). Сформировать массив Z(N+M) из положительных элементов массивов X и отрицательных массива Y. Если таких 21
элементов меньше N+M, то оставшимся элементам массива Z присвоить значение 1. 30. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если все элементы массива А превосходят сумму элементов массива В, больших заданного Х, и false в противном случае. Общее задание для всех студентов группы Для массива, состоящего из N элементов, определить:  сумму значений элементов массива;  произведение значений элементов массива;  наименьшее значение в массиве и его индекс;  наибольшее значение в массиве и его индекс;  присвоить переменной F значение true, если хотя бы один элемент массива обладает заданным свойством (например, больше 0), и false — в противном случае;  присвоить переменной F значение true, если все элементы массива обладают заданным свойством (например, больше 0), и false — в противном случае. Методические указания Рассмотрим реализацию алгоритма поиска наименьшего номера k элемента массива A, значение которого равно заданному x: A[k] = x; k = min(Ai), i = 0, 1, … , N-1 Вариант 1. const int N = 10; int a[N], x, i = 0, k; //Ввод А и х while ((a[i] != x) && (i < N)) i++; if (a[i] == x) k = i; // элемент найден else // элемент не найден 22
Этот очевидный, на первый взгляд, код содержит фатальную ошибку. Пусть i = N–1 и A[ i ] не равно x — в этом случае условие продолжения цикла истинно. Тогда i++ равно N, и при вычислении выражения A[i]! = x в заголовке цикла происходит выход за пределы массива — A[ i ]  A[N]. Вариант 2. Исключим из заголовка цикла проверку A[i]! = x. Вместо этого будем использовать логическую переменную found. const int N = 10; int a[N], x, i = 0, k; bool found = false; //Ввод А и х . . . while ((!found) && (i < N)) if (a[i] == x){ found = true; break; } else i++; if (found) k = i; // элемент найден else //.элемент не найден Использование логической переменной found сделало код безопасней, но добавило ему сложность. Это, конечно, далеко не лучший вариант поиска! Вариант 3 — поиск «с барьером». Увеличим размер массива A на 1 и присвоим элементу A[N–1] значение х. A[N–1] — это «барьер». const int N = 11; int a[N], x, i = 0, k; a[N-1] = x; //Ввод А и х //. . . while (a[i] != x) 23
i++; if (i < N-1) k = i; // элемент найден else //.элемент не найден Реализация этого варианта может быть, например, такой: #include <iostream> using namespace std; int main() { const int N = 11; int a[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, x = 18, i = 0, k; a[N-1] = x; while (a[i] != x) i++; if (i < N - 1) k = i; // элемент найден else k = -1;//.элемент не найден cout << k; } Литература 1. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. — URL: http://cph.phys.spbu.ru/ documents/First/books/7.pdf (дата обращения: 06.10.2025). 2. Руководство по языку программирования C++ // METANIT.COM — Сайт о программировании : [сайт]. — URL: https://metanit.com/cpp/tutorial/?ysclid= lkavuhfusn202815661 (дата обращения: 02.10.2025). 3. Введение в программирование на языке С++ : лабораторный практикум / Л.В. Гурьянов, Л.С. Гурьянова, Е.А. Дзюба, Д.В. Такташкин. — Пенза : Изд-во ПГУ, 2010. — 170 с. — URL: http://elib.pnzgu.ru/library/10345800 (дата обращения: 06.10.2025). 24
Контрольные вопросы 1. Какие особенности структуры данных — массив? 2. Что такое операция индексации? 3. Что обозначает термин — структура с произвольной выборкой, и можно ли его применить к массиву? 4. Определите значение элемента массива с индексом 1, если массив определен следующим образом: int a[ArraySize] = {12, 3, 42, 5, 34}; 5. Можно ли определить массив следующим образом? 6. Можно ли определить массив следующим образом? 7. Можно ли определить массивы следующим образом? using I4 = int[3]; I4 a, b; I4 c = {-1, 2, -5}; 8. Как улучшить следующий код? int A[] = {-1, -2, 3, 4, 5}; bool found = false; for (int i = 0; i < N; ++i) { if (A[i] > 0) found = true; } cout << found << endl; //{1 - элемент найден, 0 – нет 25
9. Что не так в следующем коде? const int N = 3; int c[]{ -1, for (int i = if (c[i] a[i] 2, -3 }, a[N]; 0; i < N; ++i) > 0) = c[i]; 10. Можно ли использовать операцию присваивания для двух массивов? 26
ЛАБОРАТОРНАЯ РАБОТА № 4. ДВУМЕРНЫЕ МАССИВЫ Цель работы Познакомиться со структурой данных — двумерным массивом, особенностями и способами применения этой структуры в обработке данных. Подготовка к работе Изучить операторы объявления и инициализации двумерного массива, операции ввода/вывода значений массива в программах C++ в среде разработки Microsoft Visual Studio. Требования Реализовать простое приложение С++ обработки значений двумерного массива. Приложение должно выводить на консоль исходные данные и полученные результаты. Электронный отчет должен содержать:  заголовок: группа, ФИО студента, номер и текст варианта задания;  исходный код приложения и скриншоты выполнения программы. Варианты заданий 1. Поменять местами элементы квадратной матрицы A, размерностью N, расположенные на одной строке и принадлежащие главной и побочной диагоналям. 2. Найти минимальный элемент, расположенный на главной диагонали квадратной матрицы A, а из элементов строки и столбца, на пересечении которых он находится, сформировать одномерный массив B. 3. Среди элементов, расположенных ниже главной диагонали квадратной матрицы A, найти те элементы, которые удовлетворяют условию K1  Ai,j  K2 (K1, K2 — произвольные числа), и сформировать из них одномерный массив B. 27
4. Найти номер строки матрицы A, наиболее удаленной от первой строки, если расстояние S между строками L и K матрицы определяется по формуле: S ( L, K )   abs( AL , j  AK , j ) . j 5. Найти «седловую» точку матрицы — такой элемент Ai,j, который является наибольшим в строке i и наименьшим в столбце j. Если такого элемента нет, то выдать соответствующее сообщение. 6. Сформировать одномерный массив B, элементы Bi которого равны true, если элементы i-й строки матрицы A упорядочены по возрастанию, и false — в противном случае. 7. Сформировать одномерный массив B, элементы Bj которого равны 1, если хотя бы один элемент j-го столбца матрицы A больше суммы элементов этого столбца, и 0 — в противном случае. 8. Из массивов X(N) и Y(M) построить квадратную матрицу A размерностью K (K= N  M ) таким образом, чтобы элементы массива X были расположены на главной диагонали и выше ее. Значения N, M, K подобрать самостоятельно. 9. Задана целочисленная матрица A размерностью N×M и массив X(N). Обнулить строки матрицы с номером k, для которого X[k]  0. 10. Задана целочисленная матрица A размерностью N×M. Соседями элемента Ai,j, матрицы A будем считать элементы AK,L, для которых i–1  K  i+1 и j– 1  L  j+1; (K, L)  (i, j). Сформировать матрицу B путем «сглаживания» матрицы A — заменой каждого элемента A средним арифметическим его соседей (сглаживание — это замена каждого числа значением среднего арифметического трех стоящих рядом элементов). 11. Заданы целочисленные матрицы A, B размерностью N×M. Поменять местами столбец матрицы A, где расположен минимальный элемент, со столбцом матрицы B, где расположен максимальный элемент. 12. Заданы целочисленные квадратные матрицы A, B размерностью N. Вывести на экран значения той матрицы, которая содержит больше строк, с положительной суммой элементов. 13. Заданы целочисленные квадратные матрицы A, B размерностью N. Поменять местами строку матрицы A, которая содержит только положительные элементы и имеет минимальный номер в матрице A, со столбцом матрицы B, номер которого совпадает с номером найденной строки матрицы A. Если строка в матрице A не найдена, то выдать соответствующее сообщение. 28
14. Построить двумерный массив В, каждая строка которой содержит значение элемента одномерного массива А и количество его повторений в массиве. 15. Поменять местами элементы матрицы, расположенные в одном столбце и принадлежащие главной и побочной диагоналям. 16. Найти максимальный элемент, расположенный на главной диагонали матрицы A, а из положительных элементов строки и столбца, на пересечении которых он находится, сформировать одномерный массив B. 17. Среди элементов, расположенных выше главной диагонали матрицы A, найти те элементы, которые удовлетворяют условию –10  Ai,j  10, и сформировать из них одномерный массив B. 18. Найти номер строки матрицы A, наиболее удаленной от последней строки, если расстояние S между строками L и K матрицы определяется по формуле: S ( L, K )   ( AL, j  AK , j ) . j 19. Сформировать одномерный массив B, элементы которого Bi равны true, если элементы i-го столбца матрицы A упорядочены по убыванию, и false — в противном случае. 20. Сформировать одномерный массив B, элементы которого Bi равны 1, если хотя бы один элемент i-ой строки матрицы A больше произведения элементов i-го столбца, и 0 — в противном случае. 21. Из массивов X(N) и Y(M) построить квадратную матрицу A размерностью K (K = N  M ) таким образом, чтобы элементы массива Y были расположены на главной диагонали и ниже ее. Значения N, M, K подобрать самостоятельно. 22. Задана целочисленная матрица A размерностью N×M и массив X(М). Присвоить заданное значение B элементам столбца матрицы с номером k, для которого X[k]  0. 23. Заданы целочисленные матрицы A, B размерностью N×N. Поменять местами столбец матрицы A, где расположен максимальный элемент, со строкой матрицы B, где расположен минимальный элемент. 24. Заданы целочисленные квадратные матрицы A, B размерностью N. Присвоить переменной F значение true, если матрица A имеет хотя бы одну строку с положительной суммой элементов большей, чем положительные суммы элементов строк матрицы B, и false — в противном случае. Если строка в матрице A с положительной суммой элементов не найдена, то выдать соответствующее сообщение. 29
25. Заданы целочисленные квадратные матрицы A, B размерностью N. Поменять местами строку матрицы A, которая не содержит положительные элементы и имеет максимальный номер в матрице A, со столбцом матрицы B, произведение элементов которого положительно и номер которого минимальный в матрице B. Если строка в матрице A или столбец в матрице B не найдены, то выдать соответствующее сообщение. 26. Заданы целочисленные матрицы A, B размерностью N×М. Поменять местами строку матрицы A, где расположен максимальный элемент, с первой найденной строкой матрицы B, в которой только положительные элементы. Если в матрице В нет такой строки, выдать соответствующее сообщение. 27. Заданы целочисленные матрицы A, B размерностью N×N. Поменять местами столбец матрицы A, где расположен минимальный элемент, с первой найденной строкой матрицы B, в которой элементы не превосходят заданное Х. Если в матрице В нет такой строки, выдать соответствующее сообщение. 28. Сформировать одномерный массив B, элементы которого Bi равны 1, если все элементы i-ой строки матрицы A не превосходят элементы i-го столбца, и 0 — в противном случае. 29. Заданы целочисленные матрицы A, B размерностью N×N. Поменять местами столбец матрицы A с такой строкой матрицы B, где все элементы столбца матрицы A не превосходят минимальный элемент строки матрицы B. Если в матрицах нет таких строк, выдать соответствующее сообщение. 30. Сформировать одномерный массив B, элементы которого Bi равны -1, если хотя бы один элемент i-ого столбца матрицы A превосходит все элементы i-ой строки, и 0 — в противном случае. Методические указания Рассмотрим варианты инициализации двумерных массивов. Вариант 1. Инициализация массива в коде программы const int ArraySize1=3, // количество строк ArraySize2=2; // количество столбцов int a[ArraySize1][ArraySize2] ={ {12, 3}, // a[0][0]=12, a[0][1]=3, {42, 5}, // a[1][0]=42, a[1][1]=5, {10, 34} // a[2][0]=10, a[2][1]=34 }; 30
Вариант 2. Ввод значений массива с консоли. //начальные значения можно ввести и с клавиатуры: for (int i=0; i<ArraySize1;++i){ for (int j=0; j<ArraySize2; ++j) cin >>a[i][j]; } Вариант 3. Определение значений элементов главной диагонали квадратной матрицы. for (int i=0; i<ArraySize1;++i) cin >>a[i][i]; Литература 1. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. — URL: http://cph.phys.spbu.ru/ documents/First/books/7.pdf (дата обращения: 06.10.2025). 2. Руководство по языку программирования C++ // METANIT.COM — Сайт о программировании : [сайт]. — URL: https://metanit.com/cpp/tutorial/?ysclid= lkavuhfusn202815661 (дата обращения: 02.10.2025). 3. Введение в программирование на языке С++ : лабораторный практикум / Л.В. Гурьянов, Л.С. Гурьянова, Е.А. Дзюба, Д.В. Такташкин. — Пенза : Изд-во ПГУ, 2010. — 170 с. — URL: http://elib.pnzgu.ru/library/10345800 (дата обращения: 06.10.2025). Контрольные вопросы 1. Может ли быть двумерный массив не прямоугольным, и не числовым? 2. Верно ли утверждение, что двумерный массив — это одномерный массив одномерных массивов? 3. В каком случае можно утверждать, что значения двумерного массива в памяти располагаются построчно? 4. Где расположены вычисляемые элементы матрицы С? for (int i = 0, k=0; i < ArraySize2; ++i) for (int j = i; j < ArraySize2; ++j) с[i][j] = a[k++]; 31
5. Где расположены вычисляемые элементы матрицы С? for (int i = 1, k=0; i < ArraySize2; ++i) for (int j = 0; j < i; ++j) с[i][j] = b[k++]; 6. Можно ли улучшить следующий код? int total = 0; for (int i = 0; i < ArraySize; ++i) for (int j = 0; j < ArraySize; ++j) if(j==i) total += a[i][j]; 7. Напишите код вывода значений матрицы по строкам. 8. Напишите код вывода значений матрицы по столбцам. 9. Напишите код поиска минимального значения на главной диагонали квадратной матрицы. 10. Напишите код поиска максимального значения на побочной диагонали квадратной матрицы. 32
ЛАБОРАТОРНАЯ РАБОТА № 5. ФУНКЦИИ Цель работы Познакомиться с понятием функции в программировании и научиться писать код функции на языке С++. Подготовка к работе Изучить синтаксис определения функции, способы передачи параметров и возвращения результата функции в программах C++. Требования Реализовать приложение С++ с функциями обработки данных массива. Операции ввода/вывода исходных данных и результатов обработки осуществляет главная программа. Приложение должно быть реализовано как с использованием операторов структурного подхода, так и с использованием алгоритмов библиотеки STL и лямбда-выражений. Электронный отчет должен содержать:  заголовок: группа, ФИО студента, номер и текст варианта задания;  исходный код приложения и скриншоты выполнения программы. Варианты заданий 1. Сформировать новый массив, переписывая в него положительные значения из исходного массива до первого его отрицательного элемента. 2. Сформировать новый массив, записав в него сумму и произведение элементов исходного массива до первого его отрицательного значения. 3. Сформировать новый массив из значений исходного, удалив все элементы до первого отрицательного значения исходного массива. 4. В новый массив записать все отрицательные значения исходного массива, которые находятся после первого его положительного элемента. 5. Сформировать новый массив путем сглаживания элементов исходного массива (сглаживание — это замена каждого числа значением среднего арифметического трех стоящих рядом элементов). 33
6. Сформировать новый массив из значений исходного массива, заменяя нулями наименьшее и наибольшее значения элементов исходного массива. 7. Сформировать новый массив, записывая в него все значения исходного массива, меньшие его среднего арифметического значения. 8. Сформировать массив, содержащий для каждого элемента исходного массива отклонение от среднего арифметического. 9. Записать в новый массив все элементы исходного массива, которые находятся в промежутке между его экстремумами. 10. Сформировать новый массив, из элементов исходного массива без отрицательных элементов, расположенных до минимального элемента исходного массива. 11. Сформировать новый массив, из элементов исходного массива без положительных элементов, расположенных после максимального элемента исходного массива. 12. Поменять местами наименьшее и наибольшее значения соответственно с первым и последним элементами массива и сформировать новый массив из первых двух и двух последних элементов исходного массива (размерность не менее 4). 13. Найти в массиве все элементы, значения которых не принадлежат некоторому указанному диапазону [А; В], и сформировать из них новый массив. 14. Записать в новый массив все значения исходного, которые находятся от первого нулевого значения до последнего нулевого значения. 15. Удалить из массива первый положительный и первый отрицательный элементы и сформировать из оставшихся значений новый массив. 16. Сформировать новый массив слиянием двух исходных массивов одинаковой длины. В новом массиве значения исходных массивов чередуются. 17. Найти значения первого положительного и последнего отрицательного элементов массива и записать их в новый массив. 18. Сформировать новый массив, заполняя его значениями исходного массива в обратном порядке, если значения исходного массива упорядочены по возрастанию. 19. Сформировать новый массив, заполняя его значениями исходного массива с противоположным знаком, если в исходном массиве значения знакопеременные. 20. Записать в новый массив те значения исходного массива, которые отличаются от среднего арифметического элементов массива не более чем на заданное значение. 34
21. Определить количество четных и нечетных элементов массива и, если четных значений больше, сформировать из четных значений новый массив. 22. Определить, образуют ли элементы массива арифметическую прогрессию и, если нет, то сформировать новый массив из элементов исходного до первого нарушения. 23. Преобразовать исходный массив в новый, удаляя из него все отрицательные и равные нулю значения. 24. Найти наибольшее из нечетных чисел исходного массива и переписать в новый массив все значения исходного до найденного наибольшего. 25. Найти наименьшее из четных чисел и переписать в новый массив все значения исходного после найденного наименьшего. 26. Расположить элементы массива в обратном порядке, не используя вспомогательный массив, и найти произведение первых трех элементов после перестановки. 27. Записать в новый массив все значения исходного массива, не превосходящие найденное среднее арифметическое значение. 28. Найти сумму нечетных и отрицательных элементов исходного массива и сформировать новый массив тех чисел исходного, которые не превосходят найденную сумму. 29. Записать все локальные минимумы в новый массив. Локальным минимумом называется любой элемент массива, который меньше своих соседей. 30. Определить номер элемента массива, ближайшего к среднему арифметическому элементу массива, и сформировать новый массив из значений исходного, заменяя найденное ближайшее значение на 100. Методические указания Рассмотрим примеры использования функций в программах на С++. Пример 1. Простые функции. //функция вычисления суммы двух значений int add ( int x, int y) { return x + y; } //функция выводит значение суммы двух чисел, 35
//но не возвращает результат void print ( int x, int y) { cout << x + y; } //программа с функцией вычисления суммы двух чисел #include <iostream> using namespace std; int add ( int , int ); //прототип функции int main() { int z; z = add ( 1, 2); // вызов функции add cout << "z= "<<z<<endl; int a=1, b=2; z = add ( a, b); // вызов функции add cout << "z= "<<z<<endl; } //функция вычисления суммы двух значений int add ( int x, int y) { return x + y; } Пример 2. Лямбда-выражение вычисления суммы двух значений. #include <iostream> int main() { // лямбда-выражение auto sum{ [](int a, int b) {return a + b; } }; // вызываем лямбда-выражение std::cout << sum(10, 23) << std::endl; // 33 // присваиваем результат лямбда-выражения переменной int result{ sum(1, 4) }; std::cout << result << std::endl; // 5 } 36
Пример 3. Передача массива в качестве параметра. #include <iostream> using namespace std; // прототип функции, параметры: адрес и размер массива int summa(const int[], const int); int main() { setlocale(LC_ALL, "Russian"); const int ArraySize=5; // размер массива int a[ArraySize]{1, 3, 4, 5, 2}; // инициализация массива for (int i=0; i<ArraySize;++i) // вывод массива cout<<a[i]<<endl; cout <<"Сумма элементов массива: "<<summa(a, ArraySize) <<endl; return 0; } int summa(const int x[], const int n) { int total=0; // сумма значений элементов массива for (int i=0; i<n; ++i)// цикл вычисления суммы total+=x[i]; return total; } Пример 4. Лямбда-выражение как параметр функции. #include <iostream> #include <algorithm> #include <cmath> void abssort(int x[], unsigned n); int main() { int numbers[]{ 1, 4, 3, 5, 2 }; for (const auto& n : numbers) { std::cout << n << "\t"; 37
} std::cout << std::endl; abssort(numbers, 5); for (const auto& n : numbers) { std::cout << n << "\t"; } std::cout << std::endl; return 0; } void abssort(int x[], unsigned n) { std::sort(x, x + n, [](int a, int b) {// лямбда-выражение return (std::abs(a) < std::abs(b)); } ); } Пример 5. Алгоритмы. #include <iostream> #include <algorithm> using namespace std; int find1Minus(int[], const int); void formArray(int[], const int); int main() { int numbers[]{ 1, 4, -3, 5, -2 }; int k; if ((k = find1Minus(numbers, 5)) >= 0) cout << numbers[k] << endl; formArray(numbers, 5); copy(begin(numbers), end(numbers), ostream_iterator<int>(cout, " cout << endl; 38 "));
reverse(numbers, numbers+5); for (const auto& n : numbers) { cout << n << "\t"; } cout << endl; cout << * min_element(numbers, numbers+5)<< endl; return 0; } int find1Minus(int a[], const int n) { int* ptr_ax = std::find_if(a, a+n, [&](int x) {return (x < 0); }); if (ptr_ax != a + n) { return (ptr_ax - a); } return -1; } void formArray(int a[], const int n) { for_each(a, a + n, [](int& x) {x *= 2;}); } Литература 1. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. — URL: http://cph.phys.spbu.ru/documents/First/books/7.pdf (дата обращения: 06.10.2025). 2. Руководство по языку программирования C++ // METANIT.COM — Сайт о программировании : [сайт]. — URL: https://metanit.com/cpp/tutorial/?ysclid= lkavuhfusn202815661 (дата обращения: 02.10.2025). 3. Введение в программирование на языке С++ : лабораторный практикум / Л.В. Гурьянов, Л.С. Гурьянова, Е.А. Дзюба, Д.В. Такташкин. — Пенза : Изд-во ПГУ, 2010. — 170 с. — URL:http://elib.pnzgu.ru/library/10345800 (дата обращения: 06.10.2025). 39
Контрольные вопросы 1. 2. 3. 4. 5. 6. 7. 8. В каких случаях следует использовать функции? Что такое «правило одного задания» функции? В чем отличие глобальных и локальных переменных? Что такое параметры функции? В чем заключается способ передачи параметров значением? В чем заключается способ передачи параметров по адресу? Что такое прототип функции и как он определяется? Что возвращает данная функция, если параметр имеет значение 10? int inc ( int n) { return ++n; } 9. Что возвращает данная функция, если параметр имеет значение 10? int inc ( int n) { return n++; } 10. Что такое прототип функции и как он определяется? 40
ЛАБОРАТОРНАЯ РАБОТА № 6. ПЕРЕГРУЗКА И ШАБЛОН ФУНКЦИИ Цель работы Познакомиться с понятиями «перегрузка функций» и «шаблон функции», научиться писать код на языке С++, реализующий эти понятия. Подготовка к работе Изучить синтаксис перегрузки и шаблона функции, рассмотреть способы реализации перегрузки и шаблона функций. Требования Реализовать приложение С++ на основе созданного приложения лабораторной работы 5 с добавлением перегрузки и шаблона функции. Приложение должно выводить на консоль исходные данные и полученные результаты. Электронный отчет должен содержать:  заголовок: группа, ФИО студента, номер и текст варианта задания;  исходный код приложения и скриншоты выполнения программы. Варианты заданий 1. Сформировать новый массив, переписывая в него положительные значения из исходного массива до первого его отрицательного элемента. 2. Сформировать новый массив, записав в него сумму и произведение элементов исходного массива до первого его отрицательного значения. 3. Сформировать новый массив из значений исходного, удалив все элементы до первого отрицательного значения исходного массива. 4. В новый массив записать все отрицательные значения исходного массива, которые находятся после первого его положительного элемента. 5. Сформировать новый массив путем сглаживания элементов исходного массива (сглаживание — это замена каждого числа значением среднего арифметического трех стоящих рядом элементов). 6. Сформировать новый массив из значений исходного массива, заменяя нулями наименьшее и наибольшее значения элементов исходного массива. 41
7. Сформировать новый массив, записывая в него все значения исходного массива, меньшие его среднего арифметического значения. 8. Сформировать массив, содержащий для каждого элемента исходного массива отклонение от среднего арифметического. 9. Записать в новый массив все элементы исходного массива, которые находятся в промежутке между его экстремумами. 10. Сформировать новый массив, из элементов исходного массива без отрицательных элементов, расположенных до минимального элемента исходного массива. 11. Сформировать новый массив, из элементов исходного массива без положительных элементов, расположенных после максимального элемента исходного массива. 12. Поменять местами наименьшее и наибольшее значения соответственно с первым и последним элементами массива и сформировать новый массив из первых двух и двух последних элементов исходного массива (размерность не менее 4). 13. Найти в массиве все элементы, значения которых не принадлежат некоторому указанному диапазону [а; в], и сформировать из них новый массив. 14. Записать в новый массив все значения исходного, которые находятся от первого нулевого значения до последнего нулевого значения. 15. Удалить из массива первый положительный и первый отрицательный элементы и сформировать из оставшихся значений новый массив. 16. Сформировать новый массив слиянием двух исходных массивов одинаковой длины. В новом массиве значения исходных массивов чередуются. 17. Найти значения первого положительного и последнего отрицательного элементов массива и записать их в новый массив. 18. Сформировать новый массив, заполняя его значениями исходного массива в обратном порядке, если значения исходного массива упорядочены по возрастанию. 19. Сформировать новый массив, заполняя его значениями исходного массива с противоположным знаком, если в исходном массиве значения знакопеременные. 20. Записать в новый массив те значения исходного массива, которые отличаются от среднего арифметического элементов массива не более чем на заданное значение. 21. Определить количество четных и нечетных элементов массива и, если четных значений больше, сформировать из четных значений новый массив. 42
22. Определить, образуют ли элементы массива арифметическую прогрессию и, если нет, то сформировать новый массив из элементов исходного до первого нарушения. 23. Преобразовать исходный массив в новый, удаляя из него все отрицательные и равные нулю значения. 24. Найти наибольшее из нечетных чисел исходного массива и переписать в новый массив все значения исходного до найденного наибольшего. 25. Найти наименьшее из четных чисел и переписать в новый массив все значения исходного после найденного наименьшего. 26. Расположить элементы массива в обратном порядке, не используя вспомогательный массив, и найти произведение первых трех элементов после перестановки. 27. Записать в новый массив все значения исходного массива, не превосходящие найденное среднее арифметическое значение. 28. Найти сумму нечетных и отрицательных элементов исходного массива и сформировать новый массив тех чисел исходного, которые не превосходят найденную сумму. 29. Записать все локальные минимумы в новый массив. Локальным минимумом называется любой элемент массива, который меньше своих соседей. 30. Определить номер элемента массива, ближайшего к среднему арифметическому элементов массива и сформировать новый массив из значений исходного, заменяя найденное ближайшее значение на 100. Методические указания Рассмотрим примеры использования перегрузки и шаблонов функций в программах на С++. Пример 1. Перегрузка функций вычисления квадрата переменной. #include <iostream> using std::endl; using std::cout; int square(int x){ return x * x;} double square(double y){ return y * y;} int main() { 43
cout<<"Квадрат целого числа 7 = " << square(7) <<endl; cout<<"Квадрат вещественного числа 7.5 = " <<square(7.5) <<endl; return 0; } Пример 2. Шаблон функции вычисления квадрата переменной. #include <iostream> using std::endl; using std::cout; template <typename T> T square(T); функции //прототип шаблона int main() { setlocale(LC_ALL, "Russian"); cout << "Квадрат целого числа 7 = " << square(7) << endl; cout << "Квадрат вещественного числа 7.5 = " << square(7.5)<< endl; return 0; } //реализация шаблона функции с параметром типа T template <typename T> T square(T value) { return value * value; } Литература 1. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. — URL: http://cph.phys.spbu.ru/ documents/First/books/7.pdf (дата обращения: 06.10.2025). 44
2. Руководство по языку программирования C++ // METANIT.COM — Сайт о программировании : [сайт]. — URL: https://metanit.com/cpp/tutorial/?ysclid= lkavuhfusn202815661 (дата обращения: 02.10.2025). 3. Введение в программирование на языке С++ : лабораторный практикум / Л.В. Гурьянов, Л.С. Гурьянова, Е.А. Дзюба, Д.В. Такташкин. — Пенза : Изд-во ПГУ, 2010. — 170 с. — URL: http://elib.pnzgu.ru/library/10345800 (дата обращения: 06.10.2025). Контрольные вопросы 1. Перегруженные функции должны находиться в одной области видимости? 2. Могут ли перегруженные функции иметь параметры по умолчанию? 3. Можно ли перегрузить функции, если описание их параметров: int и const int или int и int&? 4. Что выведет следующая программа, если функция repchar() выводит заданный символ заданное число раз? #include <iostream> using namespace std; void repchar(char = '*', int = 15); int main() { repchar(); repchar('='); repchar('+', 30); return 0; } 5. Для чего используется шаблон функции? 6. Что определяет шаблон функции? template < typename Туре> void add(Туре, Туре); 45
7. В определении шаблона функции что можно задать вместо typename? template < typename Туре> заголовок{. . .} 8. В определении шаблона функции что можно задать вместо Туре? template < typename Туре> заголовок{. . .} 9. Можно ли «вручную» задать вариант шаблона функции? 10. Можно ли использовать ссылки, указатели, массивы, которые представляют тип параметра шаблона? Например, так: template < typename T> T add(const T&, const T&); 46
ЛАБОРАТОРНАЯ РАБОТА № 7. СТРОКИ КАК МАССИВЫ СИМВОЛОВ Цель работы Познакомиться со структурой данных — строка, особенностями представления строк как массива символов Подготовка к работе Изучить синтаксис объявления строк, функции их обработки и примеры использования строк в программах С++. Требования Реализовать приложение С++ с использованием функций обработки строк, представленных как массив символов. Реализация задания осуществляется в разработанной студентом функции. Ввод исходных данных и вывод результатов осуществляет главная программа. Приложение должно выводить на консоль исходные данные и полученные результаты. Электронный отчет должен содержать:  заголовок: группа, ФИО студента, номер и текст варианта задания;  исходный код приложения и скриншоты выполнения программы. Варианты заданий Внимание! Длина исходных строк не превышает 80 символов. Все слова разделены строго одним пробелом. 1. В предложении заменить в словах одинаковые, стоящие подряд символы одним символом, после которого в скобках указать количество символов, которые были заменены. 2. Найти в предложении слова длиной не более 6 символов, в которых количество гласных букв составляет не менее 30 %. 3. Найти в предложении все слова, которые являются палиндромами. 47
4. Заменить в предложении символы «abc» в начале слова на символы «123». 5. Найти в предложении все слова, в которых встречаются первые три буквы первого слова предложения. 6. В предложении S найти все слова, которые содержат строку S1 (длина 2 символа) или строку S2 (длина 3 символа). 7. В предложении S1 найти самое длинное слово, которое отсутствует в предложении S2. 8. В предложении S1 найти все слова с символом «1», которые есть в предложении S2. 9. Присвоить переменной F значение true, если из символов предложения S1 можно составить слово S2, и false — в противном случае. 10. Найти в предложении слова длиной не более 6 символов, в которых отсутствуют символы строки S2 (длина 3 символа). Если таких слов нет, выдать соответствующее сообщение. 11. Найти в предложении все слова без символа «а», которые не являются палиндромами. 12. Заменить в предложении S1 все слова, в которых есть символы ‘a’ или ‘b’ на первое слово предложения S2, в котором есть символ ‘c’. Если таких слов нет, то выдать соответствующее сообщение. 13. Найти в предложении все слова, в которых встречаются первые три символа последнего слова предложения. Если таких слов нет, выдать соответствующее сообщение. 14. В предложении S найти все слова, которые не содержат строку S1 (длина 2 символа) и содержат строку S2 (длина 3 символа). Если таких слов нет, выдать соответствующее сообщение. 15. В предложении S1 найти самое короткое слово, которое присутствует в предложении S2. Если такого слова нет, выдать соответствующее сообщение. 16. Присвоить переменной F значение true, если в предложении S1 есть хотя бы одно слово, которое отсутствует в предложении S2, и false — в противном случае. 17. Присвоить переменной F значение true, если в предложении S1 есть хотя бы одно слово, которое присутствует в предложении S2 и длина которого не превышает 6 символов, в противном случае присвоить переменной F — false. 48
18. Сформировать предложении S из таких слов предложения S1, которые не содержат символы строки S2 (длина 3 символа). Если таких слов нет, выдать соответствующее сообщение. 19. Сформировать предложении S из таких слов предложения S1, которые не содержат заданные символы (3 символа). Если таких слов нет, выдать соответствующее сообщение. 20. Присвоить переменной F значение true, если в предложении S1 есть хотя бы одно слово, которое отсутствует в предложении S2 и длина которого не превышает длину самого короткого слова S2, в противном случае присвоить переменной F — false. 21. Присвоить переменной F значение true, если в предложении S2 есть хотя бы одно слово предложения S1 и длина которого превышает длину самого короткого слова S1, в противном случае присвоить переменной F — false. 22. Сформировать предложении S из таких слов предложения S1 и S2, длина которых меньше самого короткого слова предложения S3. Если таких слов нет, выдать соответствующее сообщение. 23. Присвоить переменной F значение true, если в предложении S все слова содержат хотя бы один символ из слова S1, в противном случае присвоить переменной F — false. 24. Присвоить переменной F значение true, если в предложении S все слова не содержат первый и последний символы из слова S1, в противном случае присвоить переменной F — false. 25. Сформировать предложении S из таких слов предложения S1, длина которых меньше числа гласных символов слова S2. Если таких слов нет, выдать соответствующее сообщение. 26. Сформировать предложении S из таких слов предложения S1, в которых нет заданных символов (3 символа) и длина которых не менее 3-х символов. Если таких слов нет, выдать соответствующее сообщение. 27. Присвоить переменной F значение true, если в предложении S нет слов, которые содержат первый и второй символы из слова S1, в противном случае присвоить переменной F — false. 28. Сформировать предложении S из таких слов предложения S1, в которых нет символов заданного слова (5 символа) и длина которых не менее 4-х символов. Если таких слов нет, выдать соответствующее сообщение. 29. Присвоить переменной F значение true, если в предложении S есть слова, которые содержат хотя бы один символ из слов S1 и S2, в противном случае присвоить переменной F — false. 49
30. Присвоить переменной F значение true, если в предложении S есть слова, которые не содержат символы из слова S1 и длина которых не превышает 4 символов, в противном случае присвоить переменной F — false. Методические указания Рассмотрим примеры использования функций обработки строк, представленных как массивы символов. Пример 1. Копирование и сравнение строк. #include <iostream> using namespace std; void copy1(char str1[], const char str2[]); void copy2(char str1[], const char str2[]); int main() { setlocale(LC_ALL, "Russian"); //копирование строк char s1[10], *s2 = (char*)("Hi"), s3[10], s4[] = "Good Bye"; copy1(s1, s2); copy2(s3, s4); cout << "строка1 cout << "строка2 cout << "строка3 cout << "строка4 : : : : " " " " << << << << s1 s2 s3 s4 << << << << endl; endl; endl; endl; //копирование строк с использованием strcpy_s, strncpy_s char s1_1[]{"Happy Birthday to You"}; // или char s1_1[] = "Happy Birthday to You"; char s2_2[25], s3_3[15]; cout << "строка1_1: " << s1_1 << endl; strcpy_s(s2_2, s1_1); cout << "строка2_2: " << s2_2 << endl; 50
strncpy_s(s3_3, s1_1, 14); s3_3[14] = '\0'; cout << "строка3_3: " << s3_3 << endl; //сравнение строк char s5[] = "Happy New Year"; char* s6 { (char*)"Happy New Year" }; // или char* s6= (char*)"Happy New Year"; char s7[] = "Happy Holidays"; cout << "строка5 : " << s5 << endl; cout << "строка6 : " << s6 << endl; cout << "строка7 : " << s7 << endl; cout << "сравнение s5 с s6: " << strcmp(s5, s6) << endl; cout << "сравнение s5 с s7: " << strcmp(s5, s7) << endl; cout << "сравнение 5 символов s5 с s7: " << strncmp(s5, s7, 5) << endl; return 0; } //примеры функций копирования строк void copy1(char str1[], const char str2[]) { for (int i = 0; (str1[i] = str2[i]) != '\0'; ++i); } void copy2(char str1[], const char str2[]) { for (; (*str1 = *str2) != '\0'; str1++, str2++); } Пример 2. Строки — параметры функций. #include <iostream> using namespace std; void findS1InS2(char[], char[], char[]);//поиск слов S1 в строке S2 51
int main() { char string1[] = "1 2 34 5 8 3 9"; //исходная строка char string2[] = "1 2 3 58 5 4 1"; //исходная строка char string3[80] = ""; //результирующая строка findS1InS2(string1, string2, string3); cout << string3 << endl; return 0; } void findS1InS2(char s1[], char s2[], char s3[]) { char p3[80]; //копия строки s2 s3[0] = NULL; //'\0'//ОБЯЗАТЕЛЬНО ОБНУЛИТЬ!!! char* p1, * pp1; //указатели на начало текущего слова и //остаток s1 char* p2, * pp2; //указатели на начало текущего слова и //остаток s2 p1 = strtok_s(s1, " ", &pp1); //strtok_s - функция //возвращает указатель на первый символ из s1 до //указанного ограничителя – пробела //pp1 – указатель на символ после ограничителя(хвост s1) while (p1 != NULL) { strcpy_s(p3, s2); p2 = strtok_s(p3, " ", &pp2); while (p2 != NULL) { if (!strcmp(p1, p2)) { strcat_s(s3, 80, p1);//добавление в конец //s3 символов p1 strcat_s(s3, 80, " "); break; } p2 = strtok_s(NULL, " ", &pp2); } p1 = strtok_s(NULL, " ", &pp1); } } 52
Пример 3. Поиск гласных букв. #include <iostream> int main() { char str[] = "Police Academy"; char key[] = "aeiou"; std::cout << "Finding vowels in a string" << str << std::endl; char* pch = strpbrk(str, key); // первый поиск while (pch != NULL) // пока есть гласные буквы в строке { std::cout << *pch << " "; // гласный символ pch = strpbrk(pch + 1, key); // поиск гласных букв } std::cout << "\n"; return 0; } Пример 4. Массивы строк. #include <iostream> using namespace std; int main() { const int max_length{ 50 };// максимальная длина строки //включая нулевой байт \0 char langs[][max_length]{ "C++", "C#", "Python", "Java", "Kotlin", "Go", "Dart", "PHP" }; cout << langs[0] << endl; // C++ cout << langs[1] << endl; // C# cout << langs[2] << endl; // Python cout << endl; for (int j = 0; j < size(langs); j++) 53
cout << langs[j] << endl; cout << endl; for (auto lang : langs) { cout << lang << std::endl; } cout << endl; } Литература 1. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. — URL: http://cph.phys.spbu.ru/ documents/First/books/7.pdf (дата обращения: 06.10.2025). 2. Руководство по языку программирования C++ // METANIT.COM — Сайт о программировании : [сайт]. — URL: https://metanit.com/cpp/tutorial/ ?ysclid=lkavuhfusn202815661 (дата обращения: 02.10.2025). 3. Введение в программирование на языке С++ : лабораторный практикум / Л.В. Гурьянов, Л.С. Гурьянова, Е.А. Дзюба, Д.В. Такташкин. — Пенза : Изд-во ПГУ, 2010. — 170 с. — URL: http://elib.pnzgu.ru/library/10345800 (дата обращения: 06.10.2025). Контрольные вопросы 1. Чем отличается массив символов (строка) от массива целых чисел? 2. Что выведет на консоль следующий код? char* str = (char*)"Vasia"; str[1] ='u'; cout << str <<endl; 3. Есть ли ошибки в следующем коде? Если есть, как их исправить? char* str1 = (char*)"Vasia", *str2; for (int i = 0; (str2[i] = str1[i]) != '\0'; ++i); cout << str2 << endl; 4. Есть ли разница в определении строк? char str[10]; и char str[10]{}; 54
5. Для чего используется функция strchr и что она возвращает? 6. Что выводит на консоль следующий код? char s1[] = "1 2 34 5 8 3 9"; char* p1, * pp1; p1 = strtok_s(s1, " ", &pp1); cout << p1 << endl; 7. Что выводит на консоль следующий код? char s1[] = "Happy New Year"; char s2[] = "Happy Holidays"; cout << strcmp(s1, s2)<< endl; 8. Что выводит на консоль следующий код? char s1[] = "Happy New Year"; char* s2 = (char*)"Happy New Year"; cout << strcmp(s1, s2)<< endl; 9. Что выведет функция size(langs), если задана следующая структура данных? const int max_length{5}; char langs[][max_length]{"C++", "C#", "Java", "Go"}; 10. Есть ли ошибки в следующем коде? Если есть, как их исправить? const int max_length{5}; char langs[][max_length]{"C++", "Python", "Java"}; 55
ЛАБОРАТОРНАЯ РАБОТА № 8. СТРОКИ — ОБЪЕКТЫ КЛАССА STRING Цель работы Познакомиться со структурой данных — строкой, особенностями представления строки как объекта класса string. Подготовка к работе Изучить синтаксис объявления строк, функции их обработки и примеры использования строк в программах С++. Требования Реализовать приложение/приложения С++ с использованием функций обработки строк, представленных как объекты класса string. Реализация задания осуществляется в разработанной студентом функции. Ввод исходных данных и вывод результатов осуществляет главная программа. Приложение должно выводить на консоль исходные данные и полученные результаты. Электронный отчет должен содержать:  заголовок: группа, ФИО студента, номер и текст варианта задания;  исходный код приложения и скриншоты выполнения программы. Варианты заданий Внимание! Длина исходных строк не превышает 80 символов. Все слова разделены строго одним пробелом. 1. В заданном предложении заменить в словах одинаковые, стоящие подряд символы одним символом, после которого в скобках указать количество символов, которые были заменены. 2. Найти в предложении слова длиной не более 6 символов, в которых количество гласных букв составляет не менее 30 % 3. Найти в предложении все слова, которые являются палиндромами. 56
4. Заменить в предложении окончания слов «ing» на окончания «ed». 5. Найти в предложении все слова, в которых встречаются первые три буквы первого слова предложения. 6. В предложении S найти все слова, которые содержат строку S1 (длина 2 символа) или строку S2 (длина 3 символа). 7. В предложении S1 найти самое длинное слово, которое отсутствует в предложении S2. 8. В предложении S1 найти все слова, которые есть в предложении S2. 9. Присвоить переменной F значение true, если из символов предложения S1 можно составить слово S2, и false - в противном случае. 10. Найти в предложении слова длиной не более 6 символов, в которых отсутствуют символы строки S2 (длина 3 символа). Если таких слов нет, выдать соответствующее сообщение. 11. Найти в предложении все слова, которые не являются палиндромами. 12. Заменить в предложении S1 все слова, в которых есть символы ‘a’ или ‘b’ на первое слово предложения S2, в котором есть символ ‘c’. Если таких слов нет, то выдать соответствующее сообщение. 13. Найти в предложении все слова, в которых встречаются первые три символа последнего слова предложения. Если таких слов нет, выдать соответствующее сообщение. 14. В предложении S найти все слова, которые не содержат строку S1 (длина 2 символа) и содержат строку S2 (длина 3 символа). Если таких слов нет, выдать соответствующее сообщение. 15. В предложении S1 найти самое короткое слово, которое присутствует в предложении S2. Если такого слова нет, выдать соответствующее сообщение. 16. Присвоить переменной F значение true, если в предложении S1 есть хотя бы одно слово, которое отсутствует в предложении S2, и false — в противном случае. 17. Присвоить переменной F значение true, если в предложении S1 есть хотя бы одно слово, которое присутствует в предложении S2 и длина которого не превышает 6 символов, в противном случае присвоить переменной F — false. 18. Сформировать предложении S из таких слов предложения S1, которые не содержат символы строки S2 (длина 3 символа). Если таких слов нет, выдать соответствующее сообщение. 57
19. Сформировать предложении S из таких слов предложения S1, которые не содержат заданные символы (3 символа). Если таких слов нет, выдать соответствующее сообщение 20. Присвоить переменной F значение true, если в предложении S1 есть хотя бы одно слово, которое отсутствует в предложении S2 и длина которого не превышает длину самого короткого слова S2, в противном случае присвоить переменной F — false. 21. Присвоить переменной F значение true, если в предложении S2 есть хотя бы одно слово предложения S1 и длина которого превышает длину самого короткого слова S1, в противном случае присвоить переменной F — false. 22. Сформировать предложении S из таких слов предложения S1 и S2, длина которых меньше самого короткого слова предложения S3. Если таких слов нет, выдать соответствующее сообщение. 23. Присвоить переменной F значение true, если в предложении S все слова содержат хотя бы один символ из слова S1, в противном случае присвоить переменной F — false. 24. Присвоить переменной F значение true, если в предложении S все слова не содержат первый и последний символы из слова S1, в противном случае присвоить переменной F — false. 25. Сформировать предложении S из таких слов предложения S1, длина которых меньше числа гласных символов слова S2. Если таких слов нет, выдать соответствующее сообщение 26. Сформировать предложении S из таких слов предложения S1, в которых нет заданных символов (3 символа) и длина которых не менее 3-х символов. Если таких слов нет, выдать соответствующее сообщение. 27. Присвоить переменной F значение true, если в предложении S нет слов, которые содержат первый и второй символы из слова S1, в противном случае присвоить переменной F — false. 28. Сформировать предложении S из таких слов предложения S1, в которых нет символов заданного слова (5 символа) и длина которых не менее 4-х символов. Если таких слов нет, выдать соответствующее сообщение. 29. Присвоить переменной F значение true, если в предложении S есть слова, которые содержат хотя бы один символ из слов S1 и S2, в противном случае присвоить переменной F — false. 30. Присвоить переменной F значение true, если в предложении S есть слова, которые не содержат символы из слова S1 и длина которых не превышает 4 символов, в противном случае присвоить переменной F — false. 58
Методические указания Рассмотрим примеры использования функций обработки строк, представленных как объекты класса string. Пример 1. Примеры функций обработки строк. #include <iostream> #include <string> using namespace std; int main() { setlocale(LC_ALL, "Russian"); string s1("Quick! Send for Count Graystone."); // Применение функций insert, erase, replace, append: string s2("Lord"), s3("Don't "); cout << "s1= " << s1 << endl; cout << "s2= " << s2 << endl; cout << "s3= " << s3 << endl; s1.erase(0, 7); //удаление "Quick! " s1.replace(9, 5, s2); //замена "Count" на "Lord" s1.replace(0, 1, "s");//замена'S' на 's' s1.insert(0, s3); //вставка "Don't " в начало s1.erase(s1.size() - 1, 1); //удаление '.' s1.append(3, '!'); //добавление "!!!" // Применение функций find: int x = s1.find(' '); //найти первый пробел while (x < s1.size()) { //цикл пока пробел найден s1.replace(x, 1, "/"); //замена пробела на "/" x = s1.find(' '); //поиск следующего пробела } cout << "s1: " << s1 << endl; string s4("лесная королева"), s5("ле"), s6("корова"); cout << "s4= " << s4 << endl; cout << "s5= " << s5 << endl; cout << "s6= " << s6 << endl; int i = s4.find(s5); int j = s4.rfind(s5); 59
cout << "первое s5 в s4 cout << "последнее s5 в s4 cout << "первое 'о' в s4 " << i << endl; " << j << endl; " << s4.find('о') << endl; cout << "последнее 'о' в s4 " << s4.rfind('о') << endl; cout << "первое в s4 " << s4.find_first_of("абвгде") << endl; cout << "последнее в s4 " << s4.find_last_of("абвгде") << endl; // Применение функции compare: if (s5.compare(s6) > 0) cout << "s5 > s6 " << endl; if (s4.compare(7, 4, s6) < 0) cout << "sl[7-10] < s6 " << endl; if(s1.compare(7, 4, s3, 0, 4) == 0) cout << "s4[7-10] == s6[0-3] " << endl; } Литература 1. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. — URL: http://cph.phys.spbu.ru/ documents/First/books/7.pdf (дата обращения: 06.10.2025). 2. Руководство по языку программирования C++ // METANIT.COM — Сайт о программировании : [сайт]. — URL: https://metanit.com/cpp/tutorial/ ?ysclid=lkavuhfusn202815661 (дата обращения: 02.10.2025). 3. Введение в программирование на языке С++ : лабораторный практикум / Л.В. Гурьянов, Л.С. Гурьянова, Е.А. Дзюба, Д.В. Такташкин. — Пенза : Изд-во ПГУ, 2010. — 170 с. — URL: http://elib.pnzgu.ru/library/10345800 (дата обращения: 06.10.2025). Контрольные вопросы 1. Чем отличается строка string от массива символов? 2. Что выведет на консоль следующий код? string s("C++"); 60
cout << s << endl << s.at(1) << endl; 3. Есть ли ошибки в следующем коде? Если есть, как их исправить? string s("Python"); cout << s << endl << s.at(10) << endl; 4. Можно ли инициализировать строки следующим образом? string s("C#"); string s1(s); 5. Для строки string s справедливо ли утверждение? &s[0] равно s? 6. В следующем коде равносильно s2 = s1? string s1("Java"), s2; s2.assign(s1); 7. Что выводит на консоль следующий код? string s("C++"); s.erase(1,2); cout << s << endl; 8. Что такое npos в классе string? 9. Как преобразовать целое значение в строку string? 10. Как преобразовать строку string в целое значение? 61
ЛАБОРАТОРНАЯ РАБОТА № 9. ДИНАМИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ, МАССИВЫ Цель работы Познакомиться с понятием «динамические структуры данных». Узнать особенности динамического массива и способы применения этой структуры в обработке данных. Подготовка к работе Изучить операторы объявления, инициализации и удаления одномерного динамического массива. Уметь использовать операции ввода/вывода и обработки значений динамического массива в программах C++ в среде разработки Microsoft Visual Studio. Требования Реализовать многофайловое приложение С++ обработки значений одномерного динамического массива. Операции выделения и освобождения памяти, добавления и вывода значений массива, а также реализация заданного алгоритма обработки данных должны быть реализованы как функции. Приложение должно выводить на консоль исходные данные и полученные результаты. Электронный отчет должен содержать:  заголовок: группа, ФИО студента, номер и текст варианта задания;  исходный код приложения и скриншоты выполнения программы. Варианты заданий 1. В массиве А, состоящего из N элементов, найти индекс первого положительного числа, оканчивающегося на 0 и не превосходящего сумму значений элементов массива В (размерность М). Если такого элемента нет, то выдать соответствующее сообщение. 2. Найти среднее арифметическое значений элементов массива А, состоящего из N элементов, расположенных между наибольшим и наименьшим зна62
чениями массива, включая эти значения, и занести в массив В среднее арифметическое и количество найденных значений массива А. 3. Найти количество элементов массива А (размерность М), начиная со второго, значение которых больше суммы индексов элементов, стоящих перед ними, и сформировать из них новый массив В. 4. Назовем элемент Аi (i = 1, …, N–2) особым, если слева от него расположены элементы меньше его, а справа — больше. Найти количество таких элементов и сформировать из них массив В. 5. Присвоить элементам массива В (размерность М) значение true, если элементы массива А (размерность N), составляют строго возрастающую арифметическую прогрессию, и false — в противном случае. 6. Сколько значений элементов встречаются в массиве А более одного раза? Сформировать из них новый массив В. 7. Сформировать массив В из таких элементов массива А, которые превышают среднее значение массива А. 8. Записать в массив В квадратный корень положительных элементов массива А, квадрат отрицательных элементов А — в массив С.  a i  / 2 для всех таких значений x i и a i (i = 1, 2, …, N), где подкоренное выражение больше нуля, и сформировать из них массив. 10. Решить уравнение a i  x i  b i для заданных пар значений a i и b i (i = 1, 2, …, N) и сформировать массив из полученных неотрицательных значений. 11. Даны два массива X(N) и Y(M). Сформировать массив Z(N+M) из положительных элементов массивов X и Y. Если положительных элементов меньше N+M, то оставшимся элементам массива Z присвоить значение 1 12. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если все элементы массива А встречаются в массиве В, и false в противном случае 13. Найти индекс последнего положительного значения в массиве А (размерность N), которое делится без остатка на 10, и переписать в массив В все элементы А до найденного значения. Если такого элемента нет, то выдать соответствующее сообщение. 14. Найти последовательность положительных значений элементов массива (элементы следуют друг за другом), максимальной длины, и записать их в массив В. Если такой последовательности нет, выдать соответствующее сообщение. 9. Вычислить значения функции z i  63  xi
15. Записать в начало массива В элементы массива А (размерность N), имеющие нечетные значения, а в конец массива В — четные значения А. 16. Назовем элемент Аi (i = 2, …, N–2) особым, если слева от него расположены элементы меньше его индекса, а справа — больше. Найти количество таких элементов и сформировать из них массив В. 17. Присвоить элементом массива А (размерность N) значение первого элемента массива В (размерность М), если элементы массива В составляют строго убывающую арифметическую прогрессию с заданным шагом, и значение последнего элемента В в противном случае 18. Поменять местами минимальный и максимальный элементы массива, если индекс минимального элемента больше индекса максимального. В противном случае выдать соответствующее сообщение. 19. Сформировать массив В из таких элементов массива А, сумма которых не превышают заданное значение С. Если таких элементов в массиве А нет, то выдать соответствующее сообщение. 20. Даны два массива X(N) и Y(M). «Обменять» максимальный элемент массива X и минимальный элемент массива Y и наоборот. 21. Даны два массива X(N) и Y(M). Вставить на первое место массива X максимальный элемент массива Y, а на его место поставить последний (вытесненный в результате вставки) элемент массива X. 22. Даны два массива X(N) и Y(M). Сформировать массив Z(N+M) из отрицательных элементов массивов X и положительных массива Y. Если таких элементов меньше N+M, то оставшимся элементам массива Z присвоить значение 0. 23. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если хотя бы один элементы массива А встречается в массиве В, и false в противном случае. 24. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если 30 % элементов массива А встречается в массиве В, и false в противном случае. 25. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если сумма элементов массива А превосходит хотя бы один элемент массива В, и false в противном случае. 26. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если произведение четных по номеру элементов массива В не превосходит сумму нечетных по номеру элементов массива А, и false в противном случае. 64
27. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если хотя бы один элемент массива А не превосходит произведение элементов массива В, больших заданного Х, и false в противном случае 28. Сформировать массив В из таких элементов массива А, среднее арифметическое которых не превышают заданного значения произведение С×D. Если таких элементов в массиве А нет, то выдать соответствующее сообщение. 29. Даны два массива X(N) и Y(M). Сформировать массив Z(N+M) из положительных элементов массивов X и отрицательных массива Y. Если таких элементов меньше N+M, то оставшимся элементам массива Z присвоить значение — 1. 30. Даны массивы А, В, состоящие из N элементов каждый. Присвоить переменной F значение true, если все элементы массива А превосходит сумму элементов массива В, больших заданного Х, и false — в противном случае. Методические указания Рассмотрим реализацию приложения формирования динамического массива В из положительных элементов динамического массива А. Пример 1. // Сформировать массив В из положительных элементов // массива А struct Data { int* mas{}; //объявление массива int cur{}; //текущий индекс элемента массива int N{}; //размер массива }; void alocMas(Data&, int); //выделить память для массива void addMas(Data&, int); //добавить значение в массив void formA(Data&); //сформировать массив void printMas(const Data&);//вывести массив void freeMas(Data&); //освободить массив void formB(const Data&, Data&); //сформировать массив В //из массива А 65
#include <iostream> int main() { const int sizeMas = 5; Data dinMas, formMas; alocMas(dinMas, sizeMas); formA(dinMas); /* можно и так: for (int value{}, i{}; i < sizeMas; ++i) { std::cin >> value; addMas(dinMas, value); } */ std::cout << "Array A:" << std::endl; printMas(dinMas); formB(dinMas, formMas); std::cout << "Array B:" << std::endl; printMas(formMas); freeMas(dinMas); freeMas(formMas); } void alocMas(Data& d, int n) { d.mas = new int[n] {}; d.N = n; } void addMas(Data& d, int x) { if (d.cur < d.N) d.mas[d.cur++] = x; } void printMas(const Data& d) { if (d.cur > 0) { for (int i{}; i < d.cur; ++i) std::cout << d.mas[i] << "\t"; std::cout << std::endl; } 66
else std::cout << "Array is empty" << std::endl; } void freeMas(Data& d) { delete[] d.mas; d.mas = nullptr; d.mas = 0; d.cur = 0; } void formA(Data& d) { for (int i{}; i < d.N; ++i) std::cin >> d.mas[i]; d.cur = d.N; } void formB(const Data& a, Data& b) { //определяем количество положительных элементов в А int count{}; for (int i{}; i < a.cur; ++i) if(a.mas[i] > 0) count++; if (count > 0) { //выделяем память для массива В alocMas(b, count); //записываем положительны элементы А в В for (int i{}; i < a.cur; ++i) if (a.mas[i] > 0) { addMas(b, a.mas[i]); } } else { b.mas = nullptr; b.cur = 0; b.N = 0; } } 67
Пример 2. Многофайловая программа. // Сформировать массив В из положительных элементов // массива А Структура приложения: Файл dinMas.h: #pragma once struct Data { int* mas{}; int cur{}; int N{}; }; void void void void void void //объявление массива //текущий индекс элемента массива //размер массива alocMas(Data&, int); //выделить память для массива addMas(Data&, int); //добавить значение в массив formA(Data&); //сформировать массив printMas(const Data&);//вывести массив freeMas(Data&); //освободить массив formB(const Data&, Data&); //сформировать массив В // из массива А 68
Файл dinMas.cpp: #include <iostream> #include "dinMas.h" void alocMas(Data& d, int n) { d.mas = new int[n] {}; d.N = n; } void addMas(Data& d, int x) { if (d.cur < d.N) d.mas[d.cur++] = x; } void printMas(const Data& d) { if (d.cur > 0) { for (int i{}; i < d.cur; ++i) std::cout << d.mas[i] << "\t"; std::cout << std::endl; } else std::cout << "Array is empty" << std::endl; } void freeMas(Data& d) { delete[] d.mas; d.mas = nullptr; d.N = 0; d.cur = 0; } void formA(Data& d) { for (int i{}; i < d.N; ++i) std::cin >> d.mas[i]; 69
d.cur = d.N; } void formB(const Data& a, Data& b) { //определяем количество положительных элементов int count{}; for (int i{}; i < a.cur; ++i) if(a.mas[i] > 0) count++; if (count > 0) { //выделяем память для массива В alocMas(b, count); //записываем положительны элементы А в В for (int i{}; i < a.cur; ++i) if (a.mas[i] > 0) { addMas(b, a.mas[i]); } } else { b.mas = nullptr; b.cur = 0; b.N = 0; } } Файл ConsoleITDinMasApp1.cpp: #include <iostream> #include "dinMas.h" int main() { const int sizeMas = 5; Data dinMas, formMas; alocMas(dinMas, sizeMas); formA(dinMas); 70
/* можно и так: for (int value{},i{}; i < sizeMas; ++i) { std::cin >> value; addMas(dinMas, value); } */ std::cout << "Array A:" << std::endl; printMas(dinMas); formB(dinMas, formMas); std::cout << "Array B:" << std::endl; printMas(formMas); freeMas(dinMas); freeMas(formMas); } Литература 1. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. — http://cph.phys.spbu.ru/documents/ First/books/7.pdf (дата обращения: 06.10.2025). 2. Руководство по языку программирования C++ // METANIT.COM — Сайт о программировании : [сайт]. — URL: https://metanit.com/cpp/tutorial/?ysclid= lkavuhfusn202815661 (дата обращения: 02.10.2025). 3. Введение в программирование на языке С++ : лабораторный практикум / Л.В. Гурьянов, Л.С. Гурьянова, Е.А. Дзюба, Д.В. Такташкин. — Пенза : Изд-во ПГУ, 2010. — 170 с. — http://elib.pnzgu.ru/library/10345800 (дата обращения: 06.10.2025). Контрольные вопросы 1. Что такое тип struct? 2. Как называются данные (переменные, массивы и другие), входящие в состав структуры? 3. Чем заканчивается определение структуры? 71
4. Какие основные типы распределения памяти поддерживает C++? 5. В чем особенность динамического распределения памяти? 6. Где располагаются статические и динамические данные? 7. Для чего предназначены операторы new и delete? 8. В чем особенность синтаксиса определения и освобождения динамических массивов? 9. Что такое «висячие указатели» и «утечка памяти»? 10. Для чего используются заголовочные файлы и файлы реализации? 72
ЛАБОРАТОРНАЯ РАБОТА № 10. ДИНАМИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ (СПИСКИ, ОЧЕРЕДИ, СТЕКИ) Цель работы Познакомиться с динамическими структурами данных, особенностями их представления и использования в С++. Подготовка к работе Изучить синтаксис объявления структур, операторы new и delete, примеры использования динамических массивов и списков в программах на С++. Требования Реализовать многофайловое приложение С++ с использованием динамических структур данных и функций их обработки. Реализовать перегрузку вывода (оператора <<) для разработанной структуры. Приложение должно выводить на консоль исходные данные и полученные результаты. Электронный отчет должен содержать:  заголовок: группа, ФИО студента, номер и текст варианта задания;  исходный код приложения и скриншоты выполнения программы. Варианты заданий Внимание! Для всех заданий реализовать функцию освобождения памяти. 1. Для хранения целых чисел используется следующая структура данных: 73
Функции:  добавить значение (в зависимости от первой цифры число попадает в конец одного из списков);  вывести текущее состояние структуры данных (вывести все значения в виде двумерного массива);  найти значение в структуре данных (функция возвращает 1, если значение найдено, и 0 — в противном случае). 2. Очередь длиной N с приоритетами задана, как однонаправленный линейный список. Элементы, имеющие больший приоритет расположены ближе к началу очереди. При добавлении элемента в очередь он располагается в конце элементов своего приоритета. Функции:  поместить элемент в очередь согласно своему приоритету;  выбрать элемент из очереди (из начала списка);  вывести содержимое очереди;  текущая длина очереди;  очередь пуста;  очередь заполнена. 3. Очередь как однонаправленный линейный список целых чисел. Задана максимальная длина очереди — N. Функции:  поместить значение в очередь (функция добавляет значение в конец списка);  выбрать значение из очереди (функция возвращает значение из начала списка и удаляет его из списка);  длина очереди (функция возвращает количество элементов в списке);  вывести очередь (не изменяя содержимого списка, функция выводит все значения, которые хранятся в списке);  количество потерянных «клиентов». 74
4. Множество целых чисел представляется как однонаправленный линейный список. Функции:  найти значение в множестве (функция возвращает 1, если значение найдено, и 0 — в противном случае);  добавить значение в множество (если значение уже есть в множестве, то оно в множество не добавляется. Для проверки используйте функцию «найти значение во множестве»);  вывести текущее состояние множества (вывести все значения);  определить мощность множества (подсчитать количество чисел во множестве);  сформировать новое множество объединением двух заданных множеств. 5. Динамический массив, заданной длины N, хранит нескольких списков (в примере: <d, e> и <a, b, c>), используя следующую структуру данных. Функции:  поместить элемент в список;  выбрать элемент из списка (при этом элемент удаляется из списка);  вывести содержимое списка;  текущая длина списка. 75
6. Многочлен a n x n  a n1 x n1  ...  a1 x1  a0 представляется как однонаправленный линейный список, элемент которого имеет следующую структуру: коэффициент степень Указатель на следующий элемент Например, многочлену 2x3 + 5x – 3 будет соответствовать список: 2 3 5 1 -3 0 NULL Функции:  добавить элемент многочлена в список;  сформировать многочлен (используется функция «добавить элемент многочлена в список»);  вывести многочлен (вывести общий вид многочлена; для возведения в степень использовать символ «^», например, х^3);  вычислить многочлен (функция возвращает значение многочлена при заданном значении х);  вычислить сумму двух многочленов. Функция получает на вход два многочлена и возвращает третий многочлен, элементы которого содержат коэффициенты и степени исходных многочленов, при этом коэффициенты при равных степенях складываются. 7. «Длинное» целое число представляется как однонаправленный линейный список, где каждая цифра — элемент списка. Функции:  сформировать «длинное» целое число (функция формирует список из цифр числа);  вывести «длинное» целое число;  инвертировать исходное число (инвертировать список);  сложить два «длинных» целых числа. Функция получает на вход два списка и возвращает третий список, каждый элемент которого содержит цифру, равную сумме, соответствующих цифр исходных списков. Фактически, результат функции — сумма двух чисел. Использовать функцию инвертирования. 8. Динамический массив из N комплексных чисел. Функции:  сформировать массив; 76
вывести массив (функция выводит все комплексные числа);  определить комплексное число как сумму всех комплексных чисел массива;  найти комплексное число с максимальным модулем (модуль: re 2  im 2 , где re — действительная часть, im — мнимая часть комплексного числа);  присвоить переменной F значение true, если среди комплексных чисел, полученных как произведение исходного (из массива) и сопряженного ему комплексных чисел, есть хотя бы два равных комплексных числа, и false в противном случае.  9. Циклический однонаправленный список целых чисел имеет следующую структуру: Последний элемент указывает на начало списка ... Начало списка Функции:  добавить в список (функция добавляет элемент в конец списка);  вывести список (функция выводит все значения, которые хранятся в списке);  выбрать элемент из списка по номеру (функция удаляет элемент, отсчитывая его в соответствии с заданным номером от начала списка. Номер может быть больше количества элементов списка);  определить «последний» элемент списка после удаления элементов списка, выбранных по заданному номеру (использовать функцию «Выбрать элемент по номеру»). 10. Стек как динамический массив из N элементов. Функции:  поместить значение в стек;  выбрать значение из стека (функция возвращает значение из вершины стека и удаляет его из стека);  стек заполнен (функция возвращает значение «истина», если стек заполнен);  стек пуст (функция возвращает значение «истина», если в стеке нет значений); 77
вывести стек (не изменяя содержимое стека функция, выводит все значения, которые хранятся в стеке);  использовать стек для проверки исходной строки на соответствие открывающих и закрывающих круглых скобок (использовать функции «Поместить значение в стек» и «Выбрать значение из стека»).  11. Для формирования учебных планов используется следующая списковая структура, отражающая выбор студентами дополнительной дисциплины. Функции:  сформировать список студентов;  сформировать список дисциплин;  удалить студента;  удалить дисциплину;  вывести списки студентов с указанием выбранной ими дисциплин;  определить какая дисциплина выбрана наибольшим количеством студентов. 12. Стек задан как однонаправленный линейный список. Функции:  поместить значение в стек (функция добавляет значение в начало списка);  выбрать значение из стека (функция возвращает значение из начала списка и удаляет его из списка);  стек пуст (функция возвращает значение «истина», если в списке нет значений); 78
вывести стек (не изменяя содержимого списка, функция выводит все значения, которые хранятся в списке);  использовать стек для проверки исходной строки на соответствие открывающих и закрывающих фигурных скобок (использовать функции «Поместить значение в стек» и «Выбрать значение из стека»).  13. Ориентированный граф (орграф) задан в виде списковой структуры Функции:  добавить вершину;  добавить дугу;  удалить вершину;  удалить дугу;  построить матрицу смежности орграфа. 14. Динамический массив хранит нескольких стеков заданной длины N, используя следующую структуру данных. 79
Функции:  поместить элемент в стек;  выбрать элемент из стека;  стек пуст;  стек заполнен;  вывести содержимое стека. 15. Двоичное число В, где каждая цифра bi равна 1 или 0, представлено в виде однонаправленного списка b1, b2, ..., bn. Функции:  добавить цифру в число;  сформировать число В (функция использует функцию «добавить цифру в список);  вывести число В;  вычислить десятичное значение числа В;  увеличить число В на единицу. 16. Отображение задано в виде списка пар (d1,r1), (d2,r2), ..., (dn,rn), где d1,d2, ..., dn — целые значения, r1, r2, ..., rn — символы, ассоциированные с этими значениями. Функции:  добавить элемент (di, ri) в список;  вывести все значения из списка;  найти по заданному значению di, соответствующий ему символ ri;  формирования строки символов по заданному массиву целых чисел (использовать функцию «Найти по заданному значению»). 17. Двунаправленный линейный список целых чисел. Каждый элемент списка имеет указатель на следующий элемент списка и указатель на предыдущий элемент. Функции:  поместить значение в список (функция добавляет значение в начало списка);  удалить значение из списка (функция удаляет значение из начала списка);  вставить значение в список после элемента с порядковым номером M (функция добавляет новый элемент в список после элемента с указанным номе80
ром. Если в списке меньше элементов, чем M, функция выводит предупредительное сообщение и не изменяет структуру списка);  вывести список в прямом порядке (не изменяя содержимого списка, функция выводит все значения, которые хранятся в списке, от начала до конца списка);  вывести список в обратном порядке (не изменяя содержимого списка, функция выводит все значения, которые хранятся в списке, от конца списка к началу). 18. Очередь с двусторонним доступом задана, как однонаправленный линейный список целых чисел. Задана максимальная длина очереди — N.  Реализовать дисциплину обслуживания FIFO — первым пришел, первым ушел. Функции:  поместить элемент в очередь;  выбрать элемент из очереди;  вывести содержимое очереди;  текущая длина очереди;  очередь пуста;  очередь заполнена. 19. Динамический массив хранит нескольких очередей заданной длины, используя следующую структуру данных. Динамический масссив Начало очереди 1 Очередь 1 2 3 Очередь 2 Конец очереди 1 2 Очередь 3 3 81
Функции:  поместить элемент в очередь (в конец очереди);  выбрать элемент из очереди (из начала очереди);  вывести содержимое очереди;  текущая длина очереди;  очередь пуста;  очередь заполнена. 20. Однонаправленный линейный список задан как одномерный динамический массив ограниченной длины.  Элементы списка располагаются в соседних ячейках массива. Добавление в список осуществляется после последнего существующего элемента (last). Однако, вставка или удаление элемента из середины списка потребует перемещения всех последующих элементов списка на одну позицию к концу массива (вставка) или к началу (удаление). Функции:  добавить элемент в список;  вставить элемент в список;  удалить элемент из списка;  выбрать элемент из списка;  вывести содержимое списка;  текущая длина списка. 21. Очередь с двусторонним доступом задана, как однонаправленный линейный список целых чисел. Задана максимальная длина очереди — N.  Реализовать дисциплину обслуживания LIFO — последним пришел, первым ушел. 82
Функции:  поместить элемент в очередь;  выбрать элемент из очереди;  вывести содержимое очереди;  текущая длина очереди;  очередь пуста;  очередь заполнена. 22. Очередь представлена как динамический кольцевой массив ограниченной длины. Для вставки элемента в очередь необходимо переместить указатель на конец очереди на одну позицию по часовой стрелке и записать добавляемый элемент в эту позицию. При удалении элемента из очереди достаточно переместить указатель на начало очереди на одну позицию по часовой стрелке. Функции:  поместить элемент в очередь (в конец);  выбрать элемент из очереди (из начала);  вывести содержимое очереди;  очередь пуста;  очередь заполнена. 23. Однонаправленный линейный список задан следующей структурой (в примере список содержит символы a, b, c). Добавление элемента в список осуществляется в позицию, которую указывает переменная «Начало свободного места». Удаление элемента списка добавляет элемент в свободные ячейки массива. 83
Функции:  поместить элемент в список;  выбрать элемент из списка;  вывести содержимое списка;  текущая длина списка. 24. Динамический массив хранит два стека: первый располагается с начала массива и растет к его концу, второй – располагается с конца массива и растет к его началу. Функции:  поместить элемент в стек;  выбрать элемент из стека;  стек пуст;  стек заполнен;  вывести содержимое стека. 25. Двунаправленный линейный список целых чисел (каждый элемент списка имеет указатель на следующий элемент списка и указатель на предыдущий элемент) используется для хранения двух стеков: первый располагается с начала списка и растет к его концу, второй – располагается с конца списка и растет к его началу. Функции:  поместить элемент в стек;  выбрать элемент из стека;  стек пуст;  стек заполнен;  вывести содержимое стека. 84
26. Двумерный динамический массив представлен как следующая структура данных. Функции:  добавить значение в массив. Добавление идет в тот массив, индекс которого в массиве указателей соответствует значению хэш-функции h(x): h(x) = x по модулю N, где x — значение, добавляемое в массив;  найти значение в массиве (функция возвращает значение «истина», если значение найдено, и значение «ложь» — в противном случае);  найти максимальный элемент массива и вывести его значение и расположение в массиве;  вывести все значения, которые хранятся в массиве, в виде матрицы. 27. Множество целых чисел представлено как динамический массив, размерности N, где i-ый элемент массива равен 1, если число i присутствует в множестве, и 0 — в противном случае. Структура данных содержит мощность множества. Функции:  поместить число в множество;  выбрать число из множества;  найти объединение множеств. Функция получает на вход два множества и возвращает третье множество, равное объединению;  найти пересечение множеств;  найти разность множеств;  вывести содержимое множества и мощность множества. 85
28. Дерево задано с помощью динамического массива А, который определен следующим образом: a[i] — номер родительской вершины для i-ой вершины дерева (для первой вершины всегда равен 0 — корень дерева). Функции:  добавить вершину в дерево (функция получает номер вершины и номер вершины родителя);  найти всех наследников вершины с заданным номером (возможна рекурсия);  определить высоту дерева;  отобразить дерево (вывести номера вершин дерева по уровням с указанием родительской вершины). 29. Дерево определено с помощью следующей списковой структуры: 86
Функции:  добавить вершину в дерево (функция получает номер вершины и номер вершины родителя);  найти всех наследников вершины с заданным номером;  определить высоту дерева;  отобразить дерево (вывести номера вершин дерева по уровням с указанием родительской вершины). 30. Словарь описаний (код -> описание) реализуется как списковая структура. Функции:  поместить термин в словарь;  поместить пояснение в словарь;  выбрать пояснение по термину в словаре;  удалить термин из словаря;  вывести содержимое словаря. Методические указания Рассмотрим примеры использования динамических структур данных и функций их обработки. Пример 1. #include <iostream> int main() { int* numbers { new int[4]{} }; // массив: 0, 0, 0, 0 int* numbers1{ new int[4]{ 1, 2, 3, 4 } };//массив: //1, 2, 3, 4 //int* numbers1{ new int[] { 1, 2, 3, 4 } }; int* numbers2{ new int[4]{ 1, 2 } }; // массив: // 1, 2, 0, 0 // аналогичные определения массивов // int *numbers = new int[4]{};// 0, 0, 0, 0 // int *numbers = new int[4]();// 0, 0, 0, 0 // int *numbers1 = new int[4]{ 1, 2, 3, 4 }; // int *numbers2 = new int[4]{ 1, 2 }; 87
// получение std::cout << std::cout << // получение std::cout << std::cout << элементов через синтаксис массивов numbers1[0] << std::endl; // 1 numbers1[1] << std::endl; // 2 элементов через операцию разыменования *numbers1 << std::endl; // 1 *(numbers1 + 1) << std::endl; // 2 //способы перебора массива: unsigned n{ 5 }; // размер массива - переменная! int* p{ new int[n] { 1, 2, 3, 4, 5 } }; // используем индексы for (unsigned i{}; i < n; i++) { std::cout << p[i] << "\t"; } std::cout << std::endl; // добавляем к адресу в указателе смещение for (unsigned i{}; i < n; i++) { std::cout << *(p + i) << "\t"; } std::cout << std::endl; // проходим по массиву с помощью вспомогательного //указателя for (int* q{ p }; q != p + n; q++) { std::cout << *q << "\t"; } std::cout << std::endl; // освобождение памяти и обнуление указателей delete[] p; delete[] numbers; delete[] numbers1; delete[] numbers2; p = nullptr; numbers = nullptr; numbers1 = nullptr; numbers2 = nullptr; return 0; } 88
Пример 2. #include <iostream> #include <ctime> #include <iomanip> using namespace std; int main() { const int N = 2, M = 5; srand(time(0)); // генерация случайных чисел //динамическое создание двумерного массива float** ptrarray = new float* [N]; //две строки for (int count = 0; count < N; count++) ptrarray[count] = new float[M]; //и пять столбцов //заполнение массива случайными числами от 1 до 10 for (int count_row = 0; count_row < N; count_row++) for (int count_column = 0; count_column < M; count_column++) ptrarray[count_row][count_column] = (rand() % 10 + 1) / float((rand() % 10 + 1)); // вывод массива for (int count_row = 0; count_row < N; count_row++) { for (int count_column = 0; count_column < M; count_column++) cout << setw(4) << setprecision(2) << ptrarray[count_row][count_column] << " "; cout << endl; } // освобождение памяти for (int count = 0; count < N; count++) delete[]ptrarray[count]; delete[]ptrarray ptrarray = nullptr; return 0; } 89
Пример 3. #include <iostream> using namespace std; struct Elem { int x; Elem* next; friend ostream& operator<<(ostream& out, const Elem* start) { Elem* tmp; if (!start) return out << "список пуст" << endl; tmp = const_cast<Elem*>(start); while (tmp) { out << tmp->x << "\t"; tmp = tmp->next; } return out << endl; } }; void add_end(Elem*&, const int); int main(){ setlocale(LC_ALL, "Russian"); Elem* start{}; add_end(start, 1); add_end(start, 2); add_end(start, 3); cout << start; } void add_end(Elem*& start, const int a) { Elem *tmp{ new Elem }, *cur{}; 90
tmp->x = a; tmp->next = nullptr; if (!start) start = tmp; else { cur = start; while (cur->next) cur = cur->next; cur->next = tmp; } } Пример 4. Во многих заданиях определение структуры данных требует определения более чем одной структуры. Пусть в задании необходимо создать очередь ограниченной длины как однонаправленный список целых чисел. В этом случае необходимо определить вспомогательную структуру — список целых чисел, и основную – очередь, реализованную как список. #include <iostream> using namespace std; //Однонаправленный список целых чисел struct Elem { int x; Elem* next; friend ostream& operator<<(ostream& out, const Elem* start) { Elem* tmp; if (!start) return out << "список пуст" << endl; tmp = const_cast<Elem*>(start); while (tmp) { out << tmp->x << "\t"; tmp = tmp->next; 91
} return out << endl; } }; //очередь как однонаправленный список целых чисел struct QueueAsList { Elem* start{}; //указатель на начало очереди int count{}; //количество элементов в очереди int N{}; //Максимальная длина очереди }; //прототип функции добавления в очередь void add_end(QueueAsList&, const int); }; int main() { QueueAsList q; add_end(q, 10); cout << q.start << endl; } //Пример кода для добавления в пустую очередь void add_end(QueueAsList& s, const int x) { s.start = new Elem{x, nullptr}; s.count++; } Литература 1. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. — http://cph.phys.spbu.ru/documents/ First/books/7.pdf (дата обращения: 06.10.2025). 2. Руководство по языку программирования C++ // METANIT.COM — Сайт о программировании : [сайт]. — URL: https://metanit.com/cpp/tutorial/?ysclid= lkavuhfusn202815661 (дата обращения: 02.10.2025). 92
3. Введение в программирование на языке С++ : лабораторный практикум / Л.В. Гурьянов, Л.С. Гурьянова, Е.А. Дзюба, Д.В. Такташкин. — Пенза : Изд-во ПГУ, 2010. — 170 с. — http://elib.pnzgu.ru/library/10345800 (дата обращения: 06.10.2025). Контрольные вопросы 1. Что такое тип struct и как называются данные (переменные, массивы и другие), входящие в состав этого типа? 2. В чем особенность динамического распределения памяти, в чем отличие от статического распределения? 3. Для чего предназначены операторы new и delete? 4. Что такое «висячие указатели» и «утечка памяти»? 5. Приведите пример кода динамического выделения памяти для массива из 10 целых чисел. 6. Какие особенности динамической структуры данных «список», реализуемой с помощью указателей, Вы знаете? 7. Приведите пример кода вставки элемента в односвязный список целых чисел. 8. Приведите пример кода удаления элемента односвязного списка целых чисел. 9. Что произойдет, если в Примере 3 объявить переменную start следующим образом: Elem* start? 10. Из каких файлов состоит модуль С++? 93
СПИСОК ЛИТЕРАТУРЫ 1. Павловская Т.А. C/C++. Программирование на языке высокого уровня. — Санкт-Петербург : Питер, 2003. — 461 с. 2. Павловская Т.А. C/С++. Процедурное и объектно-ориентированное программирование. — Санкт-Петербург : Питер, 2018. — 496 с. 3. Конова Е.А., Поллак Г.А. Алгоритмы и программы. Язык С++ : учебное пособие. — 4-е изд., стер. — Санкт-Петербург : Лань, 2019. — 384 с. 4. Шилдт Г. C++. Базовый курс. — 3-е изд. — Москва : Вильямс, 2019. — 624 с. 5. Липпман С.Б., Лажойе Ж., Му Б.Э. Язык программирования C++. Базовый курс / пер. с англ. — 5-е изд. — Москва : Вильямс, 2014. — 1118 с. 6. Андрианова А.А., Исмагилов Л.Н., Мухтарова Т.М. Алгоритмизация и программирование. Практикум : учебное пособие. — Санкт-Петербург : Лань, 2019. — 240 с. 7. Макконнелл С. Совершенный код. Мастер класс. — Москва : Русская редакция, 2013. — 896 с. 8. Пратт Т., Зелковиц М. Языки программирования: разработка и реализация. — 4-е изд. — Санкт-Петербург : Питер, 2002. — 688 с. 9. Руководство по языку программирования C++ // METANIT.COM — Сайт о программировании : [сайт]. — URL: https://metanit.com/cpp/tutorial/?ysclid= lkavuhfusn202815661 (дата обращения: 02.10.2025). 94