Текст
                    •	ЦВЕТНОЕ ИЗДАНИЕ
•	ПОШАГОВЫЕ ИНСТРУКЦИИ
•	СОЗДАЙТЕ ПРОГРАММУ С НУЛЯ
•	ОПЫТ В РАЗРАБОТКЕ НЕ НУЖЕН
C++
ДЛЯ НАЧИНАЮЩИХ
4
Виктор Шитов	4ки»|*
Виктор Шитов
\ ПРОГРАММИРОВАНИЕ
----	ДЛЯ НАЧИНАЮЩИХ
•	ЦВЕТНОЕ ИЗДАНИЕ
•	ПОШАГОВЫЕ ИНСТРУКЦИИ
•	СОЗДАЙТЕ ПРОГРАММУ С НУЛЯ
•	ОПЫТ В РАЗРАБОТКЕ НЕНУЖЕН
C++
ДЛЯ НАЧИНАЮЩИХ
Ь БОМБОРА
ИЗДАТЕЛЬСТВО
Москва
УДК 004.42
ББК 32.973.2-018
П164
Шитов, Виктор Николаевич.
Ш64	C++ для начинающих / Виктор Шитов. — Москва : Эксмо, 2025. —
320 с. —(Программирование для начинающих).
ISBN 978-5-04-222593-2
Эта книга создана специально для тех, кто только начинает знакомство с миром програм мирозания. Она станет вашим пошаговым проводником в изучении С+ -I-одного из самых
востребованных и универсальных языков разработки. Вы научитесь писать собственные программы с нуля, работать с массивами, поймете, как применять C++ для решения практических задач. Каждая глава сопровождается наглядными цветными примерами и полезными советами, чтобы обучение было максимально эффективным и увлекательным. Даже без опыта в программировании вы сможете уверенно делать первые шаги и получить удовольствие от написанного своими руками кода.
УДК 004.42
БЬК 32.973.2-018
ISBN 978-5-04-222593-2
© Шитов В.Н., текст, иллюстрации, 2025
© Оформление ООО «Издательство «Эксмо», 2025
Содержание
Введение в программирование	9
Основные понятия программирования	10
Приложение Dev-C++	13
Инсталлирование программы Dev-C++	14
Создание первой программы	17
Русификация вывода текста на консоль	22
Этапы создания программы, языки программирования, структура системы программирования
25
Общая характеристика языка C++	27
Основные конструкции языка
Алфавит	28
Идентификаторы	29
Ключевые слова	30
Специальные символы	34
Структура программы на языке C++	36
Простые тины данных	49
Переменные и константы	52
Переменные	52
Константы	57
Основные операции	61
Приоритеты операторов C++	63
Арифметические и логические выражения	64
Арифметические выражения	64
Логические выражения	67
Оператор равенства	71
Операторы отношения	73
Операторы ввода-вывода библиотеки iostream, h	75
Использование манипуляторов вывода	77
Форматирование с помощью манипуляторов	i 77
Форматирование с помощью функций-	
членов и флагов	81
Стандартные математические и строковые	
функции	84
Библиотека математических функций math.h	84
Преобразование строк в числа	92
Форматирование программного текста	97
Комментарии	99
Заключение	101
К	
Программы разветвляющейся структуры	103
Понятие алгоритма	104
Линейные и разветвляющиеся алгоритмы	105
Условный оператор if	106
Правила вычисления логических выражений	108
Оператор выбора switch	111
Заключение	113
		
Программы циклической структуры	115
Операторы цикла языка C++	116
Операторы цикла с предусловием (while)	117
Операторы цикла с постусловием (do while)	119
Операторы цикла с заданным, числом	
повторений (for)	121
Операторы передачи управления (break,	
return, continue)	123
Заключение	124
	к	
	Обработка одномерных массивов	125
	F	
	Объявление, инициализация, обработка	
	одномерных массивов	126
	Алгоритмы нахождения минимального	
	и максимального значения	130
	Сумма элементов массива	132
	Произведение элементов массива	134
	Удаление элементов массива	134
	Удаление положительных элементов	
	массива	135
	Алгоритмы сортировки	137
	Метод пузырька	137
	Метод прямого выбооа	139
	Заключение	141
Обработка двумерных массивов	143
Объявление и инициализация двумернь.х	
массивов различных типов	144
Ввод-вывод элементов двумерною массива	146
Заключение	149
Создание пользовательских функций	151
Объявление и определение функций	152
Фактические и формальные параметры	157
Понятие прототипа функции	160
Вызов функции	163
Передача значений с использованием	
оператора return	166
Область действия и время жизни переменной	169
Заключение	174
	
Объявление указателей	178
Основные операции над указателями	181
Операции адресации и разыменования	181
Нулевой указатель (NULL)	184
Операции сравнения и логические операции187	
Математические действия с указателями Присвоение указателю одного типа	187
значения указателя другого типа	192
Особенности операций с указателями	196
Указатели на константы	199
Константный указатель	201
Константный указатель на константу	201
Средства использования динамической памяти Операторы new и delete	202
Связь между указателями и массивами	204
Понятие ссылки	206
Виды ссылок	207
Передача ссылки в качестве параметра функции	207
Создание независимой ссылки	210
Использование ссылок для передачи значений из функции	211
Заключение	213
Типы данных, определяемые пользователем	217
Перечисляемый тип	218
Переименование типов с помощью tyoedef Структурный шаблон и синтаксис	222
его объявления	225
Понятие «поле шаблона» Объявление, инициализация и обоаботка	227
структурных переменных	229
Указатели на структуру	231
232
Вложенные структуры
Переменные типа объединения и особенности их использования	234
Заключение
239
		LC	\	Основы объектно ориентированного /	программирования	241
			Основные принципы объектно ориентированного программирования	242 Инкапсуляция	243 Полиморфизм	245 Наследование	251 Определение класса и структуры в C++	254 Поля и методы класса	258 Спецификаторы управления доступом	261 Объекты	268 Конструкторы	270 Деструкторы	273 Правила обьявления конструкторов и деструкторов в производных классах	274 Дружественные функции	278 Заключение	282
г L	1		Приложения	285 
			Приложение 1	286 Приложение 2	287 Приложение 3	292 Приложение 4	295 ЗАКЛЮЧЕНИЕ	302 ЛИТЕРАТУРА	303
В книге изложены основы программирования на популярном языке высокого уровня C++. Отражены следующие темы: этапы создания программы; языки программирования, структура системы программирования; программы разветвляющейся и циклической структуры, обработка одномерных и двумерных массивов; создание пользовательских функций; типы данных, определяемые пользователем; основы объектно соиентированногс программирования.
Введение
в программирование
10
Основные понятия программирования
13
Приложение Dev-C++
14
Инсталлирование программы Dev-C++
17
Создание первой программы
22
Русификация вывода текста на консоль
Основные понятия программирования
Программа — это данные, используемые для управления определенными компонентами системы обработки информации для выполнения определенных алгоритмов. Программное обеспечение включает в себя ряд программ вычислительной системы и программную документацию, необходимую для работы этих программ. Программирование — это научно-практическая деятельность, направленная на создание программ.
При протраммировании используются специальные понятия:
команды в компьютерной программе — это инструкции по выполнению определенных действий для решения проблемы. Обычно команда соответствует глаголу повелительного наклонения, например: «Умножить», «Ввести (с консоли)», «Вывести (на консоль)» и т. д. Команды описывают основные операции на языке компьюзера, которые он должен выполнять;
переменная — это именованное местоположение в памяти компьютера, которое может хранить определенные значения данных. Переменные используются для хранения и обработки информации в программе;
тип данных — определяет, какие значения может принимать переменная и какие операции могут выполняться с использованием этих значений.
К основным типам данных относятся целые числа (int, short int, long int), числа с плавающей точкой (float, double, long double), строки (char, string) и логические значения (bool);
операторы — это символы или ключевые слова, используемые в программе. Операторы могут быть арифметическими (+, —, *, /), операторами сравнения (==,!=, <, >), логическими (&&, ||,1);
условные операторы — предназначены для принятия решения при определенных условиях. Например, оператор if может использоваться для выполнения определенного блока кода, если условие выполняется, т. е. истинно (true, или 1), и пропускать его, если условие не выполняется, т. е. ложно (false, или 0);
циклы — предназначены для многократного использования при выполнении блока кода. Например, цикл for выполняет заданный блок кода заданное количество раз, а цикл while (или do while) выполняет блок кода до тех пор, пока условие истинно. Причем цикл while проверяет истинность условия до его выполнения, а цикл do while — после его выполнения;
функция — это блок кода, который может быть вызван из других частей программы. Они позволяют разделить код на более мелкие и понятные фрагменты, что делает программу более структурированной и легкой в обслуживании;
Программирование — это деятелэность, направленная на создание программ.
массив — это структура данных, которая позволяет хранить несколько значений одного типа в одной переменной. Массивы позволяют эффективно обрабатывать большие объемы данных, а доступ к элементам массива осуществляется по индексу. Массивы бывают одномерными, двумерными и многомерными.
Приложение Dev-C++
Dev-C++ — это бесплатная интегрированная среда разработки с открытым исходным кодом, написанная на Delphi для Windows. Это легкая IDE, установка которой занимает всего несколько минут. Это идеальная среда разработки для начинающих.
Dev-C++ обладает следующими особенностями: небольшой объем занимаемой дисковой памяти, простая в использовании панель инструментов, автозаполнение кода, использование языков С и C++ (по умолчанию предлагается C++), комбинации клавиш для компиляции и инициализации (например, F9 и F10), простейший процесс инсталлирования созданной программы.
Инсталлирование программы Dev-C++
Выбирайте пункт «Запуск от имени администратора».
Скачайте приложение Dev-C++ с сайта разработчика https://www.dev-cpp.com. Скачанный дистрибутив Dev-Cpp 5.11 TDM-GCC 4.9.2 Setup.exe обычно находится в папке «Загрузки»; если его гам нет, то укажите имя дистрибутива или хотя бы фрагмент имени в строке поиска (справа от кнопки Пуск). Запустите выполнение этого дистрибутива или двойным щелчком, или после выделения нажатием кнопки Enter. После этого запускается мастер по инсталлированию приложения Dev-C++.
На нервом шаге мастера инсталляции открывается окно, в котором предлагается язык инсталлирования:, если в параметрах ОС Windows выбран русский язык, то именно этот язык и предлагается. Нажмите кнопку ОК.
На втором шаге мастера предлагается
принять лицензионное соглашение GNU
(открытое лицензионное соглашение —
лицензия на свободное программное обеспечение). Нажмите кнопку Принимаю.
На третьем шаге мастера предлагается выбрать компоненты устанавливаемой программы. Ничего не изменяя, нажмите кнопку Далее >.
На четвертом шаге мастера выбирается папка для установки в нее программы. Ничего не изменяя, нажмите кнопку Установить.
После этого запускается установка программы на компьютер. Дождитесь завершения установки, которая продлится считаные минуты.
После завершения установки открывается финишный шаг работы мастера
инсталлирования. В опции Запустить Dev-C++ 5.11 установлен флажок. Это означает, что после нажатия кнопки Готово будет запущено приложение Dev-C++ первый раз. Нажмите кнопку Готово.
После первого запуска программы Dev-C++ 5.11 интерфейс английский, так как русский язык предлагался только для инсталлирования приложения, и запускается настройка параметров программы В списке Select your language выберите русский язык — Russian (Русский) (рис. 1). Нажмите кнопку > Next.
Dev-C+* first time configuration
1 ^include <iostream>
2
3	A int main(int argc, char** argv)
4	std::cout « "Hello world!\
5	return
б	L }
Select your language:
Polish (Polski) Portuguese (Brazil) Rcmanian (Romenr)		A
Russian (Русский)		
Slovak (Slovenska)		
Slovenian (slovenAinna) Spanish (Latino Атйпса) Espaccl (Castellano) Espaccl (Colombia) Svenska Turkish Ukrainian ГУкоаТнська)
You can later change the language at Tools >> Environment Options >> General.
Next
Рис. 1. Выбор русского языка для интерфейса Dev-C++ 5.11
Споавка открывается только в браузерах FireFox и Internet Explorer.
На следу тощей вкладке — Select your theme («Выберите свою тему») — нет никакого смысла изменять что-либо, даже шрифт. Нажмите кнопку > Next.
В последнем шаге конфигурации говорится, что для ознакомления предлагается справка по данному приложению
в разделе меню Справка. Вызвать справку можно клавишей F1 или выполнив команду Справка Dev-C++ из раздела меню Справка. Справка открывается в браузере, в котором можно перевести ее необходимые материалы. Число браузеров для работы со справкой невелико: FireFox и Internet Explorer. После изменения конфигурации приложения Dev-C++ открывается рабочее окно приложения.
Создание первой программы
Для создания программы нужно предварительно создать папку, в которую будут сохраняться учебные файлы.
Например, на Рабочем столе или в папке «Документы» можно создать папку «Программы».
Программа состоит из нескольких файлов. Во-первых, это текстовый файл с расширением *.срр (от C++; язык С сохраняет программу в файле с расширением *.с). Во-вторых, после компилирования создается исполняемый файл *.ехе, который можно переносить на другие компьютеры (теоретически исполняемые файлы должны работать одинаково на всех компьютерах).
В языках С и C++ существует еще файл h (или .hpp, но реже) — это заголовочный файл, содержащий определения функций, типов данных, используемых в проекте. Файл.Ь объявляется директивой ftinclude в начале текста программы. Символ # сообщает компилятору или транслятору, что сейчас последует директива.
Для создания первой программы выполните команду Файл => Создать => Исходный файл. Отдельные файлы .срр можно создать также следующими удобными способами: нажать кнопку New («Новый», Г) на инструментальной панели Главная; выполнить комбинацию клавиш Ctrl + N (переключаться на английскую раскладку для этого не нужно).
Для примера создадим простейшую программу (рис. 2). В области директив (в верхней части исходного файла) необходимо записать:
ttinclude <iostream>
ftindude <string>
со^е
[*] Безымянныйl.cpp
1
2 3
4
6
7
8
^include <iostream>
^include <string> using namespace stdj int
H
main()
ccut <<"\t return 3j
Посмотрите на цветовое решение программного кода (рис 2) Хотя и ключевые слова, и имена функций (main, cout) форматированы черным цветом, но ключевые
слова выделены полужирным начертанием Обратите внимание на цвет символов (; и «) и скобок: они красного цвета. Числовое значение (0) форматировано фиолетовым цветом.
Puc. 2. Пример программы
iostream.h — это заголовочный файл, содержащий классы, функции и переменные для организации ввода-вывода в языке программирования C++ и входящий в стандартную библиотеку C++.
string.h — это заголовочный файл, предназначенный работать со строками (в заголовочных файлах расширение *.h обычно опускается).
using namespace std — пространство имен, т. е. это область объявления, в которой задаются различные идентификаторы (имена типов, функций, переменных и т. д.).
Пространства имен используются для организации кода в логические группы и для предотвращения конфликтов имен, особенно когда кодовая база содержит несколько библиотек. Все идентификаторы внутри пространства имен могут обращаться друг к другу без свертывания. Желательно пространство имен using namespace std указывать в каждой программе сразу вод директивами.
Обратите внимание на цвет строк: во всех приложениях языка C++ используются следующие цветовые решения:
•	зеленый — директивы препроцессора;
•	черный полужирный — ключевые слова;
•	черный — функции, переменные;
•	фиолетовый — цифры;
•	— комментарий;
•	красный — символы, оператооы, скобки;
•	синий — текст.
Тем не менее есть и исключения. Например, цифры в имени переменной или функции будут черного цвета, а не фиолетового. Точка в числе с дробной частью или минус будут фиолетового цвета, а не красного, так как относятся к числу, а не к символам. Любые символы, буквы, цифры в тексте будут синего цвета, так как относятся к тексту.
Менять цвет программного кода крайне не рекомендуется, так как на другом компьютере будет дзугое цветовое решение, мешаюшее восприятию программы. В окне Параметры редактора можно посмотреть назначение каждого цвета в тексте программ.
Цвет команд, текста и так далее можно изменить командой Сервис ~> Параметры редактора — в открывшемся окне Параметры редактора на вкладке Синтаксис можно выбрать другие цвета для каждого параметра программного кода.
Функция main является главной функцией C++, так как основные события в программе описываются именно здесь. Подробно рассмотрим ход выполнения программы в функции main (рис. 2).
cout « — вывод строки, следующей за угловыми скобками;
\t — относится к специальным символам и заключен в кавычки. Это символ табуляции, т. е. отступ вправо на 0,5 английского дюйма (примерно 1,25-1,27 см). Здесь он необходим потому, что на консоли текст выводится максимально влево, поэтому на иллюстрации это выглядит неестественно и странно. Вы можете табуляцию для этого не использовать.
Выполните команду Выполнить => Скомпилировать и выполнить или нажмите клавишу F11 на клавиатуре. Результат работы программы будет выведен на консоль (рис. 3). Нажмите любую клавишу на клавиатуре ПК для продолжения работы. Обратите внимание, что на консоли названия русских папок выводятся непонятными символами.
• С:'\изег5\у!1Ло\ОпеОпуе\1рсюушщё€юы\-^Аф‘| ^э1юЕьр€шър —ч-\т++ ьрыхэ№ыищ\-1-
I'm learning С++
Process exited after 0.3559 seconds with return value 0 Для продолжения нажмите любую клавииу . . .
Рис. 3. Результат работы программы на консоли
С выводом английского языка на консоль нет никаких проблем. Замените английский текст на русский (вместо английского языка напишите «Я учу язык C++» или любую другую фразу, но на русском языке), снова скомпилируйте и выполните программу. Увидите, что вместо русского текста выводятся непонятные значки. Необходимо русифицировать вывод текста на консоль, так как кодировки при создании программы и на консоли разные: в оболочке Dev-C++ русские буквы набираются в кодировке СР-1251, а на консоль русские буквы выводятся в кодировке С Р-866.
В каждом примере обязательно отмечайте для себя новое — то, что впервые встретилось в этом примере, — или старое, например цветовое решение в программном коде. Это помогает быстрее ориентироваться при поиске ошибок, когда вы начнете создавать собственный код.
Русификация вывода текста на консоль
В интернете необходимо найти файлы русификации gccrus.exe и g++ rus.exe. Задайте в браузере запрос: «gccrus.exe и g++rus.exe скачать». Например, по адресу https://kpolyakov.spb.rU/school/c/faq.htin найдите текст «Вариант 2» — сразу под этим текстом находится ссылка «Скачайте архив». Щелкните по ней, и файлы gccrus. ехе и g++rus.exe будут скачаны в виде архива. Разархивируйте его. Откройте папку C:\Program Files (х86) => Dev-Cpp =,> MinGW64 => bin. В папку bin скопируйте файлы gccrus.exe и gT+rus.exe.
Выполните команду Сервис —> Параметры компилятора. На вкладке Программы
4) в строке gcc нажмите кнопку Папка ( и выберите файл gccrus.exe. Файлы gccrus.exe и gT+rus.exe можно скопировать другим способом^ в строке gcc нажмите кнопку Папка ( ВЦ) и в открывшееся окно скопируйте русифицированные файлы, а потом здесь же выберите файл gccrus.exe. Аналогично в строке g++ нажмите кнопку Папка ( ss) и выберите файл g++rus.exe. Его имя также появится в строке g++. Нажмите кнопку ОК.
Создайте файл с расширением Ссрр, заполните его по примеру (рис. 5). Символ \п означает переход на новую строку.
То, что в примере два объекта cout, не предписывает программе создавать две строки: переход на новую строку осуществляется, например, с помощью специального символа \п
Параметры компилятора
X
Набор настроек компи лятора: TDM-GCC 4.92 64-bit Release
Компилятор Настройки Каталоги Программы
Вы можете изменить имена файле? программ, которые будут использоваться в Dev-C++ (например, когда используется кросс-компилятор):
дсс:	gccrus.exe	"ft
		
д++:	g++rus.exe	%
		
make:	mingw32-make.exe	Cd Г8
		
qdb:	gdb.exe	Й
		
vjndres:	windres.exe	%
		
gprcf:	gprof.exe	%

«/OK X Отмена
Рис. 4. Подключение русифицированных файлов gccrus.exe и g-n-rus.exe
sals)
« >	(*] Безымянный!.срр
1 «include <icitrear>
2 «include <string>
3 using namespace
stdj
int main() {
cout <<“\t“
cout <<"\t"
<<"Я учу язык C++ \n"j
<<"Я стану программистом"}
8	return 0;
9 Lr
Рис. 5. Программа с русским текстом
Обратите внимание, что названия русских папок в системной полосе так и остались в мнемокодах.
Поэтому желательно создавать папки с английскими именами, чтобы путь, по которому создается файл .срр, всегда был понятен не только вам, но и вашим помощникам и преемникам на работе.

Разберемся с кавычками в специальных символах \t и \п. Символ \t имеет пару кавычек, а символ \п — только одну. Дело в том, что число кавычек должно быть парным в каждом операторе вывода «. Поэтому символ \t имеет пару кавычек, а символ \п является продолжением текста, поэтому открывающая кавычка уже имеется перед текстом, а закрывающая кавычка находится после \п.
Скомпилируйте и выполните программу. В результате этого на консоль будет выведен русский текст (рис. 6).
CAUiersXviktoXOneDriveV-pcKjyuiiM е€юы\—\|}| ЫюЕьрСшър-*+\-+-г орыхэ№ъш1
Я учу язык C++
Я стану программистом
Process exited after 0.3258 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис. 6. На консоль выводится русский текст
Этапы создания программы, языки
программирования, структура системы программирования
27 Общая характеристика языка C++
28 Основные конструкции языка
28	Алфавит
29	Идентификаторы
30	Ключевые слова
34	Специальные символы
36 Структура программы на языке C++
49 Простые типы данных
52 Переменные и константы
52 Переменные
57 Константы
61 Основные операции
63 Приоритеты операторов C++
64 Арифметические и логические выражения
64 Арифметические выражения
67 Логические выражения
71 Оператор равенства
73 Операторы отношения
75 Операторы ввода-вывода библиотеки iostream.h
77 Использование манипуляторов вывода
77 Форматирование с помощью манипуляторов
81 Форматирование с помощью функций-членов и флагов
84 Стандартные математические и строковые функции
84 Библиотека математических функций math.h
92 Преобразование строк в числа
97 Форматирование программного текста
99 Комментарии
101 Заключение
Общая характеристика языка C++
Язык программирования C++ (читается как «си плюс плюс») — это высокоуровневый компилируемый, статически типизированный язык программирования общего назначения, который подходит для создания широкого спектра приложений.
C++ является одним из наиболее популярных и широко используемых языков программирования для разработки программного обеспечения. Его области применения включают операционные системы, различные прикладные программы, драйверы устройств, приложения для встраиваемых систем, высокопроизводительные серверы и компьютерные игры. На C++ существует множество бесплатных и коммерческих приложений для различных платформ. C++ значительно повлиял на другие языки программирования, в первую очередь на Java и С#.
Для написания программы на C++ необходимо иметь два основных компонента: текстовый редактор для ввода исходного кода и компилятор, который преобразует текстовый файл с исходным кодом в исполняемый файл (*.ехе). Все это имеется в Dev-C++.
Стандартная библиотека C++ содержит набор инструментов, которые должны присутствовать в каждой реализации языка, предоставляет программистам полезные возможности и служит основой для разработки как полноценных приложений, так и пользовательских библиотек.
5 £ 05 Q_ L_ О Q_
Этапы создания
оО см
Основные
конструкции языка
Алфавит
В алфавит языка входят:
1)	прописные латинские буквы A-Z;
2)	строчные латинские буквы a-z;
3)	арабские цифры 0-9;
4)	символ подчеркивания (_);
5)	пробельные символы;
6)	знаки пунктуации и специальные символы (табл. 1).
Символы из первых четырех пунктов используются для образования ключевых слов и имен языка. Как видно из алфавита, прописные и строчные буквы различаются между собой. Например, Perem, perem и PEREM будут тремя разными идентификаторами.
Таблица 7
Знаки пунктуации и специальные символы
Сим-L ОЛ	Наименование	Символ	Наименование	Символ	Наименование
/	запятая	{	открывающая скобка	(	открывающая скобка
•	точка	}	закрывающая скобка	)	закрывающая скобка
/	точка с запятой	<	меньше	II	кавычки
	двоеточие	>	больше	+	плюс
?	знак вогэоса	[	квадратная открывающая скобка		тильда
i	апостроф	]	квадратная закрывающая скобка	*	звездочка
1	восклицательный знак	#	решетка, или шарп	—	минус
1	прямой слеш	%	пооцент	=	оавенство
/	слеш	&	амперсанд	А	НЕ-логическое
\	обратный слеш				
Пробельными символами являются пробел и символы табуляции, перевода строки, возврата каретки, перевода страницы. Эти символы используются для разделения лексем языка. При компиляции любые последовательности пробельных символов считаются одним пробелом. Программа на C++ состоит из лексем, или токенов, которые представляют собой наборы символов, распознаваемых компилятором. Между лексемами могут находиться пробелы, новые строки и табуляции. Токен — это наименьший элемент на C++, который имеет значение для компилятора. Компилятор интерпретирует текст программы как непрерывный поток символов, без учета расположения операторов.
Идентификаторы
Идентификатор, или имя, представляет собой набор символов, который используется для обозначения одного из следующих элементов: имени объекта или переменной; имени класса, структуры или объединения; имени перечисленного типа, члена класса, структуры, объединения или перечисления, функции или функции-члена класса; имени определения типа (typedef).
Имя, или идентификатор, — это последовательность букв и цифр, начинающаяся с буквы и не являющаяся ключевым словом, В идентификаторе также можно использовать определенные диапазоны универсальных имен символов. Универсальные имена в идентификаторах не могут содержать управляющие символы или символы кодировки исходного кода.
то о_
L_ о о.
Этапы создания
Для специальных имен типов компилятор создает «внутренние» имена, чтобы хранить информацию о типе. Длина таких имен не может превышать 2048 символов, включая информацию о типе.
Ключевые слова
В языке C++ используются ключевые слова, представленные в следующей таблице (табл. 2).
Таблица 2
Ключевые слова языка C++
№	Ключевое слово	Краткое описание
1	and	Синоним оператора &&
2	and_eq	Синоним оператооа &-
3	asm	Вставка в программу кода на языке ассемблера
4	auto	Предназначен /спя хранения переменных с автоматическим выделением памяти
5	bitand	Синоним оператооа &
6	bitor	Синоним оператооа 1
7	bool	Логический тип данных
8	break	Прерываем работу оператора case
9	case	Оператор выбора
10	catch	Оператор обработки исключительных ситуаций
11	char	Символьный тип данных
12	class	Объявление класса
13	compl	Синоним оператооа -
14	const	Константа
15	const_cast	Преобразование констант в не-константы
16	continue	Осуществляет переход к следующей итерации цикла
№	Ключевое слово	Краткое описание
17	default	Умолчание в операторе switch
18	delete	Освобождение динамически выделяемой памяти
19	do	Оператор цикла
20	double	7ип данных с плавающей запятой с повышенной точностью
21	dynamic_ cast	Определяет принадлежность объекта к определенному типу
22	else	Логический оператор
23	enum	Объявляет перечислимый тип данных
24	explicit	Запрещение вызова конструктора
25	export	Экспортирует переменную из другого файла
26	extern	Импорт функций и классов из других файлов
27	false	Один из двух логических значений, равен 0
28	float	Тип данных с плавающей запятой
29	for	Оператор ор1анизации цикла
30	friend	Объявляет дружественную функцию
31	goto	Оператор работы с меткой
32	if	Оператор цикла
33	inline	Вызывает функцию ее кодом
34	int	Тип данных, целое число
35	long	7ип данных, синоним слова «длинное число»
36	mutable	Оператор, разрешающий изменение поля const, если это объект класса
37	namespace	Разграничитель областей видимости
5 £ 05 Q_ L_ О Q_
Этапы создания
№	Ключевое слово	Краткое описание
38	new	Предназначен для динамического выделения памяти
39	not	Синоним оператооа !
40	not. eq	Синоним оператора !=
41	operator	Предназначен для перегрузки операторов
42	or	Синоним оператора 11
43	or_eq	Синоним оператора |=
44	private	Закрытая часть класса
45	protected	Защищенная иасть класса
46	public	Открытая часть класса
47	register	Оптимизатор переменной при чаевом ее использовании
48	reinterpret-cast	Предназначен для явного приведения неродственных типов
49	return	Предназначен для возврата значения Функции
50	short	Тип данных, короткое целое
51	signed	Устанавливает отрицательные и положительные значения переменной
52	sizoof	Оператор определения размера переменной в памяти
53	static	Объявление статических полей класса
54	static_cast	Предназначен для явного приведения родственных типов
55	struct	Структура, разновидность объединения
56	switch	Логический оператор
57	template	Объявление шаблонов
58	this	Указатель адреса текущего объекта в памяти
№	Ключевое слово	Краткое описание
59	throw	Предназначен для генерации исключения
60	true	Один из двух логических значений, равен 1
61	try	Оператор обработки исключительных ситуаций
62	typedef	Определяет псевдоним типа
63	typeid	Аналог sizeof для определения типа выражения
64	typenarne	Предназначен для доступа к полю параметра — шаблона
65	union	Союз, разновидность объединения
66	unsigned	Устанавливает значения переменной o'i 0 и выше, запрещает отрицательные значения переменной
67	using	Включает указанное пространство имен в глобальное
68	virtual	Предназначен для объявления виртуальных функций
69	void	Объявляет безтиповое значение функции
70	volatile	Оператор, предназначенный для изменения объекта извне npoi раммы C++
71	wchar_t	Тип символьных данных, превышающий 256 значений char
72	while	Опеоатор цикла
73	xor	Синоним оператора Л
74	xor_eq	Синоним оператора л-
5
го о_
L_ о О_
Этапы создания
Стандарт языка контролируется специальными организациями (ISO — Международная организация по стандартам, ANSI — Американский национальный институт стандартизации) для языка C++.
Таблица содержит ключевые слова, используемые в современном стандарте языка C++. Стандарт языка контролируется специальными организациями (ISO — Международная организация по стандартам, ANSI — Американский национальный институт стандартизации) для языка C++.
Специальные символы
Специальные символы (табл. 3) используются для перехода на новую строку, табуляции и т. д.
Таблица 3
Специальные символы
гл
Название	Символ
Новая сорока	\п
Горизонтальная табуляция	\t
Забой (backspace)	\ь
Звуковой сиI нал	\а
Обратный слеш	\\
Знак вопроса	\?
Одинарная кавычка	V
Двойная кавычка	\"
Рассмотрим пример с использованием специальных символов (рис. 7) (обратите внимание, что специальные символы находятся внутри строки, ограниченной кавычками):
В этой теме и личной и мелкой, перепетой не раз и не пять, я кружил поэтической белкой и хочу кружиться опять.
Про это Б.В. Маяковский
Process exited after 0.4065 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис. 7 Применение специальных символов
#include <iostream> ^include <string> using namespace std; int main()
{
cout «"\n\t"«"B этой Tewie,\n\t";
cout «"\t"«"n личной\п\ЛГ;
cout	мелкой,\n";
cout «"\1"«"перепетой не раз\п\Г\Г;
cout «"\1"«"и не пятьДп";
cout «"\t"«"n кружил поэтической белкой\п"; cout «"\Г«"и хочу кружиться onaTb.\n\n\t\t"; cout «"\t"«"npo 3To\n\t\t";
cout «"\t"«"B. В. Маяковский\п"; return 0;
}
Специальные символы должны быть заключены в кавычки, как правило — двойные. Если специальные символы находятся после текста — кавычки им нужны только справа. Но если рядом нет текста, то специальные символы заключаются в отдельные кавычки.
Часто вместо одной двойной кавычки неопытные пользователи вводят две одинарные кавычки. В C++ в программном коде это хорошо видно: одиночные кавычки находятся на большем расстоянии, чем в двойной. Программа ошибку обнаружит
Структура
программы на языке
Программный код состоит из нескольких связанных между собой частей: директив препроцессора и подключаемых файлов из библиотек. Подключаемые файлы содержат расширение *.h (или другие расширения) (расширение *.h обычно опускается), а директивы препроцессора такого расширения не содержат.
Перед директивой и подключаемым файлом указывается выражение ftinclude. То есть:
tfinclude <iostreain>
^include <stdio.h> tfinciude <conio.h>
(В директиве <iostream> расширение *.h опущено.)
Инструкции препроцессора используются для упрощения изменений в программе и для обеспечения ее независимости от различий в компиляторах. Директивы могут быть размещены в любом месте исходного файла, но их действие распространяется, начиная с места записи директивы и заканчивая концом файла.
Препроцессор — это текстовый процессор, управляющий текстом файла исходного кода в ходе первого этапа трансляции. Препроцессор не анализирует исходный текст, а разбивает его на маркеры для поиска вызовов макросов. Хотя компилятор обычно вызывает препроцессор при первом проходе, препроцессор можно также вызвать отдельно для обработки текста без его компиляции.
Директивы препроцессора, такие как ttdefine и ftifdef, как правило, используются для упрощения изменения и упрощения компиляции исходных программ в разных средах выполнения. Директивы в исходном файле сообщают препроцессору, что надо выполнять определенные действия. Например, препроцессор может заменять токены в тексте, вставлять содержимое других файлов в файл исходного кода или отключать компиляцию части файла путем удаления разделов текста. Строки препроцессора распознаются и выполняются до расширения макросов. Таким образом, если макрос расширяется в то, что выглядит как команда препроцессора, она не распознается препроцессором.
Инструкции препроцессора используют тот же набор символов, что и инструкции исходного файла. Набор символов в операторах препроцессора совпадает с кодировкой выполнения. Препроцессор также распознает отрицательные значения символов.
Знак номера (#) должен быть первым символом в строке, содержащей директиву. Символы пробелов могут отображаться между знаком номера и первой буквой директивы. Некоторые директивы содержат аргументы или значения. Любому тексту, следующему за директивой (кроме аргумента или значения, который является частью директивы), должен предшествовать одностроковый комментарий разделителя (//), или такой текст должен быть заключен в разделители комментариев (/* */)• Строки, содержащие директивы препроцессора, можно продолжить сразу перед маркером конца строки с обратной косой чертой (\).
Препроцессор не анализирует исходный текст, а разбивает его на маркеры для поиска вызовов макросов
Директивы препроцессора могут отображаться в любом месте исходного файла, но они применяются только к остальной части исходного файла после их появления.
Команды в C++-заканчиваются точкой с запятой.
оО m
Директивы препроцессора могут отображаться в любом месте исходного файла, но они применяются только к остальной части исходного файла после их появления.
Препроцессор входит в любой компилятор программ на C++ и любую среду разработки, рассчитанную на этот язык. Препроцессор обрабатывает исходный код программ до их компиляции.
Препроцессорные команды, или директивы, управляют работой препроцессора.
Таких команд немного, они все начинаются со знака решетки (#) и должны быть в начале строки исходного кода:
•	ddei* — эта директива предусматривает определение макросов или препроцессорных идентификаторов, простейшее применение — это замены в тексте программы;
•	tfnclu ie — позволяет включать текст других файлов в текст вашей программы;
•	fundef — отменяет действие директивы tfdefine;
•	— организация условной обработки
директив;
•	— организация условной
обработки директив;
— организация условной обработки директив;
•	tend — организация условной обработки директив;
•	teli — организация условной обработки директив;
•	Mine — управление нумерацией строк в тексте программы;
•	terror — задает текст диагностического сообщения, выводящегося при наличии ошибок;
•	4рг<"	— зависит от среды разработки;
•	— нулевая, или пустая, директива,
бездейственно пропускается.
Директива #define. Директива ffdefine служит для замены часто использующихся констант, ключевых слов, операторов или выражений некоторыми идентификаторами. Идентификаторы, заменяющие текстовые или числовые константы, называются именованными константами. Идентификаторы, заменяющие фрагменты программ, называются макроопределениями, причем макроопределения могут иметь аргументы.
Основная форма синтаксиса директивы tfdefine:
ttdefine идентификатор текст
Так, например, в программе:
ftdefine N 5 int main() { int a;
a = N;
return 0,
s
5
m
Директива include — это .директива препроцессора.
Каждая из таких директив размещается на одной строке.
И в отличие от
завершающихся точкой с запятой, признаком завершения прелроцессорной директивы служит перевод на новую строку. Кроме того, директива должна начинаться со знака решетки # Именно include определяет, какие файлы и библиотеки надо подключить в код программы.
Здесь ftdefine — директива, константа; N — имя константы; 5 — значение константы. В нашем примере переменная а примет значение 5.
Директива #undef. Директива ftundef удаляет текущее определение идентификатора, поэтому все встречающиеся появления идентификатора будут игнорироваться предпроцессором. Чтобы удалить определение макро с использованием tfundef, нужно задать только идентификатор макро, не задавая список параметров.
Можно применить директиву ftundef к идентификатору, у которого нет определения. Тем самым пользователь получает дополнительную гарантию того, что данный идентификатор не определен.
Директива flundef обычно используется в паре с директивой #d efine для задания области исходной программы, в которой идентификатор имеет специальное значение. Например, некоторая функция исходной программы может иметь объявленные константы, которые задают значения среды работы, не влияющие на остальную часть программы. Директива #undef также работает с директивой #if для управления условной компиляцией исходной программы.
Условные директивы frit, #ifdef, #else, tfendif, Эти директивы позволяют подавить компиляцию части исходного файла, проверяя постоянное выражение или идентификатор. Результат проверки определяет, какие блоки текста будут переданы в компилятор, какие — удалены из исходного файла при предпроцессорной обработке.
Директива #line. Изменяет внутренний номер строки и имя файла компилятора. Если имя файла опущено, оно остается прежним.
Синтаксис директивы:
ftline константа <"имя_файла">
К примеру, #line 1000 "file.cpp" устанавливает имя исходного файла file, срр и текущий номер строки 1000. Текущий номер строки и имя файла доступны через константы препроцессора___LINE__и____
FILE_
Директива #еггог. Директива fterror создает заданное пользователем сообщение об ошибке во время компиляции, а затем завершает компиляцию.
Синтаксис:
Сообщение об ошибке,
создаваемое этой
директивой, содержит
параметр token-string Параметр tokenstring не подлежит расширению макроса. Эта директива наиболее полезна в ходе предварительной
обработки: она
позволяет уведомлять разработчика
о противоречиях в программе или о нарушении ограничений.
fterrortoken-string
Пример использования:
#if!defined(_cplusplus)
tterror C++ compiler required. #endif
5
го
Q_
L_
О Q_
Обратите внимание на вид кавычек: это компьютерные кавычки. Если в процессе обучения вы возьмете пример со стороны и кавычки там будут иметь другой вид (елочки «», лапки то после встазки текста примера необходимо изменить кавычки на компьютерные, иначе может быть сгенерирована ошибка.
Директива ttpragma. Это инструкция к компилятору, которая определяется реализацией. Конструкция #pragma в языке C/C++ используется для задания дополнительных указаний компилятору. С помощью этих конструкций можно указать, как осуществлять выравнивание данных в структурах, запретить выдавать определенные предупреждения и т. д.
Директива ^include. Обычно файлы, которые появляются в директивах #include, заканчиваются на *.h и представляют собой файлы заголовков (header file).
В них содержатся объявления констант, переменных и функций, необходимых для работы программы. Например, для выполнения математических вычислений часто используется файл math.h, в котором описаны такие процедуры, как извлечение квадратного или кубического корня, и многое другое.
Директива препроцессора #include позволяет включать в текст программы, написанной программистом, тексты других готовых программ.
Эта директива имеет две формы записи:
//include <имя_включаемого_файла> //include "имя_включаемого_файла"
Когда имя _включаемого_файла
(файла включений) записывается в угловых скобках, то поиск этого файла осуществляется в стандартных системных каталогах, например каталоге подключаемых файлов (include directory), — в месте, где компьютерная система хранит все доступные для использования файлы заголовков.
Если имя_включаемого_файла указано в кавычках, то сначала поиск осуществляется в текущем каталоге и лишь затем в системных.
Директива ftinclude — это директива препроцессора для подключения указанных файлов. Каждая директива препроцессора размещается на одной строке. В отличие от обычных инструкций C++, которые заканчиваются точкой с запятой (;), окончанием директивы препроцессора является новая строка. Директива должна начинаться с символа решетки (ft).
Директива #include определяет, какие файлы и библиотеки будут включены в определенное место программного кода.
Программа на C++ состоит из последовательности инструкций. Каждая инструкция выполняет определенное действие. В конце инструкции вводится точка с запятой (;). Этот символ указывает компилятору, что инструкция завершена.
Набор инструкций также может представлять собой блок кода. Блоки кода заключаются в фигурные скобки, а инструкции помещаются между фигурными скобками.
Файлы заголовка содержат объявления прототипов библиотечных функций. В них находятся определения типов данных и символических имен констант библиотечных функций, а также глобальные переменные, определяемые C++ и библиотечными функциями.
4=. GO
Этапы создания программы
Ниже приведен краткий список таких заголовочных файлов:
•	alloc.h — объявляет функции управления памятью (распределение памяти, отмена распределения памяти И т. д.);
•	assert.h — определяет отладочный макрос assert;
•	complex.h — объявляет комплексные математические функции C++;
•	conio.h - объявляет различные функции, используемые при вызове функций ввода-вывода с консоли;
•	ctype.b — содержит информацию, используемую макросами символьной классификации и символьных преобразований;
•	dir.h — содержит структуры, макросы и функции для работы с папками и путями доступа;
•	errno.b — содержит мнемонические константы кодов ошибок;
•	fcntl.h — содержит символические константы, используемые совместно с библиотечной подпрограммой open;
•	float.h — содержит параметры функций обработки чисел с плавающей точкой;
•	fstream.h — объявляет классы потоков C++, поддерживающие ввод-вывод в файлы;
•	ic.h — содержит структуры и объявления функций ввода-вывода низкого уровня;
•	icmanip.h — объявляет манипуляторы ввода-вывода потоков C++;
•	iostream.h — объявляет методы (ввода-вывода) потоков базового C++;
•	limits.h — содержит параметры среды программирования, информацию об ограничениях времени компиляции, численные диапазоны интегральных типов;
•	locale.h — объявляет функции, содержащие информацию, специфичную для конкретной страны и языка;
•	math h — объявляет прототипы математических функций;
•	mem.h — объявляет функции манипулирования памятью (многие из них также определены в string.h);
•	process.h — содержит структуры и объявления для функций spawn и ехес;
•	share.h — определяет параметры, используемые в функциях, работающих с разделением файла;
•	signal.h — определяет макросы, используемые для чтения списков аргументов функций, объявленных как принимающие переменное число аргументов (например, vprintf, vscanf и т. д.);
44
Ln
Этапы создания программы
•	stddef.h — определяет несколько общих типов данных и макросов;
•	stdlib.h — объявляет некоторые широко используемые подпрограммы (методы преобразования, методы поиска или сортировки и проч.);
•	string.h — объявляет несколько функций строковых манипуляций и манипуляций с памятью;
•	strstrea.h — объявляет классы потоков C++ для работы с байтовыми массивами в памяти;
•	sys\stat.h — объявляет символические константы, используемые при открытии и создании файлов;
•	sys\timeb.h — объявляет функцию time и структуру timeb, возвращаемую time,
•	sys\types.h — объявляет тип type_t, используемый функциями времени;
•	time.h — определяет структуру, используемую функциями преобразования времени asetime, localtime и gmtime, а также тип, используемый функциями ctime, difftime, gmtime, localtime и stime; содержит прототипы этих функций;
•	values.h — определяет некоторые константы.
После директив //include могут описываться символические константы //define, глобальные переменные, прототипы функций.
В каждой программе на C++ есть функция main() Именно эта функция начинает выполнение приложения; имя main является фиксированным и всегда одинаково во всех программах на C++. Функция main также является блоком кода, поэтому ее тело заключено в фигурные скобки, а между ними определен набор инструкций. Определение функции main начинается с возвращаемого типа. Как правило, главная функция должна возвращать число.
Поэтому ее определение начинается с ключевого слова int. Если функция main ничего не возвращает, то она может иметь тип void. После этого следует имя функции — main. Обычно функция main не принимает никаких параметров, поэтому за именем следуют пустые круглые скобки. Однако некоторые определения функции main предполагают использование параметров. В функции main могут описываться локальные переменные, вызываться функции, объявленные перед функцией main. Если в функции main вызываются глобальные переменные (объявленные перед main), то при использовании перед их именем указывается двойное двоеточие (::).

о
©
©
В конце функции следует инструкция return Эта инструкция завершает выполнение функции main, а контроль передается операционной системе. Число О после оператора return указывает операционной системе, что выполнение функции завершилось успешно, без ошибок.
В исходном коде могут присутствовать комментарии, которые помогают пользователю понять смысл программы и функционал определенных ее частей. Комментарии не учитываются при компиляции и не влияют на работу программы или ее объем.
Для создания исполняемою файла из исходного кода на C++ выполняются три этапа:
•	препроцессор обрабатывает все директивы препроцессора, такие как #include, заменяя их в тексте программы на реальный программный код из указанных заголовочных файлов;
•	компилятор обрабатывает каждый файл исходного кода, создавая из него объектный файл, содержащий машинный код (если код разделен на несколько файлов исходного кода, для каждого файла создается свой объектный файл);
•	компоновщик (линковщик) объединяет все объектные файлы в одну исполняемую программу.
Простые типы данных
Переменная в программе — это идентификатор, который требует выделения определенной памяти. Чтобы определить, сколько памяти нужно выделить, необходимо указать тип переменной. Память будет выделена в соответствии с этим типом. Основные типы переменных приведены в следующей таблице (табл. 4).
Таблица 4
Типы переменных
Тип (значение)	Размер (байт)	Значения
int(целое)	4	от-2147 483 648 до 2147 483647
short int (короткое целое)	2	от-32768 до 32767
long int	Л	от-2147 483 648
(длинное целое)	ч	до 2147 Д83647
float (число с плавающей запятой)	4	3,4 х 10’38 ... 3,4 х 10+38
double (число с плавающей запятой двойной	8	1,7 х IO’308 ... 1,7 х 1О+308
точности)		
long double (длинное число с плавающей запятой двойной	10	3,4 х 10"4932 ... 1,1 Ю+4932
точности)		
char (символьное)	1	-128...127
bool (логическое)	1	true (1) или false (0)
-и. о
5 го Q_ i— О CL Логический тип bool относится к целым значениям и занимает 1 байт. Диапазон допустимых значений для
з	bool — целые числа от 0 до 255. Этот
EZ
тип данных используется для хранения результатов логических выражений. Логическое выражение может быть истинным (true) или ложным (false). Константа true эквивалентна числам от 1 до 255 включительно. Константа false эквивалентна только числу 0.
Символьные данные типа char представляют собой различные символы, которым соответствует численное значение во внутренней кодировке компьютера. Символьная константа — это символ, заключенный в одинарные кавычки, например '9',	'g'. Независимо
от того, что речь идет о символах, они имеют числовое значение, которое берется из кодировки ASCII (программой, не программистом). Символ 'а' (английская), например, имеет в кодировке ASCII значение 97.
Существует две модификации этого типа: signed char и unsigned char.
Данные char занимают 1 байт и меняются в диапазоне:
• signed char (или просто char) — от -128 до +127;
unsigned char — от 0 до 255.
Как правило, тип char считается устаревшим и вместо него применяют тип string, но тип char по-прежнему широко используется в программах. Кроме числа символов в string добавляется символ конца строки. Поэтому строка «C++» будет занимать не три, а четыре символа. Значение string заключается в кавычки.
Значения short int, long int допускается писать без слова int, т. е. short и long, хотя написание полного типа (short int, long int) тоже допускается. Добавление перед типом переменной ключевого слова unsigned («беззнаковый») приводит к отбрасыванию отрицательных значений и увеличению на эту величину положительных значений, например unsigned char, unsigned long int и т. д. Например, переменная типа unsigned char имеет значения от 0 до +255 — таким образом реализована в языке возможность работы с кириллицей. Кодировка символов находится в таблице ASCH, Переменная типа unsigned long может принимать значения от 0 до 4294 967295.
Для справки: можно к обычным значениям типов данных слева писать слово signed («знаковый») — signed long signed long double; но обычно это не делается, так же как в положительных числах мы обычно не пишем знак плюс (+).
Точное знание границ значения переменной необходимо для предотвращения выхода за границы возможных значений.
Например, если к значению 32 767 типа short прибавить 1 (т. е. n = n + 1), то вместо ожидаемого значения, равного 32 768, значение п будет равно 0, т. е. цикл допустимых значений будет пройден и после пересечения границы допустимых значений, будет происходить циклический переход и счет начнется с 0.
5 £ го Q_
ГЧ1 Ln
Переменные и константы
Переменные
Теперь, когда определены основные типы переменных, можно приступить непосредственно к объявлению переменных. Переменная объявляется следующим образом:
имя переменной;
Например, через точку с запятой:
double Stoim; int itogo, unsigned long int Npoporjadku;
Каждая переменная может быть записана в программе как в одну строку, образец которой приведен выше, так и отдельными строками:
double Stoim; int itogo;
unsigned long int Npoporjadku;
Переменные с одним типом данных можно записать в одну строку, отделяя каждую переменную запятой; после последней переменной тоже ставится точка с запятой, например:
double Stoim, itogo, Sebestoim, effekt.
Запятая в C++ используется только в одном качестве — как перечисление в списке. Больше нигде запятая не участвует (кроме текста), в том числе и для обозначения десятичного знака в действительном числе. В качестве десятичного знака в C++ используется только точка.
Эту же строку можно расписать и отдельными строками, завершая каждую строку точкой с запятой:
double Stoim;
double itogo,
double Sebestoim, double effekt;
Имена переменных могут начинаться с буквы латинского алфавита или символа подчеркивания (_). Хотя первым символом в имени переменной может быть подчеркивание, рекомендуется избегать его в имени переменной в виде первого символа.
Следующими символами переменной могут быть буквы латинского алфавита, цифры или еще одно подчеркивание (например, вместо пробела). Переменная может иметь длину до 200 символов. Ключевые слова языка C++ нельзя использовать в качестве переменных. Объявлять переменную как:
int int;
недопустимо, зато переменная
double Double;
или
double Double z;
вполне допустима, так как ключевые слова имеют только строчные буквы, а C++ различает регистр. Поэтому переменные Double, Long, Int не будут являться ключевыми словами и такие переменные теоретически можно использовать.
Внутри переменной не допускаются пробелы.
СП UJ
Хотя это и не является ошибкой и допустимо, но все-таки переменных с именами, похожими на ключевые слова, следует избегать, чтобы не запутаться самим и облегчить понимание вашей программы другим людям, которые будут работать с вашими программами в будущем.
Б приведенном примере впервые встретился комментарий, Все, что будет обьявлено после //, будет являться комментарием и не будет включаться в программу.
Внутри переменной не допускаются пробелы. Например, переменная double Itogo Polnaja будет воспринята как ошибка, так как внутри переменной Itogo Polnaja находится пробел. Но если пробел убрать: double ItogoPolnaja, то никаких нарушений правил не будет. Если необходимо визуально разделить переменную на несколько слов для лучшею восприятия, то, как правило, используют символ подчеркивания: double Itogo_Polnaja.
Если переменную не объявить или в ней сделать ошибку, то при компиляции будет выдано сообщение об ошибке: Undefined symbol <Имя переменной> (Необъявленная переменная).
Допустимо объявлять переменную в любом месте программы, но до использования этой переменной, например:
double Itogo2, Summal, с; с = Itogo2 / Summal;
Но сначала использовать, а но гом объявлять переменные недопустимо:
с = Itogo4 / Zena3;
double Zena3, Itogo4, c;
Такой пример при прочтении первой строки вызовет сообщение об ошибке
компилятора — о том, что переменная не объявлена. После прочтения второй строки переменные все же будут объявлены, но компилятор не будет помнить о первой строке. Поэтому должно быть выдано программой предупреждение, что переменные Zena3 и Itogo4 объявлены, но не используются.
При объявлении переменной в памяти ПК создается некоторое случайное значение. Это значение берется случайным образом в прямом смысле этого слова. При инициализации переменная уже получает конкретное, а не случайное значение. Поэтому объявленная, но неинициализированная переменная хранит некоторое значение, которое она сама же и придумала. Не стоит этому удивляться, так как мы уже говорили, что при объявлении переменной ей отводится некоторая память, а память ведь не может быть пустой, поэтому она и забивается случайным значением.
Хороший стиль программирования требует, чтобы переменные объявлялись в начале программы (глобальные переменные) или сразу после объявления функции main() (локальные переменные), в файле с именем *.срр.
Понятие области видимости переменных тесно связано с понятием переменных. Переменные могут быть глобальными или локальными. Глобальные переменные существуют на протяжении всей программы, в то время как локальные переменные действуют только в ограниченной части программы.
Переменная представляет собой именованный участок памяти. Переменная имеет тип, имя
и значение.
Например, объявим глобальную переменную перед функцией main:
double А = 40,
Объявляются только используемые в данной программе переменные. Если переменная объявляется, но не используется, это не считается ошибкой, но при компиляции вашей программы может быть выдано предупреждение: «Переменная» is declared but never used, т. e. переменная объявлена, но не используется. Такую переменную лучше исключить из объявления, иначе она будет занимать лишнюю память, или закомментировать ее.
Заканчивая рассмотрение переменных, необходимо остановиться на типе bool. Переменные с таким типом объявляются следующим образом:
bool Perv = true;
bool Wtor = false:
Никаких других значений тип bool принимать не может. Оба значения пишутся строчными буквами, значения True или False недопустимы. Немного выше уже описывались подобные же ситуации с Double, Long, Int: изменив в слове одну букву, мы ключевое слово превратим в неключевое. Поэтому, если ввести: bool Perv = True; — мы тем самым объявим, что логическая переменная Perv равна значению переменной True, которая к тому же нигде не объявлена, поэтому получим сразу несколько ошибок и предупреждений компилятора. Даже если случайно переменная Perv объявлена, она наверняка не логического типа, а, например, числового или символьного, что тоже вызовет сообщение об ошибке.
Переменная объявляется только один раз. Если переменная объявляется более одного раза, будет выдано сообщение об ошибке: двойное объявление переменной.
Нельзя также объявлять переменную (int а;), а затем присваивать ей значение с объявлением (int а = 10;).
Правильнее сразу объявить переменную и сразу присвоить ей значение:
int а = 10;
или:
int а; а = 10;
Константы
Символическая константа tfdefine.
Синтаксис константы следующий:
^define Игля константы значение
Значок решетки говорит о том, чго константа должна объявляться в группе объявлений, т. е. в начале программы.
В конце этой конструкции точка с запятой не ставится. Имя константы — идентификатор, используемый в тексте программы. Значение — числовое, символьное или строковое, которое замещает в процессе выполнения программы Имя_константы. Например:
#define Kurs 89.123
Здесь Kurs — курс рубля в какой-либо валюте, 89.123 — значение курса. В тексте программы используется константа Kurs, например:
double itogo;
itugo = Kurs * banknot;
1000000
При расчете вместо константы Kurs будет подставляться значение 89.123.
Этапы создания программы
Рассмотрим следующий пример (рис. 8):
Значение itogo=: 17875.1327
Сесер. Общество с ограниченной ответственностью
Process exited after 0.3049 seconds with return value 0
Цля продолжения нажмите любую клавишу . . . _
Рис. 8. Пример с константами
00 1Л
Обратите внимание на строку «Значение itogo =: «. Здесь символы (=) и (:) показаны синим цветом, а не красным, так как в данном примере это текст, а не программный код.
^include <iostream> ttdefine Kurs 89.123 ^define Sewer "Север. Общество с ограниченной ответственностью" using namespace std.
int main()
{
double znash = 200.567;
double itogo;
itogo = Kurs * znash;
cout« fixed;:
cout precision(4);
cout« "\t" « "Значение itogo=: " « itogo <<"\n"; cout « "\t" « Sewer« "\n";
return 3.
}
Рассмотрим новые строки:
cout« fixed;
cout precision^);
Первая команда сообщает, что будет выводиться фиксированное число, с заданным числом знаков после запятой. Вторая команда указывает, что после запятой будет выведено четыре знака: в нашем примере — 17875,1327.
В качестве значения константы необязательно может использоваться только число, но еще и строка:
ttdefine Sewer "Север. Общество с ограниченной
ответственностью
В ходе выполнения программы константа Sewer всюду, где встретится, будет заменена соответствующим текстом, объявленным в директиве fldefne.
Обычно это объявление используется при частом обращении к длинным и точным константам. Например, числа л, г можно объявит], так:
tfdefine Pi 3.14159265358979323846 ttdefine е 2,7182818284590
Во всех расчетах используется только идентификатор Pi или е, который во время расчета заменяется на заданное значение.
Именованная константа. Это константа, для которой присваивается идентификатор. Именованная константа объявляет синтаксис:
const Тип_константы Имя_константы значение;
Например:
const int abc = 63;
Здесь const — ключевое слово, объявляющее константу; Тип_константы может принимать любой допустимый тип (int, float, double и т. д.). Имя_константы значение аналогично рассмотренным в символической константе, только объявляется в области объявления переменных. Строка должна завершаться точкой с запятой. В именованной константе допускаются числовые, символьные и строковые значения.
1Л
СО
Этапы создания программы
Рассмотрим пример с ошибкой:
tfinclude <iostream> ttinciude <cstdlib> using namespace std, int main()
{
int a = 25;
int b = 8,
const int abc = 63;
abc = a / 4 + b;
cout« "\t" « "Переменная abc=:" « abc « "\n"; return D,
}
Константа получила значение 63. Если попробовать использовать ее так, как в нашем примере, строка abc = а / 4 + Ь; будет объявлена ошибкой: [Error] assignment of read-only variable 'abc'. Попробуем обмануть программу и не будем инициализировать константу, т. е. запишем:
const int abc;
В этом примере константа abc не инициализирована, поэтому она получила случайное значение, которое в ходе расчета нельзя изменить.
Наша хитрость не удалась, и текст ошибки тот же.
Основные операции
Операции делятся на унарные и бинарные: унарная операция — это операция с одним операндом; бинарная операция — это операция с двумя операндами.
В табл. 5 представлены основные операции языка C++.
Таблица 5
Основные операции языка C++
Операция	Описание
	УНАРНЫЕ ОПЕРАЦИИ
++	Увеличение значения на единицу
—	Уменьшение значения на единицу
	Поразрядное отрицание
!	Логическое отрицание
—	Арифметическое отрицание (унарный минус)
+	Унарный плюс
&	Получение адреса
*	Обрацение по адресу
(type)	Преобразование типа
	БИНАРНЫЕ ОПЕРАЦИИ
+	Сложение
—	Бычитание
*	Умножение
/	Деление
%	Остаток от деления
«	Сдвиг влево
»	Сдвиг впоаво
<	Меньше
>	Больше
<=	Меньше или равно
5
05 Q_
L_
О Q_
Этапы создания
Операция	Описание
>=	Больше или равно
==	Равно
!=	Не разно
&	Поразрядная конъюнкция (И)
Л	Поразрядное исключающее И71И
1	Поразрядная дизъюнкция (ИЛИ)
&&	Логическое И
II	Логическое ИЛИ
-	Присваивание
*_	Умножение с присваиванием
/=	Деление с присваиванием
+=	Сложение с присваиванием
—=	Вычитание с присваиванием
%=	Остаток от деления с присваиванием
«=	Сдвиг влево с присваиванием
»=	Сдвиг вправо с присваиванием
&=	Поразрядная конъюнкция с присваиванием
1=	Поразрядная дизъюнкция с присваиванием
л-	Поразрядное исключающее ИЛИ с присваиванием
ДРУГИЕ ОПЕРАЦИИ	
?	Условная операция
	Последовательное вычисление
sizeof	Определение размера
(тип)	Преобразование типа
Приоритеты операторов C++
Здесь GLPEREM - глобальная переменная, PEREM — любая переменная.
Создавая алгоритм, необходимо учитывать приоритетность выполнения операторов.
Таблица 6
Приоритеты операторов С++
Оператор	Название
:: GLPEREM	Оператор разрешения контекста
i++, i—	Постфиксный инкремент и декремент
sizeof, ++i, —i	Оператор sizeof, префиксный инкремент и декремент
*, /, %	Умножение, деление, взятие остатка
+, —	Сложение, вычитание
<? <=, >, >=	Меньше, меньше или равно, больше, больше или равно
== 1= ) •	Равно, не равно
&&	Лог ическое И
II	Логическое ИЛИ
PEREM? PEREM: PEREM	Условный опеэатор
Если в одном выражении встречаются действия с различными приоритетами, то каждая часть выражения заключается в круглые скобки, так же как в математике пишутся подобные же выражения, например:
(А + В) * С + (D-C);
Этапы создания программы
Арифметические и логические
выражения
Арифметические выражения Арифметические выражения, или операции, обозначаются теми же привычными символами, что и в математике (табл. 7):
Арифметические операции
Обозначение	Операция	Пример
+	Сложение	А + Bl, Zertal + Zena2, Itogol + Itogo3
—	Вычитание	С — E12, Itogol — Itogo4, GHJ - 7
*	Умножение	Zena2 * Kol3, ERT * BvHl
/	Деление	Z / 10, Itogol / Zena3
%	Остаток от целочисленного деления	Razmer % 5
Примеры этих операций: А + В, Zena 1 * KOL2 и т. д.
Оператор взятия остатка предназначен для определения остатка от целочисленного деления. Оператор возвращает остаток от деления: А % В. Если заменить эти переменные целыми цифрами, то при делении 25% 3 остаток будет 1.
В языке C++ существуют понятия инкремента и декремента (табл. 8), или операторов приращения, от которого язык и получил свое название «C++».
Табл и ио 8
Операции инкремента и декремента
Обозначение	Операция	Пример
++	Инкремент	)++; ++I
—	Декремент	i—i
Назначение этого оператора — увеличить или уменьшить имеющееся значение на единицу. Работа происходит в основном с целыми величинами, так как применять оператор для чисел с плавающей запятой бессмысленно.
Итак, оператор приращения заменяет оператор сложения (вычитания) Tshislo = Tshislo + 1; на оператор Tshislo++ (при вычитании — на Tshislo—).
Между знаками ++ или — пробелы не пишутся: это один знак, состоящий из двух символов.
Оператор приращения применяется в основном при переборе чисел какого-то цикла в указанных границах. Границы должны быть обязательно, так как и увеличение, и уменьшение возможно до бесконечности.
Различают постфиксный и префиксный операторы инкремента и декремента.
Постфиксные операторы выглядят так:
у++; х—;
Префиксные операторы выглядят так:
++у; —у;
Это очень важное между ними различие, о котором очень часто забывают.
В зависимости от того, какой оператор приращения выбран — постфиксный или префиксный, приращение происходит в разное время. Если выбран постфиксный оператор, то приращение происходит после вычисления всего выражения. Если выбран префиксный оператор, то приращение происходит до вычисления всего выражения. Если объяснить это еще проще, то в постфиксном операторе сначала считается что-то, а потом приращивается (или вычитается) единица, а в префиксном — сначала приращивается (или вычитается) единица и только потом производится расчет.
Рассмотрим пример расчета с делением и выводом результата на консоль (рис. 9):
Переменная с=: 14
Process exited after 0.2562 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис. 9 Пример выводе результата расчета
^include <iostream> ^include <cstdlib> using namespace std. int main()
{
int a = 25;
int b = 8;
int c;
c = a / 4 + b;
cout« "\t" « "Переменная c=:" « c « "\n"; return D;
Разберем этот пример. Целая а = 25 делится на 4. В результате получится 6,25. Но переменная а является целым, поэтому дробный остаток отбрасывается, остается б, а6 + 8 = 14.
Логические выражения
Оператор И. Оператор И представляет собой два амперсанда: &&. Оператор И является бинарным, или двухместным, т. е. работает для двух операндов, по одному с каждой стороны. Внутри этого бинарного оператора пробел не разрешается, так как два символа этого оператора пишутся вместе.
Синтаксис оператора можно представить так:
Idenl && !den2
Оператор И является левоассоциативным, т. е. при наличии нескольких операндов в одном операторе вычисление происходит в порядке следования, а именно слева направо:
Idenl && Iden2 && Iden4
Оператор И является истинным, т. е. true, если оба операнда являются истинными (true). Если хотя бы один операнд не является истинным (false), то все выражение является ложным (false).
Таблицу истинности для оператора
И можно представить следующим образом (табл. 9):
5 £ 05 CL L_ О CL
Этапы создания
Табпица 9
Таблица истинности для оператора И
Значение		
левого операнда Л	правого операнда П	истинности Л и П
		
		
		
		
Аналогом оператора && является ключевое слово and. Написанное выше выражение можно переписать так:
idenl and Iden2 and Iden3
Оператор && не самостоятельный оператор, который заканчивается точкой с запятой, — это только фрагмент логического оператора. Такое логическое выражение можно встретить, например, в операторе ветвления. Тогда этот фрагмент мог бы выглядеть так:
if(ldenl and Iden2 and Iden3)
или так:
ifpdenl && Iden2 && iden3)
Оператор ИЛИ. Оператор ИЛИ представляет собой два вертикальных слеша: | |. Так же как и оператор И, этот оператор является бинарным и левоассоциативным. Оператор ИЛИ будет истинным, если хотя бы один операнд является истинным (true). Оператор ИЛИ является ложным, если ложны оба операнда (false).
Таблицу истинности для оператора ИЛИ можно представить следующим образом (табл. 10):
Таблица 10
Таблица истинности для оператора ИЛИ
Значение
левого операнда Л	правого операнда П	истинности Л и П
true	true	true
true	false	true
false	true	true
false	false	false
Примеры применения оператора ИЛИ:
(20/5) <6 П true (2+ 2) >5 || false
Аналог оператора ИЛИ — ключевое слово or. Оператор ИЛИ встречается в других выражениях и не является самостоятельным. Использование оператора ИЛИ в операторе ветвления могло бы выглядеть так:
if(lden 1 11 Iden2)
или так:
if(lden 1 or Iden2)
Этапы создания программы
Оператор отрицания
Оператор отрицания (!) изменяет логическое выражение на противоположное, true на false, false на true.
Пример применения оператора отрицания:
(•true)
!(5 < 6)	, или {!(true)}, или {не(Исгина)] =
Неистина
В качестве отрицания можно использовать следующие ключевые слова: not в качестве (!), not_eq в качестве (!=).
Рассмотрим следующий пример работы логических операторов (результат представлен на рис. 10):
i < j
i <= j
i != j
!(a && b) равно значению ИСТИНА а || b равно значению ИСТИНА
Process exited after 0.9435 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис. 10. Результат работы логических операторов
ttinclude <iostream>
using namespace std,
int main()
{
int i, j;
bool a, b;
i = 10;
j = n;
if(i < j) cout« "\t" « "i < j\n";
if(i <= j) cout « H\t" « "i <= j\n";
if(i != j} cout« "\t" « "i 1= j\n"-
if(i == j) cout « "\t" « "Это не выполняется!\п";
if(i >= j) cout « "\t" « "Это не выполняется !\n";
if(i > j) cout« "\t" « "Это не выполняется !\n";
a = true;
b = false;
ifla && b) cout« "\t" « "Это не выполняется !\n"; if(!(a && b)) cout« "\t" « "!(a && b) раБж значению ИСТИНА\п";
if(a 11 b) cout « "\t" « "a 11 b равно значению ИСТИНА\п";
return 0;
)
Оператор равенства
Оператор равенства (==) является одним из наиболее сложных понятий на этапе обучения, так как имеется внешне похожий на него оператор присвоения (=). Начинающие программисты часто путают между собой эти два оператора.
Синтаксис оператора равенства следующий:
операнд! == операнд2
Значение оператора является истинным, если оба операнда совпадают.
Значение оператора является истинным, если оба операнда совпадают. Например:
Этапы создания программы
double Ras = 15;
double Dwa = 8; (Ras == Dwa!
Оператор равенства является бинарным (двухместным) и левоассоциативным. Оператор равенства (==) является логическим оператором и отвечает на вопрос: «Так ли это? Да или нет?» Применяется в логических операторах выбора или цикла. Оператор присваивания (=) не отвечает ни на какой вопрос и является директивой, приказом.
Оператор равенства (=-) можно ассоциировать с вопросом (?), тогда как оператор присваивания (=) — с восклицанием (!) или утверждением. Все вышеперечисленные операторы пишутся без разделения символов пробелом. Рассмотрим это на конкретном примере (результат - на рис. 11):
Введите свой вариант числа: 41 Вы не угадали.
а=31567
Process exited after 4.645 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис. 11. Применение оператора равенства
include <iostream>
ftinclude <cstdhb>
^include <ctime>
using namespace std,
int main()
{
srand(time;NULL));
int a;
int b;
a = rand(); генерирование случайного чист
cout« "Введите свой вариант числа:
cin » Ь:
if b =- а;
cout« "Вы угадали.\п"
else
cout « "Вы не угадалиДп";
cout« "а=" « а;
return 0;
}
Описание функций rand(), srand() и time() мы рассмотрим далее.
Операторы отношения
Операторы отношения сведены
в следующую таблицу:
Таблица 11
Операторы отношения
Оператор	Операция	Пример
|с	Не равно	АВ1= ВС
<	Меньше чем	ZENA1 < ZENA2
>	Больше чем	RAS > DWA
<=	Меньше или равно	K0L1 <= Ко13
>=	Больше или равно	ZYX >= XZY
Операторы отношения возвращают одно из двух значений: true или false.
Этапы создания программы
Переменная а будет выводить результат сравнения переменных а и Ь. Значения true или false можно по-другому обозначить как 0 и 1. В данном примере а > Ь, поэтому переменная d будет равна 1, т. е. true.
#incluae <iostream> using namespace std; int main()
{
int a = 40;
int b = 8;
int c;
int d
c = a / 5 + b;
d = a >= b
cout« "Переменная c=: " « c «"\n";
cout« d, return D.
Ответ:
Переменная c=: 16
1
1 — это true, так как 40 > 8
В другом примере мы изменим строку отношения:
d = а <= Ь;
В результате переменная d будет равна 0, т. е. false.
Операторы ввода-вывода библиотеки iostream.h
Для применения клавиатуры используется объект cin, т. е. объект «клавиатура». Рассмотрим следующий пример. В нем объявляется строка (string) с именем name. Здесь же строке name присваивается пустое значение, так как имя мы будем вводить с клавиатуры в ходе выполнения программы.
Подробно рассмотрим ход выполнения программы в функции main:
•	cout « — вывод строки, следующей за угловыми скобками;
•	cin » — ввод строки с клавиатуры ПК;
•	cout « — продолжение вывода строки.
В обращении «Здравствуйте, » после запятой введен пробел, чтобы обращение к человеку и имя человека не слились вместе.
Оператор endl или специальный символ \п используется для прерывания строки текста. Это означает, что строка заканчивается и следующий текст выводится на консоль, начиная с новой строки.
На новой строке консоли выводится текстовая строка «Здравствуйте, » и после этого выводится строка, введенная с клавиатуры. Этот массив может содержать или не содержать троку символов, заканчивающуюся 0. Он используется только для получения общего количества символов в строке.
Этапы создания
5
2 т с.
^include <iostream>
^include <string>
using namespace std;
string name="";
int main()
{
cout« "Как тебя зовут? \n";
cm » name;
cout« endl « "Здравствуйте, " « name;
return 0;
}
Вместо оператора endl можно использовать специальный символ \п, заключенный
в кавычки, например:
cout« "\п" « "Здравствуйте," « name « "\п";
сО
Использование манипуляторов вывода
Возможность управлять вводом-выводом в C++ обеспечивают манипуляторы, форматирующие функции-члены и флаги. Манипуляторы, форматирующие функции и флаги, выполняют одну и ту же задачу — задают определенный формат ввода-вывода информации в потоках. Ввод-вывод на консоль и с консоли в C++ осуществляется с помощью операторов cin и cout соответственно. Это означает, что манипуляторы форматирования используются совместно с операторами ввода-вывода cin и cout. Различие между манипуляторами, функциями форматирования и флагами заключается в способе их применения.
Форматирование с помощью манипуляторов
Манипуляторы — это особый тип объектов, которые управляют потоком ввода-вывода и форматируют информацию, передаваемую в этот поток. Манипуляторы дополняют возможности ввода-вывода. Большинство манипуляторов создают аналогичные возможности, что и функции с флагами форматирования. В одних случаях проще использовать флаги форматирования и функции, а в других — удобнее использовать манипуляторы форматирования. По этой причине C++ предоставляет множество возможностей форматирования ввода и вывода. В табл. 12 показаны основные манипуляторы форматирования C++.
5
05 CL
L_
О CL
Этапы создания
В начале программы для манипуляторов (с setw и до последнего манипулятора из табл. 12) подключите директиву:
ttinclude <iomanip>
Так как для всех манипуляторов используется оператор вывода cout, то для всех манипуляторов подключите директиву:
ttinclude <iostream>
Таблица 12
Манипуляторы форматирования в C++
Манипулятор	Назначение	Пример	Результат
endl	Переход на новую строку при выводе	cout « “Proverka:" « endl « "obrazovanie-saratov.ru",	Proverka: obrazovanie-saratov.ru
boolalpha	Вывод логических величин в текстовом виде (true, false)	bool !og_true = 1; cout « boolalpha « log_true « endl;	true
		или	
		bool )og_true = 200;	
		cout« boolalpha « log_true « endl;	
noboolalpha	Вывод логических величин в числовом виде (true, false)	bool log_true = true; cout « noboolalpha « log_irue « endl;	1
oct	Вывод величин в восьмеричной системе счисления	int value = 777; cout « oct « value « endl;	1411
dec	Вывод величин в десятичной системе счисления (по умолчанию)	int value = 999; cout « dec « value « endl;	999
hex	Вывод величин в шестнадцатеричной системе счисления	mt value = 999; cout « hex « value « endl;	37
Манипулятор	Назначение	Пример	Результат
showbase	Выводить индикатор основания системы счисления	mt value = 999; cout « showbase « hex « value « endl;	0x3e7
noshowbase	Не выводить индикатоо основания системы счисления (по умолчанию)	int value = 998, cout« noshowbase « hex « value « endl;	3eS
uppercase	В шестнадцатеричной системе счисления использовать буквы верхнего регистра (по умолчанию установлены буквы нижнего регистра)	int value = 255; cout« uppercase « hex « value « endl;	3DB
nouppercase	В шестнадцатеричной системе счисления использовать буквы нижнею регистра (по умолчанию)	int value = 987; cout« nouppercase « hex « value « endl;	3db
showpos	Выводить знак плюс для положительных чисел	int value = 998, cout« showpos « value « endl;	+998
noshowpos	Не выводить знак плюс для положительных чисел (по умолчанию)	int value = 998; cout« noshowpos « value « endl;	998
scientific	Вывод чисел с плавающей точкой в экспоненциальной форме	double value = 7890 135; cout« scientific « value « endl;	7 890135e+0C3
fixed	Вывод чисел с плавающей точкой в фиксированной форме (по умолчанию)	double value = 1024.165678; cout « fixed « va ue « endl;	7890.135678
5 £ 05 Q_ L_ О Q_
Этапы создания
Манипулятор	Назначение	Пример	Результат
setw(int number)	Установить ширину поля, где number — количество позиций, символов (выравнивание по умолчанию — по правой границе), Манипулятор с параметром	cout « setw(30) « "obrazovanie-saratov ru" « endl;	obrazovanie-saratov. ru (перед именем, сайта 8 пробелов)
right	Выравнивание по правой границе (по умолчанию) Сначала необходимо установись ширину поля (должна быть большей, чем длина выводимой строки)	cout « setw(30) « right « "obrazovanie-saratov.ru" « endl;	obrazovanie-saratov. ru (перед именем сайта S пробелов)
left	Выравнивание по левой границе, Сначала необходимо установить ширину поля (должна быть заведомо большей, чем длина выводимой строки)	cout « setw(30) « left « "obrazovanie-saratov.ru" « endl;	obrazovanie saratov.ru (после имени сайта должно быть 8 пробелов, но в Dev-C++ они не выделяются)
setprecision (int count)	Задает количество знаков после запятой, где count — количество знаков после десятичной точки	double value = 1234.56789; cout « fixed « setprecision(2) « value « endl;	1234 57 1234.5G8
		cout « fixed « setprecision(3) « value « endl;	
setfill(int symbol)	Установить символ заполнителя слева. Если ширина поля больше, чем выводимая величина (включая десятичный знак), то свободные места поля будут наполняться символом заполнителя symbol	oouble value = 1234.56789; cout « setfill('O') « setw(10) « value « endl;	0001234.57
Форматирование с помощью функций-членов и флагов
Возможность управлять вводом-выводом в C++ обеспечивают манипуляторы, форматирующие функции-члены и флаги. Все они выполняют одну и ту же задачу — задают определенный формат ввода-вывода информации в потоках.
Доступ к функциям осуществляется через операцию «точка», в круглых скобках передается аргумент. Аргумент функции fill() может передаваться в виде символа, заключенного в одинарные кавычки, или в виде числа (необходимо указать код символа).
Флаги форматирования позволяют включить или выключить один из параметров ввода-вывода. Для установки флага ввода-вывода необходимо вызвать функцию setf(); если необходимо отключить флаг вывода, то необходимо вызвать функцию unsetf().
Если при вводе-выводе необходимо установить (сбросить) несколько флагов, то можно воспользоваться поразрядной логической операцией | (означающей «или»),
В табл. 13 подробно описаны основные флаги форматирования, а также показаны примеры использования флагов.
При работе с флагами в начале программы объявляется директива:
ftinclude <ios>
Так как для всех манипулят оров используется оператор вывод cout, то для всех манипуляторов подключите директиву:
ttinclude <iostream>
5
га
О_
L_
О CL
Этапы создания
гм 00
Таблица 13
Флаги форматирования в C++
Флаг	Назначение	Пример	Результат
boolalpha	Вывод логических величин в текстовом виде (true, false)	cout.setf(ios:: boolalpha); bool log_false = 0, iog_true = 1; cout « log_false « endl	false true
		« log_true « endl;	
oct	Ввод-вывод величин в восэмеоичной системе счисления (сначала снимаем флаг dec, затем устанавливаем флаг oct)	cout.unsetf(ios : dec); cout.setf(ios:: oct); int value; cin » value; cout « value « endl;	ввод: 1234 5678 вывод: 57060516
doc	Ввод вывод величин в десятичной системе счисления (флаг установлен по умолчанию)	cout.setf(ios:: dec); int value = 123456; cout « value « endl;	123456
hex	Ввод-вывод величин в шестнадцатеричной системе счисления (сначала сбрасывается флаг dec, затем устанавливается флаг hex)	cout.unsetf(ios.: dec); cout setf(ios . hex), int value; cin » value; cout « value « endl;	ввод: 123456789 вывод:75bcdl5
showbase	Выводить индикатор основания системы счисления	cout.unsetf(ios:: dec); cout.setf(ios:: oct | ios:: showbase); int value; cin » value; cout « value « endl;	ввод: 123456789 вывод: 0726746425
Флаг	Назначение	Пример	Результат
uppercase	В шестнадцатеричной системе счисления использовать буквы верхнего pei истра (по умолчанию установлены буквы нижнего регистра)	cout.unsetf(ios:: dec); cout.setf(ios:: hex I ios:: uppercase); int value, cin » value; cout « value « endl;	ввод: 123456789 вывод: 75BCD15
showpos	Вывод знака плюс для положительных чисел	cout.setf(ios:: showpos); int value = 123456; cout « value « endl;	+123456
scientific	Вывод чисел с плавающей точкой в экспоненциальной форме	cout.setf(ios:. scientific); double value = 12345.6789; cout « value « endl;	1.234568e+0C4
fixed	Вывод чисел с плавающей точкой в фиксированной форме (по умолчанию)	double value = 123456.7891; cout.setf(ios:: fixed);	123И56.79 123456.789
		cout « setprecision(2) « value « en.dl;	
		cout « setprecision(3) « value « endl;	
right	Выравнивание по правой границе (по умолчанию). Сначала необходимо установить ширину поля (должна быть заведомо большей, чем длина выводимой строки)	cout.width(30); cout « obrazovanie-saratcv.ru" « endl;	obrazovanie-saratov. ru (перед именем сайта 8 пробелов)
left	Выравнивание по левой । ранице. Сначала необходимо установить ширину поля (должна быть заведомо большей, чем длина выводимой строки).	coutsetffios:: left); cout.width(3(J); cout « obrazovanie-saratov.ru" « endl;	obrazovanie-saratov.ru (после имени сайта должно быть 8 пробелов, но в Dev-C++ они не выделяются)
5
5
оо
Стандартные математические и строковые функции
Библиотека математических функций math.h
Стандартные математические функции предназначены для выполнения наиболее часто встречающихся операций, таких как вычисление математических, тригонометрических, статистических и других действий, — например, извлечение корня, возведение в степень, преобразование типов данных и т. д.
Многие функции в языках программирования С и C++ повторяют друг друга и выполняют аналогичные действия, хотя существует некоторое расхождение в наборах стандартных функций этих языков.
Библиотека math.h определяет набор функций для выполнения общих математических операций и преобразований (табл. 14). Для функционирования библиотеки math.h подключите ее в области объявлений директив и файлов:
ttinclude <rnath.h> или
ttinclude <cmath.h>
Последний вариант может вызвать ошибку (например, в Dev-C++), тогда нужно использовать имя math.h.
Таблица 14
Функции библиотеки math.h
Имя	Описание
abs	Возвращает абсолютную величину целого числа
acos	Арккосинус, возвращает значение в радианах
acosh	Гиперболический арккосинус
asm	Арксинус, возвращает значение в радианах
asinh	Гиперболический арксинус
atari	Арктангенс, возвращает значение в радианах
atan2	Арктангенс с двумя параметрами
atanh	Гиперболический ареатангенс
cbrt	Кубический корень
ceil	Округление до ближайшего большего целого числа
copysign(x, y)	Возвращает величину, абсолютное значение которой равно х, но знак которой соответствует знаку у
cos	Косинус угла, задаваемого в радианах
cosh	Гиперболический косинус
erf	Функция ошибок
erfc	Дополнительная функция ошибок
exp	Вычисление экспоненты
exp2(x)	Значение числа 2, возведенного в степень х, — 2х
expml(x)	Значение функции ex — 1 (число Эйлера)
tabs	Абсолютная величина (числа с плавающей точкоЙ)
fdim(x, y)	Вычисление положительной разницы между х и у, fmax(x - у, 0)
floor	Округление до ближайшего меньшего целого числа
СЛ (л
£ га О_ L_ О Q.
Этапы создания
Имя	Описание
fma(x, у, z)	Значение функции (x * у) + z
fmax(x, у)	Наибольшее значение среди х и у
fmin(x, у)	Наименьшее значение среди х и у
fmod	Вычисление остатка отделения нацело для чисел с плавающей точкой
frexp	Разбивает число с плавающей тонкой на мантиссу и показатель степени
hypot(x, у)	Гипотенуза, sqrt(x2 + у2)
ilogb	Экспонента числа с плавающей точкой, конвертированная в int
Idexp	Умножение числа с плавающей точкой на целую степень двух
Igamma	Натуральный логарифм абсолютного значения гамма-функции
llrint	Округление до ближайшею целого (возврашэет long long)
llround	Округление до ближайшего целого в направлении от 0 (возвращает long long)
log	Натуральный логарифм
loglO	Логарифм по основанию 10
loglp(x)	Натуральный логарифм 1 + х
log?	Логарифм по основанию 2
logb	Целочисленная часть логарифма х по основанию 2
Irint	Округление до ближайшего целого (возвращает long)
Iround	Округление до ближайшего целого в направлении от 0 (возвращает long)
modf(x, p)	Извлекает целую и дробную части (с учетом знака) из числа с плавающей точкой
nan(s)	Возвращает нечисловое значение 'Not a Number'
Имя
Описание
nearbyint	Округление аргумента до целого значения в формате числа с плавающей точкой
nextafler(x, у)	Следующее ближайшее представимое для х (по направлению к у)
nexttoward(x, у)	Тс же, что и nextafrer, нс у имеет тип long double
pow(x, у)	Результат возведения х в степень у, — ху
remainderfx, у)	Вычисляет остаток от деления согласно стандарту IEC 60559
remquo(x, у, р)	Тс же, что и remainder, но сохраняет коэффициент по указателю р (как int)
rint	Округление до целого (возвращает int) с вызовом ошибки inexact, если результат отличается от аргумента
round	Округление до целого (возвращает double)
round	Математическое скругление
sin	Синус угла, задаваемого в радианах
sinh	Гиперболический синус
sqrt	Квадратный корень
tan	Тангенс угла, задаваемою в радианах
tanh	Гиперболический тангенс
tgamma	Гамма-функция
trunc	Отбрасывание дробной части
5
то о_
L_ о CL
Этапы создания
При объявлении функции укажите ее прототип: идентификатор типа результата, название функции и список аргументов. Названия аргументов можно не указывать, нужен только их тип. Функцию стоит объявить до того, как она впервые вызывается.
00
00
Математических функций много, поэтому рассмотрим только несколько стандартных функции, которые могут дать представление об остальных.
Корень квадратный sqrt. Синтаксис описания этой функции следующий:
double sqrt(double х);
И тип функции, и тип аргумента являются числом с плавающей запятой двойной точности double. Для использования этой функции необходимо подключить библиотеку math.h в начале модуля реализации:
ttincluae <math.h>
В качестве аргумента используется не только число с типом double, но и любое число с любым типом, просто это число в процессе вычисления будет преобразовано в тин double. Например, если в качестве аргумента объявить целое число, то оно будет преобразовано в число с плавающей запятой. Рассмотрим пример:
ttinclude <iostream>
^include <cstdlib>
^include <math.h>
using namespace std:
int main()
{
int a = 25;
int b = 5;
double c;
c = sqrtfa * b);
cout« "Переменная c=:" « c, return 0;
}
При изучении многих других стандартных функций можно заметить, что способы работы с ними не отличаются от способов работы с рассмотренной функцией.
В них может быть два или три аргумента, но принцип работы остается тем же.
Функция fmod. Функция fmod — остаток от деления х / у, синтаксис которой описан так:
double fmod(double х, double у);
В этой функции определяется остаток от деления первого числа на второе. Но результат этот не совсем то, что вы ожидаете. Если разделить, например, 5 на 2, то остаток будет не 0,5, как может показаться сначала, а 1. Действительно, целое число раз можно разделить только на 2, а 2 х 2 = 4. Поэтому остаток и будет 1. Здесь в качестве аргументов можно также передать число любого типа, главное, чтобы это было число:
ttinclude <math.h> double tmod(x, у); double x;
double y;
Описание. Функция fmod вычисляет остаток от деления х на у с плавающей точкой, где х = iy + f; i — целое; f имеет тот же знак, что х.
Абсолютное значение х меньше, чем абсолютное значение у.
Возвращаемое значение. Функция fmod возвращает остаток с плавающей точкой. Если у равно 0, функция возвращает 0.
Этапы создания программы
Знак минус относится к числу, а не к символам, поэтому он окрашен в фиолетовый цвет, а не в красный.
Пример:
^include <math.h> double х, у, z;
х = -10.0;
У = 3.0;
z = fmodfx. у);
Функция frexp. Синтаксис:
^include <math.h>
double frextlx, expptrj;
double x;
int *expptr;
Описание. Функция frexp разрывает значение с плавающей точкой х на мантиссу m и экспоненту п, так что абсолютное значение m больше или равно 0,5 и меньше 10 и х равен т, умноженную на 2 в степени п. Левое значение экспоненты п хранится в расположении, указанном по expptr.
Возвращаемое значение. Функция frext возвращает мантиссу гл. Если х равен 0, функция возвращает 0 для мантиссы и экспоненты. Возвращаемого значения в случае ошибки нет. (См. также Idex, modf.)
Пример:
^include <math.h> double x, у;
int n;
x = 16.4;
у = frexp(x.- &n);
Функция hypot. Синтаксис:
tfinclude <math.h> double hypot(x, y);
double x, y;
Описание. Функция hypot вычисляет длину гипотенузы прямоугольного треугольника с заданной длиной двух сторон х и у. Вызов hypot эквивалентен следующему:
sqrt(x * х + у * у);
Возвращаемое значение. Функция hypot возвращает длину гипотенузы.
В случае переполнения результата hypot устанавливает еггпо в ERANGE и возвращает значение HUGE (см. Приложение 4).
Пример:
ttinclude <math.h> double х, у, z;
х = 3.0;
у = 4.0;
z = hypot(x, у);
П"Гипо1енуза=%2.1Лп", z);
На выходе:
Гипотенуза = 5.0
Г>1 ст>
Функция Idcxp. Синтаксис:
//include <math.h>
double Idextix, exp);
double x;
int *exp:
Описание. Функция Idexp возвращает x, умноженный па 2 в степени ехр.
В случае переполнения результата функция возвращает +HUGE или-HUGE (в зависимости от знака х) и устанавливает errno в ERANGE (см. Приложение 4).
Пример:
//include <math.h> double х, у;
int р;
х= 1.5;
р = 5;
у = Idехр(х, р),
Преобразование строк в числа Для преобразования строк в числа необходимо подключать директивы:
//include <string> //include <cstdlib>
Стандартные функции, применяемые для преобразования чисел и строк, делятся на две большие группы. Первая группа включает функции, появившиеся в языке С и переданные в язык C++ или разработанные в языке C++.
Необходимость в строчных функциях возникает при диалоге пользователя со средой визуального программирования (например, Visual C++). Пользователь может ввести информацию в компоненты управления только в виде строки.
Например, данные вводятся в элемент «Текстовая строка». Если строка предназначена для числового расчета, то ее нужно преобразовать в число. Так как внутреннее представление информации находится в кодированном виде, то в этот вид и нужно преобразовать строку. После преобразования строки в число программа может производить с ним математические или логические действия. После того как эти действия выполнены, необходимо вернуть пользователю результат расчета (если это нужно). Полученное число необходимо вернуть в виде строки для восприятия полученного результата с помощью зрения. То есть нужно преобразовать число в строку.
Преобразование типов данных осуществляется так же, как и в рассмотренных выше функциях, — по различным исходным основным типам. Для этого целое число или число с плавающей запятой преобразуется в строку, и, соответственно, наоборот: строки — в целое число или в число с плавающей запятой.
Функция преобразования строки в целое число называется atoi. Ее синтаксис следующий:
int atoi(char stringin]);
о Uj
Здесь char — тип данных (строка), string — имя строки, в кавычках (текстовая константа).
Несмотря на некоторую сложность синтаксиса описания, функция atoi очень проста: она преобразует строку string в число. Например:
ttindude <iostream> ^include <string> ^include <cstdlib> using namespace std, int main()
{
int i;
int j;
char stroka[7] = "123456";
i = atoi(stroka); 2 345f j = i + ICO;
cout« i « "\n";
cout«j;
return 0;
}
Здесь char — тип данных (строка), string имя строки, в кавычках (как и положено, текст строки, или, правильнее сказать, текстовая константа).
Символьные строки состоят из набора символьных констант, заключенных в двойные кавычки. При объявлении строкового массива необходимо учитывать наличие в конце строки нуль-терминатора и отводить под него дополнительный байт. Поэтому на строковый массив из шести символов необходимо отводить семь символов (6 символов + 1 нуль-терминатор).
Результатом преобразования будет программный код представления данного числа. Только с числом можно производить расчеты, только это число можно использовать в математических и логических выражениях.
Переменная i предназначена только для одной цели: показать, что строка была преобразована в число и с ним можно выполнять математические операции.
Оператор cout является предопределенным объектом класса ostream и используется для печати данных на стандартном устройстве вывода.
Оператор cout с использованием пространства имен — это декларативная область, внутри которой что-то определено. В этом случае cout определяется в пространстве имен std. То есть cout указывает, что cout определен в пространстве имен std, в противном случае следует использовать определение cout, которое не определено в пространстве имен std.
Для преобразования строки в длинное целое число используется функция atol, которая имеет следующий прототип:
long int atol(const char string[n]);
Функция возвращает целое число, в которое преобразована строка string, например:
long int i;
char stroka[7] = "123456"; i = atol(stroka);
Для преобразования строки в число типа double используется функция atof, которая имеет следующий прототип:
double atofjehar string[n]);
Этапы создания программы
Декларацию о пространстве имен лучше все-таки указывать.
В случае успешного завершения эта функция возвращает число типа double, в которое преобразована строка string. Например:
ttindude <iostream>
^include <string>
^include <cstdlib>
int mam()
{
double i;
double j,
char string[8] = "123.456“;
i = atof(string); 123.456
j = i + 100.987;
std cout« i « "\n";
std cout«j;
return 0;
}
В итоге будет 123.456 и 224.443.
Обратите внимание: в последнем примере не была объявлена декларация об единстве имен. Строка
using namespace std,
была пропущена Поэтому перед cout каждый раз приходилось писать std:: cout, т. е. указывать, что cout определен в пространстве имен std.
Форматирование программного текста
При вводе программного текста обратите внимание на цветовое решение текста и фона. Например, директивы препроцессора окрашиваются зеленым, буквы и идентификаторы — черным, ключевые слова выделяются полужирным, комментарий — голубым цветом, а символы — красным. Это необходимо для того, чтобы программист по цвету текста, операторов и так далее быстрее понял, где он мог ошибиться, и исправил ошибку.
Для знакомства с цветовым решением выполните команду Сервис => Параметры редактора. Перейдите на вкладку Синтаксис. В списке под вкладкой Общие перечислены все стили редактора. Выделяйте по очереди различные стили и знакомьтесь с цветовым решением данного стиля. Изменять цветовое решение стиля настоятельно не рекомендуется, но если приложение Dev-C++ установлено на вашем собственном компьютере, то в списках Текст и Фон для эксперимента — можно, но лучше потом вернуть все на место.
Здесь же приведены оптимальные цветовые схемы.
5 го о. и. о о_ Перейдите на вкладку Общие. Обратите внимание, что в опции Режим вставки установлен флажок. Если его сбросить, то включается режим замены, при котором каждый введенный символ программы заменяется на вводимый с клавиатуры, что может быть опасным. Включить такой режим можно случайно, например, нажав символ Insert (на ноутбуке — Fn + Insert). Понять, что программа переведена в режим замены, очень просто: в режиме вставки курсор имеет вид вертикальной линии, а при режиме замены или забое — вид блока. Виды курсоров при вставке и при забое также определены на вкладке Общие.
Но умолчанию текст программы вводится выровненным влево. Это неудобно при работе с циклами, ветвлениями и программными блоками. Чтобы программа сама отформатировала созданный текст, перед началом создания программы выполните команду AStyle => Format Current Style.
Комментарии
Комментарии нужны для описания назначения или действий программиста, чтобы вспомнить потом свои действия и рассуждения по созданию приложения. Если не сделать этого, то потом трудно вспомнить о назначении многих переменных или операций в приложении. Кроме того, нужно учитывать, что над одним приложением могут работать несколько человек, и разбираться в чужих действиях без подробного описания очень трудно.
Комхментарии в C++ оформляются двумя способами:
1) однострочный, начинается с символа И и заканчивается на этой же строке, никакой специальный знак в конце строки не ставится. Например:
double Summa;
2) многострочный (одна строка — эго частный случай многострочной), начинается с Л и заканчивается */. Например:
double SummaZechOtis;
О
или:
double Itogo:
Этапы создания программы
Все, что находится после И или между /* */, программа будет считать комментарием и в программный код при компиляции включать не будет.
Не будет считаться ошибкой комментарий такого содержания:
double ZenaOpt;
Казалось бы, здесь ошибка, так как указано сразу несколько видов комментария.
Но никакой ошибки здесь нет: игнорируется все, что находится после первой пары знаков /7, в том числе и знаки внутреннего комментария, - - программа считает, что это тоже текст комментария, и даже не анализирует его. Если ввести Н между /* */ или написать: //////////, то это тоже не будет считаться ошибкой.
Заключение
•	Язык программирования С-ы- — это высокоуровневый компилируемый, статически типизированный язык программирования общего назначения, который подходит для создания широкого спектра приложений.
•	В алфавит языка входят: прописные латинские буквы А-Z, строчные латинские буквы a-z, арабские цифры 0-9, символ подчеркивания (_), пробельные символы, знаки пунктуации и специальные символы.
•	Имя, или идентификатор, — это последовательность букв и цифр, начинающаяся с буквы и нс являющаяся ключевым словом.
•	Наиболее популярными специальными символами являются новая строка \п и горизонтальная табуляция \t.
•	Программный код состоит из нескольких связанных между собой частей: директив препроцессора и подключаемых файлов из библиотек, глобальных переменных и объявляемых функций, функции main()
с исполняемым кодом и команды return.
•	Для создания исполняемого файла из исходного кода на C++ выполняется три этапа:
•	I) препроцессор обрабатывает все директивы препроцессора, такие как #include, заменяя их в тексте программы на реальный программный код из указанных заголовочных файлов;
•	2) компилятор обрабатывает каждый файл исходного кода, создавая из него объектный файл, содержащий машинный код (если код разделен
101
5 £
го
Q_
0Z
на несколько файлов исходного кода,
для каждого файла создается свой объектный файл);
102
•	3) компоновщик (линковщик) объединяет все объектные файлы в одну исполняемую программу.
•	К простым типам данных относятся:
int (целое)
short int (короткое целое)
long int (длинное целое)
float (число с плавающей запятой)
double (число с плавающей запятой двойной точности)
long double (длинное числе с плавающей запятой двойной точности)
char (символьное)
boc-i (логическое)
•	Имена переменных могут начинаться с буквы латинского алфавита или символа подчеркивания (_).
•	Константы бывают символическими и именованными.
•	Операции делятся на унарные и бинарные: унарная операция — это операция с одним операндом; бинарная операция — это операция с двумя операндами.
•	К оператору И относятся && и and.
•	К оператору ИЛИ относятся || и or.
•	К оператору отрицания относятся
! и not. Оператор not_eq можно использовать в качестве != (не равно).
• Оператор равенства (==) сравнивает левый и правый операнды (равны ли они друг другу).
Программы разветвляющейся структуры
104 Понятие алгоритма
105 Линейные и разветвляющиеся алгоритмы
106 Условный оператор if
108 Правила вычисления логических выражений
111 Оператор выбора switch
113 Заключение
104
Понятие алгоритма
Алгоритм — это набор правил или инструкций, которые определяют последовательность действий для решения определенной задачи. Инструкции могут выполняться параллельно в любом порядке, если это возможно для данного исполнителя.
Существует два вида алгоритмов: вычислительные и управляющие. Вычислительный алгоритм преобразует входные данные в выходные для выполнения вычислений функции. По завершении вычислений вычислительный алгоритм завершает свою работу. Управляющие алгоритмы, напротив, осуществляют необходимые управляющие действия над объектом в определенный момент или в ответ на внешнее событие. В отличие от вычислительного алгоритма, управляющий алгоритм может продолжать работать бесконечно.
Линейные
и разветвляющиеся алгоритмы
Линейный алгоритм представляет собой последовательное выполнение операций, где каждая операция выполняется после предыдущей. Он включает команды присваивания, ввода, вывода и вызова вспомогательных алгоритмов. Алгоритмы с разветвленной структурой используются, когда необходимо выполнить одно из двух действий в зависимости от определенного условия.
105
Программы разветвляющейся структуры
Условный оператор if
Для выполнения многих задач необходимо действовать в зависимости от определенных условий. Часто приходится выбирать между несколькими вариантами в соответствии с поставленными целями. Для определения того, какой вариант использовать для расчетов, программа должна выбрать один из нескольких предложенных вариантов. Для этого существуют операторы выбора; if, if и else, switch.
Оператор if является самым широко используемым. Синтаксис оператора if следующий:
if(ycnoBne) выполняемый_оператор;
Если операт оров несколько, то описание меняется:
if(ycnoBne) {
выполняемые_операторы;
}
Синтаксическое различие сразу
заметно: если оператор один, то в конце конструкции ставится точка с запятой; если операторов несколько, то они заключаются в фигурные скобки (точка с запятой вне фигурных скобок не ставится, но внутри фигурных скобок точка с запятой ставится после каждого оператора). Для одного оператора также допускается использовать фигурные скобки. Кроме того, одиночный выполняемый оператор можно писать не в той же строке, что и оператор if, а в следующей. В предыдущих примерах
(при изучении различных логических операторов) мы делали именно так. В этом случае система программирования читает строку с оператором if и следующую строку с одиночным выполняемым оператором как одну строку.
Условие выполняется только при истинности условия, заключенного в круглые скобки. Если условие ложно, то оно не выполняется. Если не предусмотрено никаких действий для обработки данных при ложном условии, то такие данные игнорируются.
Текст инструкции if выполняется, если значение выражения ненулевое.
107
си
Q_ i—
О CL
<
Правила вычисления логических выражений
Условием может быть любое выражение:
iffSumma > Zatraty)...
if(ltogo + Summa =< 100)...
ifUgoI == 45)... и т. д.
В последнем примере приведено применение оператора равенства (==). Данное выражение означает, что условие выполняется, если переменная Ugol равна 45. При прочих значениях переменной Ugol условие не выполняется. В качестве оператора может быть использовано любое выражение — от арифметических операций:
108
А >= В;
до построения целых комбинаций, например:
iffVipolnemePlana >= 100%)
{
Zarplata * Premia;
}
Оператор if выполняет только истинные условия, в то время как ложные условия не выполняются. Это может привести к случайному пропуску ситуаций, когда необходимо обработать выражение при ложном значении оператора. Чтобы этого избежать, используются операторы выбора if и else. Они представляют собой развитие оператора if. Если оператор if определяется как: «Если, то: (действия)», то операторы if и else определяются как: «Если, то: (действия), иначе: (действия)». Синтаксис этих операторов следующий:
if(ycjiODne) оператор i; else оператор];
Если операторов несколько, то синтаксис оператора выбора (или, по-другому, оператора ветвления) следующий:
if(ycnoBne){ операторы;} else{ операторы,}
Все операторы, которые нс заключены в фигурные скобки после оператора else, не включаются в логический блок и будут выполняться в любом случае.
Операторы if выполняются только в случае истинности логического условия, заключенно: о в круглые скобки. Если это утверждение ложно, то выполняются операторы else (если они есть).
Операторы if и else могут быть вложенными, т. е. входить друг в друга. Часто приходится выбирать не из двух, а из большего числа вариантов, например из трех, тогда операторы могут вкладываться друг в друга:
iffycnoBMe 1){ операторы 1;} else if(yczioei-ie 2){ операторы 2;} else{ операторы 3;}
109
Бее операторы, не заключенные в фигурные скобки после else, не включаются в логический блок и выполняются в любом случае.
Операторы if выполняются только в случае ист инности логического условия в круглых скобках. Если это утверждение ложно, то выполняются операторы else.
Программы разветвляющейся структуры
С помощью скобок можно создавать самые разные конструкции, например выбор минимального значения:
Переменная GF=11
Process exited after 0.2767 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис. 12. Выбор минимального значения
!Яусловие 1){
iflycnoBne 2) оператор!, else оператор 2;}
Рассмотрим пример:
^include <iostream> using namespace std. int main(){ double AB = 22; double CD = 11;
double GF;
if(AB > CD) GF = CD: else GF = AB'
cout« "\n\t" « "Переменная GF=" « GF « "\n"; return 0;}
Оператор выбора switch
Оператор switch — оператор множественного выбора. Для операторов if и else рассматривались случаи, когда существует не один или два выбора, а больше. При использовании вложенных конструкций if и else возможны разного рода ошибки из-за невнимательности будущего программиста. Оператор switch позволяет избежать таких ошибок и упростить обработку выбора. Формат записи оператора switch следующий: switch (выражение) { case значение 1: оператор 1 break, // необязательно
case значение п: оператор п break; // необязательно default: оператор;//необязательнс }
Здесь значение 1,... значение п — выражения, которые сравниваются. Оператор break завершает работу оператора switch. Если ни одно сравнение нс вычисляется в true, т. е. ни одно выражение не отвечает условиям поиска, то действие переходит к default; а при его отсутствии — выходит за пределы оператора множественного выхода. Например, операторы if, if и else из всего множества вариантов выбора выбирают только одно выражение, так как сама конструкция этих операторов предусматривает однозначность толкования. Оператор же switch может выбирать сразу несколько вариантов одновременно. Поэтому использовать этот оператор надо с очень большой осторожностью.
Программы разветвляющейся
Рассмотрим пример:
^include <iostream>
using namespace std:
int main()
{
int i, d;
cout« "Задайте целое значение j\n";
cin »i;
switch(i){
case 1 case 2 case 3 cout« " i=" « i « "\n";
case 4 cout« "i = " « i «" i * 2 + 5 = " « i * 2 + 5 « "\n";
d = 10 * i - 3;
cout « " d = " « d « "\n";
break.
case 5 cout« "i = 5 \n";
break
default cout « "Значение i меньше 1 или больше 5
Ответ:
Задайте целое значение i
3
i = 3
i = 3 i * 2 + 5 = 11
d = 27
Заключение
•	Алгоритм — это набор правил или инструкций, которые определяют последовательность действий для решения определенной задачи.
•	Существует два вида алгоритмов: вычислительные и управляющие: вычислительный алгориТхМ преобразует входные данные в выходные для выполнения вычислений функции; управляющие алгоритмы осуществляют управляющие действия над объектом в определенный момент или в ответ на внешнее событие.
Линейный алгоритм представляет собой последовательное выполнение операций, где каждая операция выполняется после предыдущей.
•	Алгоритмы с разветвленной структурой используются, когда необходимо выполнить одно из двух действий в зависимости от определенного условия. Для ветвления существуют операторы выбора if, if и else, switch
•	Оператор if выполняет только истинные условия, в то время как ложные условия не выполняются.
113
•	Условие выполняется только при истинности условия, заключенного в круглые скобки. Если условие ложно, то оно не выполняется. Если не предусмотрено никаких действий для обработки данных при ложном условии, то такие данные игнорируются.
•	Операторы выбора if и else предназначены для обработки истинных и ложных условий.
•	Оператор switch — оператор множественного выбора.
Программы циклической структуры
116 Операторы цикла языка C++
117 Операторы цикла с предусловием (while)
119 Операторы цикла с постусловием (do while)
121 Операторы цикла с заданным числом повторений (for)
123 Операторы передачи управления (break, return, continue)
124 Заключение
Программы циклической
Операторы цикла языка C++
Цикл в С+н---это конструкция, которая
дает возможность многократно исполнять определенный фрагмент кода до тех пор, пока не будет выполнено указанное условие.
Операторы цикла с предусловием (while)
Цикл while будет выполняться до тех пор, пока заданное логическое условие будет истинным. Если условие никогда не станет истинным, то операторы внутри цикла не будут выполнены ни разу.
Синтаксис цикла while следующий:
while(ycrosMe)
{
операторы,
}
В качестве примера с использованием цикла while можно привести такой:
int Prim = 0;
while(Prim < 99)
{
Prim ++;
}
В данном случае анализ начинается с О и заканчивается 99, Всего в этом примере цикл будет включать 100 заходов. Анализ можно начинать не с 0, а с любого числа, например с -100. Тогда число циклов будет другое. Если переменная Prim не будет инициализирована (т. е. не будет задано стартовое значение), то начало цикла начнется со случайной величины.
В качестве числа циклов необходимо задавать целое число, а не действительное.
Цикл while выполняет определенный набор действий, пока выполняется определенное условие. Если указанное в скобках условие неверно, то тело цикла не выполнится ни разу. Если тело цикла не влияет на условие, то цикл может выполняться бесконечно.
Если при работе с операторами цикла используются инкременты и декременты, то нужно помнить о постфиксном и префиксном их преобразовании. Переход от инкрементного значения цикла к декрементному и результаты анализа могут отличаться друг от друга в зависимости от того, какой вариант перебора чисел ряда был выбран.
Рассмотрим пример:
^include <iostream> using namespace std; int main()
{
int AA = 0.
int BB = 0;
while(AA <= 95) {
BB = BB +AA:
AA++;
}
cout« "Значение AA=" « AA « "\n";
return 0;
}
Так как отсчет начинается с 0
и продолжается до 95, то результатом будет число 96.
Операторы цикла с постусловием (do while)
Цикл do while является промежуточным вариантом между циклом while и оператором выбора if. Если цикл while не использовался ни разу, т. е. если условие пи разу не было выполнено, то цикл do while будет исполнен хотя бы один раз даже в гом случае, если условие не будет выполнено ни разу. Его синтаксис следующий: do { операторы;
} while(yc ло вие);
Если после оператора while не ставится точка с запятой ни в самом операторе, ни после фигурных скобок, то в операторе do while точка с запятой ставится после оператора while. Оператор do без оператора while не используется. Такая попытка закончится сообщением компилятора.
119
В этом операторе сначала выполняются операторы do и только после этого начинается анализ в операторе while. Это может быть нужно, например, при работе с играми, где в этом операторе можно
Оператор Со без оператора while не используется.
Программы циклической структурь
выбирать вариант развития событий и т. д. Например:
ttindude <iostream>
using namespace std;
int rnainQ
{
int i = {10};
do
{
cout« i « "\t";
i—;
}
whilefi > 0);
}
Ответ:
10	9	8	7	6	5	4
3	2	1
о гч
Операторы цикла с заданным числом повторений (for)
Оператор for — один из самых популярных операторов организации циклов, т. е. перебора ряда чисел. Его синтаксис следующий:
Тог(инии,иализация_начального_значения, логическое условие; выражение) { операторы;
}
Оператор for состоит из трех аргументов. Первая часть определяет начальное значение цикла. Это значение должно быть указано в явном виде, например:
int i = 0;
Объявление переменной i внутри цикла допустимо, хотя также возможно объявить ее вне цикла for. Эго необходимо для определения области видимости переменной. Если переменная объявлена внутри оператора, то ее видимость ограничивается этим оператором. Если переменная объявлена вне цикла, может возникнуть необходимость явно указать область видимости. При этом возможно встретить переменную с таким же именем в другом цикле или части программы, поэтому важно явно указывать, какую переменную мы используем. Ни после оператора for, ни после фигурных скобок точка с запятой не ставится. Точка с запятой ставится внутри выполняемых операторов for, отделяя каждую строку.
Пример использования циклов for и while:
ttinclude <iostream>
using namespace std;
int main(){
// переменной i может быть объявлена при
инициализации
for(int i = 0. i < 5; i++){
cout« i;
}
cout« "\n";
объявлена вне цикла for
int i;
for(i = 0. i < 3: i++){
cout«i;
}
cout << '\n"
инициализирована до цикла while
i = 0;
while(i < 4){
cout« i++;
}
Ответ:
01234
012
0123
Операторы передачи управления (break, return, continue)
Оператор break осуществляет выход из тела цикла for, while, do while или оператора switch, в котором он появился. При этом управление передается на первый оператор после цикла. Оператор не может обеспечить выход сразу из двух или более вложенных циклов.
Оператор return завершает выполнение функции, в которой он задан, и возвращает управление в вызывающую функцию. Управление передается в вызывающую функцию в точку, непосредственно следующую за вызовом. Если return находится в функции main(), го он вызывает прерывание выполнения программы.
Оператор continue осуществляет переход на точку сразу за последним оператором тела цикла без выхода из цикла, так что итерации в цикле будут продолжаться. Пример вывода четных чисел:
forfint num = 0, num < 100; num += 2){ cout« num « "\п";
}
Когда num становится нечетным, выражение num += 2 получает значение 1 и выполняется оператор, который передает управление на следующую итерацию цикла for, не выполняя вывода.
Программы циклической структуры
Заключение
Цикл в C++ — это конструкция, которая дает возможность многократно исполнять определенный фрагмент кода до тех пор, пока не будет выполнено указанное условие.
Цикл while будет выполняться до тех пор, пока заданное логическое условие будет истинным.
В качестве числа циклов необходимо задавать целое число, а не действительное.
Цикл do while является промежуточным вариантом между циклом while и оператором выбора if. Если цикл while не использовался ни разу, г. е. если условие ни разу не было выполнено, то цикл do while будет исполнен хотя бы один раз даже в том случае, если условие не будет выполнено ни разу.
Цикл for в C++ предоставляет возможность создавать циклы, которые будут выполняться заданное количество раз.
Оператор for состоит из трех аргументов: стартового числа, конечного числа, значения приращения.
Оператор break осуществляет выход из тела цикла for, while, do while или оператора switch, в котором он появился.
Оператор return завершает выполнение функции, в которой он задан, и возвращает управление в вызывающую функцию.
Оператор continue осуществляет переход на точку сразу за последним оператором тела цикла без выхода из цикла, так что итерации в цикле будут продолжаться.
Обработка одномерных массивов
126 Объявление, инициализация, обработка одномерных массивов
130 Алгоритмы нахождения минимального и максимального значения
132 Сумма элементов массива
134 Произведение элементов массива
134 Удаление элементов массива
135 Удаление положительных элементов массива
137 Алгоритмы сортировки
137 Метод пузырька
139 Метод прямого выбора
141 Заключение
Обработка одномерных массивов
йй
<£>
ГМ
В C++ могут быть только одномерные массивы В массиве могут храниться не только переменные, но и объекты
Объявление, инициализация, обработка одномерных массивов
Массив — это набор элементов определенного типа, каждый из которых имеет свой порядковый номер, называемый индексом. Индекс — это число, указывающее на конкретный элемент, к которому обращается программа.
В C++ могут быть только одномерные массивы. Объявление одномерного массива имеет синтаксис:
Тип_Данных Имя_Массива[число элементов],
Нумерация элементов в массиве начинается с 0, поэтому номер последнего элемента не совпадает с числом элементов в массиве на единицу:
double Аггау[1ОО],
В даннОхМ примере создается массив из ста элементов. Последний элемент массива будет иметь индекс 99, так как индексация начинается с 0. Массив можно объявить сразу с инициализацией, т. е. присвоением значений каждому элементу:
int а[15] = {1, —2, —7, 3, -1, 0, —9, — 12, —1, 32, 56, 46,14, 34, —3};
В следующем примере компилятор сам определит размер одномерного массива (размер массива можно не указывать только при его инициализации; при обычном объявлении массива обязательно нужно указывать размер массива):
int аЦ = {1, —2, —7, 3, —1, 0, —9, —12, —1, 32, 56, 46, 14, 34, —3};
В массиве могут храниться не только переменные, но и объекты. В этом случае массив объявляется так же, но типом будет имя класса:
MyClass Objectum[110J;
Создадим для примера массив из целых переменных, в котором будет семь элементов:
int ArZeny[7] = {20, 4, 9, 87, 16, 266, 51};
Инициализация значений для простоты осуществляется здесь же. Тогда, если нам потребуется рассчитать сумму значений всех элементов массива, мы можем это сделать с помощью оператора цикла for, перебирая все элементы, начиная с заданного:
int Itogo = ArZeny[0];
for(int i = 1; i < 7; i++)
Itogo = Itogo + ArZeny[i];
В данном примере сумме Itogo присваиваем первое значение элемента массива, который имеет индекс 0. Первоначально сумма Itogo становится равной 20. Поэтому цикл надо начинать не с элемента 0, а с элемента 1. Если задать проход цикла начиная с элемента 0, то значение элемента 0 дважды будет включено в сумму и в расчете будет сделана ошибка, которая не будет обнаружена компилятором. Если последний (последние) элемент равен 0, то его можно не задавать в явном виде — программа и так будет знать, что инициализирована только разность элементов п — т, где п — число элементов массива, ат — число инициализированных элементов. В этом случае оставшиеся элементы справа будут автоматически инициализированы нулем.
Обработка одномерных массивов
Пример — инициализация элементов массива из консоли (рис. 13):
1
з
8
-2
4
0
-1
2
7
99
Array[0]= 1
Аггау[1]= 3
Array[2j= 8
Аггау[3]= -2
Аггау[4]= 4
Аггау[5]= 0
Array[6]= -1
Array[7]= 2
Array[8]= 7
Array[9j= 99
Для продолжения нажмите любую клавишу . . .
Рис. 13. Ввод элементов массива на консоль и вывод их с консоли
^include <iostream> using namespace std; int main(){ int i, ArrayflO];
for(i = 0: i < 10; i++){
cout« "\t";
cin » Ar ray (i);}
for(i = 0; i < 10; i++){
cout« "\t" « "Array[” « i « "]= " « Array[i] « "\n";}
systemf’pause");
return 0;}
В учебных целях создать массив и заполнить его можно случайными числами. В C++ для этого есть специальные функции rand() и srand(). Они находятся в библиотечном файле cstdlik поэтому, чтобы их применять в программе, необходимо подключить этот библиотечный файл: #include <cstdlib> или ^include <stdlib.h>.
Функция rand() генерирует случайные числа, но при каждом запуске программы будут получаться одинаковые числа, что нас устроить не может. Чтобы генерировать действительно случайные числа при повторных запусках программы, необходимо применить функцию srand(). Функция srand() передаст в функцию time() параметр NULL:
srand(time(NULL});
Это позволит функции rand() каждый раз генерировать действительно случайные числа. Для использования time() необходимо подключить библиотечный файл ctime (#include <ctime> или #include time.h), например:
^include <iostream>
^include <cstdlib>
ttmclude <ctime> using namespace std;
int main{)
{
int arr[5] = {};
srand(time(NULL});
forfint i = 0; i < 5; i++)
{
arr[ij = ra nd();
cout« "\t" « arr[i] « endl,
}
return 0;
}
129
В заыих примерах будут доугие случайные числа.
Ответ:
733G 15742
10318
31124
9099
Обработка одномерных массивов
Алгоритмы нахождения минимального и максимального значения
Максимальный элемент массива — это элемент, который имеет самое большое числовое значение, а минимальный элемент массива — это элемент, имеющий самое меньшее значение.
Для выбора максимального и минимального значения в массиве в языке C++ предлагается несколько способов.
Прежде всего, исходный массив можно заполнить непосредственно внутри программы, например: int arr[] = {-3, -2, 0, -1,1, 2, 3};
С помощью оператора cin (cin » arr[i];), где размер массива i нужно указать заранее.
С помощью генератора случайных чисел.
Рассмотрим поиск максимального и минимального значения массива (рис. 14):
^include <iostream>
using namespace std;
int main()
{
const int N = 10;
int ArraylN];
forflnt i = 0; i < N i++)
{
cout« "Введите элемент массива [" « i « "] = cin » Array[i];
}
int Max = Array[O], Min = Array[O];
forjint i = 1; I < N; i++)
{
if(Max < Arrayfi])
Max = Array [i];
if|Mm > Arrayfi])
Mm = Array [i];
}
cout« "Максимальный элемент массиеа= " « Max
« "\n";
cout« "Минимальный элемент массива= " « Min
« "\n";
return 0;
}
Введите элемент	массива	[0]	=	7
Введите элемент	массива	[1]	=	0
Введите элемент	массива	[2]	=	3
Введите элемент	массива	[3]	=	-8
Введите элемент	массива	[4]	=	9
Введите элемент	массива	[5]	=	-1
Введите элемент	массива	[6]	=	4
Введите элемент	массива	[7]	=	2
Введите элемент	массива	[8]	=	1
Введите элемент	массива	[9]	=	6
Максимальный элемент массива= 9
Минимальный элемент массива= -8
131
Process exited after 28.19 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис. 14. Поиск минимума и максимума в одномерном массиве
Если в массиве максимумов и минимумов не одно, а например, два числа 9 или два числа -8, то программа возьмет любое из них.
Обработка одномерных массивов
Сумма элементов масси ва
Первый пример:
flindude <iostream>
using namespace std:
int main{)
{
int arr[] = {1, 2, 3, 4, 5};
int n - sizeof(arr) / sizeoffarr[O|);
int sum - 0;
for(int i = 0; i < n; i++)
sum += arrfi];
cout« "Сумма:" « sum « endl;
return 0;
}
Оператор int n = sizeof(arr) / sizeof(arr [0]); рассчитывает размер массива.
Расчет суммы элементов массива с помощью функции accumulateO
Функция accumulateO в C++ вычисляет сумму числовых значений в определенном диапазоне. Ее также можно использовать для эффективной итерации и вычисления суммы массива.
Общий синтаксис функции accumulateO выглядит следующим образом:
accumulate(startRange, endRange, initialvalue, customPredicateDcfinithn)
Функция accumulateO в C++ обычно принимает три обязательных параметра:
• start Range — указывает позицию в массиве, с которой мы хотим начать операцию;
•	endRange — указывает позицию в массиве, до которой мы хотим выполнить конкретную операцию (число элементов в массиве);
•	initialvalue — начальное значение, которое присваивается функции accumulate!).
©
©
Например, в случае вычисления суммы начальное значение initialvalue инициируется как 0, потому что это естественное стартовое значение для сложения; или, если хотим, мы также можем придать ему другое значение. Затем процесс сложения будет выполняться над этим значением в качестве начального.
В функции accumulate!) есть необязательный параметр customPredicateDefinition. В нем можно указать тип операции, которую необходимо выполнить.
Пример с функцией accumulate!):
Во всех
примерах сумма инициализиоуется со значением 0, так как после объявления переменной она получает случайное числовое значение.
133
^include <iostream>
^include <numeric> using namespace std, int main!)
{
int sum = 0:
int a[j = {7, 3, 5,10};
cout« "Результат сложения: \n";
cout« accumulate^, a + 4, sum);
return 0;
}
Обрабстка одномерных массигов
Обратите внимание на инициализацию переменней proiz, в которой хранится произведение массива. — она получает значение 1, на которое потом будут умножаться элементы массива. Если эту переменную
Произведение элементов массива
Пример-
ttinclude <iostream>
using namespace std;
int rnain()
{
int proiz = 1;
int a110] = {1, 2, 3, 4, 5, 6, 7, 8, % 10};
for(lnt i = 0; i < a[10]; i++)
{
proiz *- a[i];
}
cout« proiz;
}
не инициализировать или инициализировать 0, то в итоге будет 0.
Удаление элементов массива
го
Пример (рис. 15):
Введите элементы массива агг 9
а
-4
1°
9
й
43 |91 29 I67 56 ‘93 .94 195
2Ь
[Редактированный массив агг
9	0	-4	6	56	43	91	29	67	56	93	94	95	87	25
Process exited after 49.72 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис. 15. Заполнение исходного массива и удаление пяти элементов
ttinclude <iostream>
using namespace std, int main()
{
int i, j, к - 20,
double arrfk];
cout« "Введите элементы массива arr \n";
for(i - 0; i < k; i++)
cin » arr[i];
for(j = 1; j <= 5; j++) // удалить 5 элементов
for(i = 4; i < к — j; i++)// удалить <
номером 4
a rr[i] = arr[i + 1];
cout« "Редактированный массив arr \n";
элементов массива
for(i = 0; i < к — 5; i++)
cout« arr| i] « "\t";
cout« "\n";
return 0;
}
Элемент под номером 4 является пятым элементом в массиве, так как нумерация элементов в массиве начинается с 0.
135
Удаление положительных
элементов массива
Пример:
^include <iostream> using namespace std, int main()
{
int i, j, k;
cout« "k =";
cin » k,
double arr[k];
cout« "Введите элементы массива arr \n";
for(i = 0, i < k; i++)
cin » arr[i];
for(i = 0; i < k)
Обработка одномерных массивов
if(arrli] > 0)
{
for(j = i; j < k — 1; j++)
arr[j] = arr[j + 1];
k—;
}
else i++; /
cout« "Редактированный массив arr \n";
for(i = 0; i < k; i++)
cout« arr[i] « " \t";
cout« endl;
return 0;
}
Ответ:
k = 6
Введите элементы массива arr
5
-7 0
-1
1
2
Редактированный массив arr
-7	0	-1
Алгоритмы сортировки
Метод пузырька
Сортировка пузырьком — это простейший алгоритм сортировки, который заключается в повторном проходе по элементам массива. На каждом проходе сравниваются два соседних элемента, и если они стоят
в неправильном порядке, то они меняются местами. Внешний цикл продолжается до тех пор, пока массив не будет отсортирован. Таким образом, внешний цикл контролирует количество проходов внутреннего цикла. Если на следующем проходе не происходит обмена элементов, то массив считается отсортированным.
Функция сортировки bubbieSort в качестве параметров принимает указатель на массив (int arrForSort[]) и его размер (const int size), например (рис. 16):
агг[0]= 3
arr[l]= 7
arr[2]= 1
arr[3]= 9
arr[4]= 4
агг[Б]» 5
arr[6]= 6
arr[7]= 0
Массив после сортировки:
01345679
Process exited after 0.2916 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис. 16. Сортировка методом пузырька
138
Обработка одномерных массивов
arrForSort[j -1] = arrForSort[j]; arrFnrSort[j] = buff:
и
Psj' CD
un
psj’ Ф
ttinclude <iostream> using namespace std; void bubbleSort(int arrForSort[], const int size),
Вложенный цикл проходит от четвертого элемента до первого, находит с помощью if самое меньшее значение, сравнивая соседние пары элементов, и поднимает его в нулевую ячейку массива.
Далее значение i увеличивается на 1 и внутренний цикл перебирает элементы от четвертого до второго. Таким образом он поднимает самое меньшее значение из оставшихся в первую ячейку и т. д.
Метод прямого выбора
Сортировка выбором является самым простым алгоритмом сортировки.
Алгоритм сортировки выбором находит наименьший или наибольший элемент в исходном массиве в зависимости от порядка сортировки (возрастание или убывание). Если массив сортируется по возрастанию, выбирается наименьший элемент исходного массива; если массив сортируется по убыванию, выбирается наибольший элемент. Например (рис. 17):
139
исходный список элементов для сортировки 3	0	-3	99	55	66	77	-4	33	44
Сортированный список элементов -4	-3	0	3	33	44	55	66	77	99
Число проходов, необходимых для сортировки массива: 10
Process exited after 0.3454 seconds with return value 0
Для продолжения нажмите любую клавишу . . .
Рис. 17. Сортировка методом прямого выбора
Обработка одномерных массивов
^include <iostream>
using namespace std.
int findSmallest(int[], int);
int main()
{
int arr[10] = {3, 0, —3, 99, 55, 66, 77, -4, 33, 44};
int pos, temp pass = 0;
cout« "\n\t Исходный список элементов для сортировки \n\t";
forfint i = 0; i < 10; i++)
{
cout« arr[i] « "\t";
}
for(int i = 0; i < 10; i++)
{
pos = findSmallestiarr, i);
temp = arr[i];
arr [i] = arrfpos);
arr[pos] = tempj
pass++;
}
cout« "\n\t Сортированный список элементов
\n\t";
for(int i = 0; i < 10; i++)
{
cout« arr[i] « "\t";
}
cout « "\n\t Число проходов, необходимых для сиртирозки массива;" « pass;
return 0;
}
int findSmaIlestfint arr[], int i)
{
int min, position, j;
min = arr[i];
position = i;
for(j = i + 1; j < 10; j++)
{
if(arr|j] < min)
{
min = arr[j);
position = j;
return position,
Заключение
•	Массив — это набор элементов определенного типа, каждый из которых имеет свой порядковый номер, называемый индексом.
•	Индекс в массиве — это число, указывающее на конкретный элемент, к которому обращается программа. Индексация в массиве начинается с 0.
•	Инициализация, т. е. заполнение массива данными, возможна в тексте программы, с клавиатуры (заполнение случайными числами).
•	В массиве можно хранить данные любых типов и объектов.
•	Наиболее популярными операциями с массивами являются поиск минимального и максимального числа, суммирование и перемножение чисел в массиве «сортировка данных».
•	С символьными данными можно выполнять такие же операции, что и с числами, так как каждый символ имеет числовой код.
•	Если в массиве максимумов и минимумов не одно, а например, два числа 9 или два числа -8, то программа возьмет любое из них.
•	Функция accumulateO в С++ вычисляет сумму числовых значений в определенном диапазоне. Ее также можно использовать для эффективной итерации и вычисления суммы массива.
•	Сортировка пузырьком заключается в том, что в каждом проходе сравниваются два соседних элемента, и если они стоят в неправильном порядке, то они меняются местами. Внешний цикл продолжается до тех пор, пока массив не будет отсортирован.
Обработка одномерных массивов
• Алгоритм сортировки выбором находит наименьший или наибольший элемент
в исходном массиве в зависимости от порядка сортировки (возрастание или убывание). Если массив сортируется по возрастанию, выбирается наименьший элемент исходного массива; если массив сортируется но убыванию, выбирается наибольший элемент.
Обработка двумерных массивов
144
146
Объявление и инициализация двумерных массивов различных типов
Ввод-вывод элементов двумерного массива
149
Заключение
143
Обработка двумерных массивов
ГОМ
Объявление и инициализация двумерных массивов различных типов
В языке C++ существуют только одномерные массивы в соответствии с его синтаксисОхМ. Элементами двумерного массива могут быть одномерные массивы. Двумерные массивы представляют собой массивы одномерных массивов и должны быть объявлены в программе следующим образом:
тип данных имя массива [размер!] [размер?];
где 7ип_данных — допустимый в C++ тип данных; имя_ массива — идентификатор, определяемый правилами языка; размер1 число строк; размер? — число столбцов.
В памяти компьютера матрицы располагаются в следующем порядке: сначала располагаются элементы первой строки, за ней — элементы второй, третьей и т. д. Двумерный массив (матрицу) можно объявить так:
тип имя_переменной[п][т];
где п — количество строк (от 0 до п — 1); m — количество столбцов (от 0 до m — 1).
Например:
double arr_2[2][5];
В каждой строке двумерного массива одинаковое число элементов. Не может быть в первой строке 10 элементов, а во второй — 9.
Обращаются к элементу матрицы, указывая последовательно в квадратных скобках соответствующие индексы. Например, агг_2[1][2] — элемент матрицы агг_2, находящийся в первой строке и во втором столбце.
Массиву, как и переменной, можно присвоить начальные значения в момент его описания.
Пример двумерного массива с целыми числами в две строки и пять столбцов'
int агг_2[2][5]
{
{1, 2, 3, 4, 5},
{6, 7, 8, 9,10}
};
Пример двумерного массива
с вещественными числами в три строки и шесть столбцов:
double arr_3[31[6j
{
{1.2, 2.7, 3.5, 4.9, 5.3, 6.4},
{6.1, 7.2, 8.3, 9.4, 10.5, 4.4},
{1.4, 2.3, 3.7, 4,5, 7.9, 5,0}
};
Если двумерный массив состоит из двух индексов, то трехмерный массив состоит из трех индексов: int arr_3[2][5][4]
145
Обработка двумерных массивов
Ввод-вывод элементов двумерного массива
Элементы двумерного массива располагаются в памяти компьютера в одну строку под индексами [ОНО], [0] [1], [0][2], [0] [3], [0][4], затем — вюрая строка под индексами [1JL0J, [1J[1J, [1] [2], [1][3], [1] [4]. Первая строка массива имеет индекс 0, поэтому во всех первых пяти парных индексах первый индекс указывает на первую строку, г. е. 0, так как отсчет начинается с 0. В следующих пяти парных индексах первый индекс указывает на вторую строку массива, т. е. 1. Во всех вторых индексах и первой, и второй строки отсчет выполняется с 0 до 4 (так как в нашем примере пять столбцов), например (рис. 18):
^include <iostream> using namespace std. int main() {
int Array[2][5]; cout« "\n"; cout« "\t" « "Элементы Array: " « "\t\n"; forfint i = 0; i < 2; ++i)
{
for(int j = 0; j < 5; ++j) {
cout« "\t";
cin » Array[i][j];}}
cout« "\t" « "Значения чисел:" « "\n"; for(int i = 0; i < 2; ++i)
{
forfint j = 0: j < 5; ++j) {
cout« "\t" « "Array [" « i « "][" «j « "]: " « Array[i][j]« "\n";
} } return 0;
Элементы Array:
1
б
8
-3
0
3
9
6
-2
5
Значения чисел:
Array [0][0]: 1
Array [0][1]: б
Array [0][2]: 8
Array [0][3]: -3
Array [0][4]: 0
Array [1][0]: 3
Array	9
Array [1][2]: б
Array [1][3]: -2
Array [1][4]: 5
Process exited after 22.78 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис. 18- Ввод и вывод элементов двумерного массива
В следующего примере элементы двумерного массива инициализируются непосредственно в программе.
Обратите внимание на следующую последовательность действий: сначала мы объявляем имя и размерность двумерного массива, затем используем знак «=» и после этого в фигурных скобках выполняем инициализацию каждой строки массива отдельно. Инициализация каждой строки тоже происходит в фигурных скобках, при этом каждая строка массива отделяется от другой запятой.
Обработка двумерных массивов
Инициализация каждой строки происходит в фигурных скобках, при этом каждая строка массива отделяется от другой запятой.
Пример вывода значений двумерного массива на консоль:
ttinclude <iostream> using namespace std; int rriain()
{
int arr_2[2][5] =
{
{1, 4, -5,0, -2},
{3, —4, —1, 0,1}
};
cout «arr_2[0][01« "
cout« arr _2[0][l] « "
cout« arr _2[0][2] « "
cout <<arr_2[0][3) « "
cout <<arr_2[0][4] « "
cout« "\n“;
cout« arr _2[l][0] « "
cout« art _2[1][1] « "
cout« arr _2[1][2] « "
cout« arr _2[1][3]« "
cout« arr _2[1][4] « "
cout« "\n";
return 0;
}
Ответ:
1, 4, -5, 0, -2 3,-4,-1, 0,1
Заключение
•	В языке C++ существуют только одномерные массивы.
•	Двумерные массивы представляют собой массивы одномерных массивов.
•	В памяти компьютера матрицы располагаются в следующем порядке: сначала располагаются элементы первой строки, за ней — элементы второй, третьей и т. д.
•	В каждой строке двумерного массива одинаковое число элементов. Не может быть в первой строке 10 элементов, а во второй — 9.
•	Обращаются к элементу матрицы, указывая последовательно в квадратных скобках соответствующие индексы.
•	Элементы двумерного массива располагаются в памяти компьютера в одну строку под индексами [0] [0], [0] [1], [0] [2], [0] [3], [0] [4], затем — вторая строка под индексами [1] [0], [1][ 1], [1] [2 , [1][3], [1] [4]. Первая строка массива имеет индекс 0, а вторая строка массива имеет индекс 1.
149
Создание пользовательских функций
152 Объявление и определение функций
157 Фактические и формальные параметры
160 Понятие прототипа функции
163 Вызов функции
166 Передача значений с использованием оператора return
169 Область действия и время жизни переменной
174 Заключение
Создание пользовательских функций

Объявление и определение функций
Функции в системе программирования могут быть разделены на две категории: пользовательские и стандартные. Пользовательские функции разрабатываются самим пользователем, в то время как стандартные функции поставляются вместе с системой. Вместе с системой поставляется обширный набор готовых функций различного назначения. В языках программирования С и C++ имеется более 700 функций, и их количество постоянно растет.
Многие функции очень похожи или выполняют аналогичные действия, предназначены для работы с различными типами данных. Например, функция abs используется для получения абсолютного значения числа и работает с целыми числовыми типами данных. А функции tabs и fabsl используются для получения абсолютного значения числа типа double и long double соответственно. Функция labs используется для получения абсолютного значения длинного целого числа типа long int. Если функцию abs применить к вещественным переменным, то будет отброшена дробная часть.
Пример.
^include <iostream>
^include <marh.h> using namespace std, int main()
{
int a = 20;
long b = 333333;
double c = 15.67;
float d = 4.6;
cout« abs(a) « "\t";
cout« absjb} « "\t";
cout« abs(c) « "\t";
cout« abstd) « "\n";
return D;
}
Ответ:
20; 333333; 15; 4
Такой результат нас, конечно, устроить не может, так как дробные части в некоторых переменных (с и d) были отброшены. Поэтому перепишем вывод для переменных b, с, d: cout« labs(b) « "\t"; cout« fabs(c) « "\t"; cout« fabs(d) « "\n";
Ответ:
20; 333333; 15.67; 4.6
Тем не менее нужно отметить, что не все стандартные библиотеки поставляются вместе со средой программирования. Например, в Dev-C++ не установлена очень важная и полезная библиотека graphics.h, в которой хранятся графические функции для рисования. Порядок установки этой библиотеки и настройки Dev-C++ для рисования подробно описаны в интернете1. Кроме того, имеется вариант Dev-Сы- под

Функция определяет действия, которые должна сделать программа. Функции позволяют выделить и назвать набор инструкций. А затем по этому присвоенному имени вызывать в различных частях программы столько раз, сколько нужно. Можно сказат ь, что функция — это именованный блок кода.
153
1 См., напр.: https://manaeff.ru/forum/viewtopic.php.
Создание пользовательских функций
названиехМ wxdevcpp 7.4.2, предназначенный для программирования и рисования на языке C++,
Язык C++ позволяет пользователям создавать собственные функции. Объявление функций не отличается от объявления переменных, за исключением указания аргументов в круглых скобках. Функция объявляется в начале модуля *.срр, где также объявляются глобальные переменные и определяется алгоритм ее расчета. Для завершения программной строки также используется точка с запятой:
Тип возвращаемого значения Имя функции (Список аргументов) { тело функции;
}
После объявления функции в первой строке точка с запятой отсутствует. За ней следует фигурная скобка, после которой содержится алгоритм вычисления функции. После закрывающей фигурной скобки точка с запятой тоже отсутствует. Вычисление может быть выполнено в одной или нескольких строках кода. Поскольку алгоритм находится внутри фигурных скобок, количество строк алгоритма вычисления не имеет значения. Программа не продолжит выполнение, пока не будет прочитан весь код между скобками. Поэтому все строки кода внутри скобок являются телом функции.
Каждая строка алгоритма функции заканчивается точкой с запятой. Одна строка может занимать несколько физических строк. Программа считывает все строки до точки с запятой. Физические строки до точки с запятой считаются одной программной строкой для анализа синтаксиса.
Если функция является возвращаемой, то необходимо использовать ключевое слово return, за которым следует формула расчета. Ключевое слово return возвращает результат выполнения функции.
В первом примере для двучленной функции запись будет выглядеть так:
return Tschislo 1+ Tschisl :2;
Во втором примере для трехчленной функции запись будет выглядеть так:
return Tschislol+ Tsch islo2+ Tschislo3;
Теперь мы можем записать определение для двучленной функции следующим образом:
В Iipoi рамме на языке C++ сразу автоматически запускается функция main. Никакие другие функции автоматически не выполняются. Их придется вызывать специально.
155
double SUMMAfdouble Tschislol, double Tschislo2)
{
return Tschislol+ Tschislo2;
}
Для трехчленной функции все то же самое, с добавлением Tschislo3 в аргументы функции и в return.
Создание пользовательских функций
Объявление функции можно совмещать с ее определением, тогда объявление функции игнорируется. Определение функции пишется вместо объявления в начале модуля *.срр. Если имеются обязательные объявления (директивы препроцессора, файлы с расширением *.h), то определение функции пишется под этими обязательными объявлениями. Например:
int SUMMA(double Fschislol, double Tschislo2);
Функции могут быть созданы для любой операции и содержать различные действия. Однако из-за сложности создания функций их имеет смысл разрабатывать только в тех случаях, когда они часто используются. После разработки не нужно повторно объявлять или переопределять функции. Вместо этого достаточно включить их в соответствующий файл с необходимыми объявлениями и определениями, т. е. подключить как библиотеку.
Фактические и формальные параметры
Для обмена данными между функциями в C++ используются следующие способы:
Л__
оО
•	оператор return;
•	глобальные переменные;
•	формальные и фактические параметры.
С помощью оператора return можно передать в вызывающую функцию единственный результат работы функции.
Глобальная переменная — это переменная, объявленная вне функций. Локальная переменная — это переменная, объявленная в функции, включая заголовок функции.
Переменные, указанные в заголовке функции, называются формальными параметрами, или параметрами функции. Формальные параметры — это параметры, которые принимают значение от функционального вызова. Они объявляются в списке параметров в начале описания функции. Список параметров определяет имена параметров и порядок, в котором они принимают значение при вызове функции. Формальные параметры могут быть входными или выходными. Входные параметры — это параметры, которые должны быть известны для вычисления в функции. Выходной параметр — это результат.
Создание пользовательских функций
Обратите внимание, что перед знаком рубля (р.) введен пробел, чтобы число и знак рубля не склеились.
Список параметров может содержать ноль или несколько идентификаторов, разделенных запятой. Даже если список пусгой, он должен быть заключен в круглые скобки. Переменные, передаваемые в функцию при ее вызове, называются фактическими параметрами. Фактические параметры (аргументы) функции указываются в круглых скобках после имени функции при ее вызове. Они представляют собой конкретные данные, которые должны быть переданы вызываемой функции, или переменные, в которые вызываемая функция передает результаты своих операций. Например:
^include <iostream> using namespace std.
double proiz(double x, double y)
{
return x * y;
}
int mainf)
{
double a = 10.5, b = 20.9, p: p = proizfa, b);
cout« "Функция proiz =" « p « " p.";
return D;
}
Ответ:
Функция proiz =219.45 p.
В данном примере формальные и фактические аргументы имеют разные имена, но имя функции у них одно (proiz). Алгоритм расчета (произведение аргументов) описан в прототипе функции, а при вызове функции proiz в функции main алгоритм не повторяется.
Чтобы передать массив в функцию, необходимо указать его имя в списке аргументов функции при ее вызове. Например, для вызова функции суммирования целочисленного массива arr из 50 элементов используется синтаксис:
sumfarr, 50);
Имя массива в C++ является константным указателем, значение которого — адрес первого элемента массива. Поэтому в вызове в функцию передается адрес массива. Массив всегда передается в функцию по ссылке. Формальный параметр функции для массива должен иметь синтаксис:
тип элементов имя[]
Пример:
ttinclude <iostream> using namespace std. void newarray(int arr[15]) {
foriint i = 0, i < 7; i++) a rr[i] = arr[i] + 7;
} int main() {
int arr[7] = {1, 2, 3, 4, 5, 6, 7};
ncwarray(arr);
forfint i = 0; i < 7; i++) cout« arr|i] « " return 0;
}
Функция newarray принимает массив arr. Назначение функции — расширить массив при необходимости до 15 элементов.
Ответ:
8	9	10	11	12	13	14
159
Создание пользовательских функций
Понятие прототипа функции
Прототип функции в C++ — это объявление функции без тела, но с указанием имени, количества аргументов, их типов и возвращаемого типа данных. Определение функции описывает ее конкретное поведение, в то время как прототип можно рассматривать как описание интерфейса функции, не раскрывая ее конкретной реализации.
В прот отипе имена аргументов являются необязательными, тем не менее необходимо указывать тип вместе со всеми модификаторами (например, указатель ли это или константный аргумент). Например:
int funkfint х);
Этот прототип объявляет функцию с именем funk, которая принимает один аргумент х целого типа (тип внутри скобок) и возвращает целое число (тип перед скобками). Определение функции может располагаться где угодно в программе, но объявление требуется только в случае ее использования. Необходимо обратить внимание на то, что, хотя функция объявлена, никаких конкретных действий с ней не предусмотрено.
Прототип имеет ту же форму, что и определение функции, за исключением того, что он завершается точкой с запятой сразу после закрывающей скобки и, следовательно, не имеет тела. В любом случае возвращаемый тип должен соответствовать возвращаемому типу, указанному в определении функции.
Прототипы функций могут применяться в следующих случаях.
Они определяют тип возвращаемого значения для функций, возвращающих типы, отличные от int. Хотя для функций, возвращающих значения типа int, прототипы не обязательны, использовать их рекомендуется.
Без полных прототипов выполняются стандартные преобразования, но не производится попытка сравнения типа или количества аргументов с количеством параметров.
Прототипы используются для инициализации указателей на функции до определения этих функций.
Список параметров используется для проверки соответствия аргументов в вызове функции и параметров в ее определении.
Прототип устанавливает атрибуты функции. После этого вызовы функций, предшествующие определению функции (или в других исходных файлах), можно проверять на несоответствие типов аргументов и возвращаемых типов. Например, если в прототипе указан описатель класса хранения static, необходимо также задать класс храпения static в определении функции.
После открывающей скобки и перед закрывающей скобкой пробел может устанавливаться, а может
и не устанавливаться, это безразлично.
Но стиль написания пробелов должен быть один.
161
Полные объявления параметров (int а) могут использоваться совместно с абстрактными деклараторами (int) в одном объявлении. Например, следующее объявление является допустимым:
int add(int a, int);
Создание пользовательских функций
Прототип может содержать как тип, так и идентификатор для каждого выражения, которое передается в качестве аргумента. Однако область действия таких идентификаторов распространяется только до конца объявления. Прототип также может отражать то, что число аргументов является переменным или что никакие аргументы не передаются. Без такого списка выявление несоответствий невозможно, поэтому компилятор не может создавать соответствующие диагностические сообщения.
Алгоритм работы прототипа функции следующий:
•	объявляется прототип функции;
•	указываются значения аргументов функции;
•	вызывается прототип функции с конкретным действием, например суммированием аргументов функции.
Пример:
ttinclude <iostream> using namespace std;
int Sum_num|int a, int b);
int rriain()
{
Sum_num(10, 20);
return 0;
}
int Sum_num(int a, int b)
{
cout« a + b, }
Ответ:
30
Вызов функции
Вызов функции состоит из имени функции и передаваемых аргументов. Это можно написать так:
SUMMA(132.25,14.64);
Имя функции указывается без типа данных в начале, так как функция уже была объявлена ранее. Повторное объявление этой же функции будет считаться ошибкой. Аргументы функции можно определить не только в теле программы, но и с помощью клавиатуры, используя оператор cin.
В конце строки с вызовом функции вводится точка с запятой. При вызове функции артументы получают конкретные значения. При анализе функции компилятор проверяет соответствие типа передаваемых данных требуемому типу. Если необходимо, выполняется преобразование типов. В приведенном примере функция имеет тип double, а аргументы могут иметь другой тип (каждый аргумент может иметь свой тип). В таком случае компилятор выполняет преобразование типов. Например, функцию можно объявить как:
int SUMMA(double Tschislol, double Tschislo2);
В этом примере аргументы функции имеют один тип, а сама функция — другой. Возвращаемое return число (в нашем примере тип обоих чисел double) преобразуется в целое число путем отбрасывания дробной части. Например:
Оф
163
return 100.25 + 200.64;
Создание пользовательских функций
СО^
Алгоритм расчета функции является необязательным. Оператор return можно вообще не указывать.
Полученное значение (300.89) возвращается как 300, так как SUMMA имеет тип int. Дробная часть отбрасывается, а не округляется. Если тины данных несовместимы, то при компиляции будет сгенерирована ошибка.
Если функция не имеет аргументов, то указывается функция без аргухментов или со словом void вместо аргументов, например:
void SUMMA(void);
void SUMМА{);
Обе записи идентичны.
Если функция ничего не возвращает, т. е. имеет тип void, то можно указать пустой оператор возврата:
return:
Как видно из этого примера, алгоритм расчета функции является необязательным. Оператор return можно вообще не указывать. При его отсутствии функция завершает работу, когда заканчивается ее код.
Рассмотрим два примера работы с функциями от начала до конца.
В первом примере мы создаем функцию сложения двух чисел. Наш пример будет выглядеть так:
Введите а
4
Введите b 15
Функция Funk=19
Process exited after 8.617 seconds with return value 0 Для продолжения нажмите любую клавишу . . .
Рис 19. Результат работы сЬунхции Funk
#include <iostream>
using namespace std;
double Funk(double A double B)
{
return A + B,
}
int main()
{
double a, b, y;
cout« "Введите a \n";
cin » a;
cout« "Введите b \n";
cin » b;
у = Funk(a, b);
cout« "Функция Funk=" « y;
return 0;
165
Создание пользовательских функций
Передача значений с использованием оператора return
В C++ нельзя пропустить оператор return, если функции имеют возвращаемый тип. Оператор return можно пропустить только для типа void.
Когда функция ничего не возвращает, используется возвращаемый тип void. Если в определении функции есть возвращаемый тип void, то внутри этой функции не должно быть оператора return (а если он все-таки имеется, то используется для других целей). Например:
ttinclude <iostream> using namespace std. void noreturnf) {
cout« "Оператора return в функции noreturn нет";
}
int main()
{
noreturn();
return 0;
}
Оператор return 0 относится к функции int main(), а не к функции noreturn.
Если внутри возвращаемого типа void есть оператор return, то он ничего не возвращает, а прерывает функцию. Его синтаксис следующий:
void noreturn() {
return:
}
Этот синтаксис используется в функции как оператор перехода, чтобы прервать поток выполнения функции и выйти из нее. Его можно рассматривать как альтернативу оператору break для использования в функциях. Обратите внимание, что оператор return установлен, а возвращаемого значения у него нет: include <iostream> using namespace std; void noreturn() { cout« "Оператор return прерывает функцию noreturn";
return;
}
int main()
{
noreturn();
return 0;
}
Но если оператор return попытается вернуть значение в функции возвращаемого типа void, это приведет к ошибкам.
Пример неправильной программы:
ftinciude <iostream> using namespace std. void noreturn() {
cout« "Оператор return в функции noreturn ничего не может возвратить";
return 100;
} int main() { noreturnf); return 0;
Если з определении функции есть возвращаемый тип void, то внутри этой функции не должно быть оператора return.
167
Создание пользовательских функций
Сообщение об ошибке:
In function 'void noreturn()':
[Error] return-statement with a value, in function returning 'void' [-fpermissive].
(В функции 'void noreturnQ':
[Ошибка] возвращает оператор co значением в функции, возвращающей 'void' [--fpermissive].)
Для методов, которые определяют возвращаемый тип, за оператором return должно сразу следовать возвращаемое значение этого указанного возвращаемого типа. Например:
^include <iostream> using namespace std; int sumfint a, int b)
{
int с - а т b;
return c;
int mainQ
{
int nl = 5;
int n2 = 50;
int s_num = suminl, n2);
cout « "Сумма итого= " « sjium;
return D.
Ответ:
Сумма итого= 55
Функция может возвращать только одно значение с помошью оператора return. Чтобы возвращать несколько значений, необходимо использовать указатели, структуры, классы и т. д.
Область действия и время жизни переменной
Переменная, или идентификатор, представляет собой именованную область памяти, где хранятся данные определенного типа. У переменной есть имя и значение. Имя используется для указания области памяти, где хранится значение. Значение переменной может быть изменено во время выполнения программы. Перед использованием переменной необходимо ее определить, так как это связано с выделением памяти под эту переменную.
Область видимости переменной определяет часть программы, где переменная может быть использована для доступа к связанной с ней области памяти. В зависимости от области видимости переменная может быть локальной или глобальной.
169
Переменная, определенная внутри блока, заключенного в фигурные скобки, называется локальной. Область ее действия ограничена от места определения до конца блока, включая все вложенные блоки. Локальными переменными также называются переменные, объявленные в функции main.
Переменная, определенная перед функцией main, считается глобальной, и ее область действия охватывает весь файл, в котором она определена, от места определения до конца файла.
Создание пользовательских функций
Правила области действия языка определяют, в какой части (частях) программы можно получить доступ к конкретному фрагменту кода, Идентификаторы, объявленные во внешнем блоке функции, имеют область действия функции. Доступ к ним возможен только в функции, в котооой они объявлены.
Пример:
#inciuae <iostream> using namespace std: int a = 100, b = 200; int main()
{
int a = 10, b = 20;
cout« "Сумма локальных= " « а к b « "\n"; cout« "Сумма глобальных^ " «: a +: b « "\n"; cout« "Сумма локально-глобальных= " « a +: a « "\n";
return 0 }
Ответ:
Сумма локальных= 30
Сумма глобальных= 300
Сумма локально-глобальных= 110
В данном примере мы специально усложнили задание: глобальные и локальные переменные объявлены с одинаковыми именами а и Ь, но с разными значениями. Для сложения локальных переменных никаких дополнительных операторов не нужно. Для сложения глобальных переменных перед каждой переменной устанавливался специальный оператор :: для того, чтобы объяснить программе, что будет использована глобальная переменная. Обратите внимание на строку:
cout« "Сумма локально-глобальных= " « а +:: а « "\п";
где выполняется сложение локальной и глобальной переменных с именем а. Причем никаких ошибок и конфликтов имен в программе не обнаружено.
В одной формуле можно использовать одновременно и локальные, и глобальные переменные, и даже с одним именем. Объявление области видимости с оператором :: называется неявным заданием области видимости. Класс памяти определяет время жизни и область видимости программного объекта (в частности, переменной). Если класс памяти не указан явным образом, он определяется компилятором исходя из контекста объявления.
Время жизни может быть постоянным (в течение выполнения программы) и временным (в течение выполнения блока). В большом приложении неявного задания областей видимости может оказаться недостаточно. Для таких случаев предусмотрено явное определение областей видимости переменных namespace с одинаковыми именами. Области видимости объявляются в начале модуля *.срр, в том месте, где мы объявляем глобальные переменные. Например:
Каждая область видимости должна быть заключена в фигурные скобки. После объявления каждой области видимости точка с запятой не ставится. Число областей видимости неограниченно.
namespace А{ int SDF = 100; }
namespace В{ int SDF = 200; }
Каждая область видимости должна быть заключена в фигурные скобки. После объявления каждой области видимости точка с запятой не ставится. Число областей видимости неограниченно. В каждой области видимости допускается не только объявлять переменные, но и писать любые программные коды, организовывать циклы, ветвление, расчеты и т. д.
Создание пользовательских функций
Одна область видимости может входить в другую область видимости, например:
namespace А{ int SDF = 100; namespace В{ int SDF = 200;
}
}
Чтобы перейти к конкретной области видимости и однозначно указать, какую переменную с одним и тем же именем необходимо использовать, ее необходимо вызвать с указанием имени области видимости.
Начиная с момента объявления области видимости переменная из этой области применяется до тех пор, пока:
1) или явно не будет объявлена другая область, в которой действует переменная с таким же именем, но с другим инициализированным значением,
2) или не покинет данный программный блок.
В последнем случае при всех равных условиях действует локальная переменная.
Рассмотрим пример:
ttinclude <iostream> using namespace std; namespace
int SDF = 100;
}
namespace B{ int SDF = 200; }
intC = A SDF + B:: SDF;
int main()
cout«А SDF«"\n"; cout « В . SDF « "\n"; cout« C;
return 0;
}
Обычно область
В нашем примере две глобальные переменные SDF из пространств А и В и одна локальная переменная С. Локальная переменная С является суммой двух глобальных переменных. Поэтому при суммировании (и при выводе на консоль) указываем, из какого пространства имен взята переменная SDF, так как в каждом пространстве имен эта переменная имеет разное значение.
На консоли будут выведены числа 100, 200 и 300.
Область видимости идентификатора определяет, где в программе можно получить доступ к памяти, связанной с этим идентификатором. Обычно область видимости совпадает с областью действия, за исключением случаев, когда переменные с одинаковыми именами определены во вложенных блоках. В таких случаях внешняя переменная во вложенном блоке включается в область видимости, но не является видимой.
видимости совпадает с областью действия, за исключением случаев, когда переменные с одинаковыми именами определены во вложенных блоках. В таких случаях внешняя переменная во вложенном блоке включается в область видимости, но не является видимой.
173
Если начальное значение переменных не указано явно, компилятор присваивает нулевое значение соответствующего типа глобальным и статическим переменным. Имена переменных должны быть уникальными в пределах их области видимости (например, в одном блоке не могут быть две переменные с одинаковыми именами).
Создание пользовательских функций
Заключение
•	Функции в системе программирования могут быть разделены на две категории: пользовательские и стандартные.
•	Пользовательские функции разрабатываются самим пользователем, в то время как стандартные функции поставляются вместе с системой.
•	Функция об ьявляется в начале модуля *.срр, где также объявляются глобальные переменные и определяется алгоритм ее расчета.
•	Если функция является возвращаемой, то необходимо использовать ключевое слово return, за которым следует формула расчета.
•	Объявление функции можно совмещать с ее определением, тогда объявление функции игнорируется.
•	Функции могут быть созданы для любой операции и содержать различные действия.
•	Глобальная переменная — это переменная, объявленная вне функций. Локальная переменная — это переменная, объявленная в функции, включая заголовок функции.
•	Переменные, указанные в заголовке функции, называются формальными параметрами, или параметрами функции.
•	Фактические параметры (аргументы) функции указываются в круглых скобках после имени функции при ее вызове. Они представляют собой конкретные данные, которые должны быть переданы вызываемой функции, или переменные, в которые вызываемая функция передает результаты своих операций.
•	Прототип функции в C++ — это объявление функции без тела, но с указанием имени, количества аргументов, их типов и возвращаемого типа данных.
•	В прототипе имена аргументов являются необязательными, но необходимо указывать тип вместе со всеми модификаторами.
•	Вызов функции состоит из имени функции и передаваемых аргументов.
•	Имя функции указывается без типа данных в начале, так как функция уже была объявлена ранее. Повторное объявление этой же функции будет считаться ошибкой. Аргументы функции можно определить не только в теле программы, но и с помощью клавиатуры, используя оператор cin.
•	Если в определении функции есть возвращаемый тип void, то внутри этой функции не должно быть оператора return. Если внутри возвращаемого типа void есть оператор return, то он ничего не возвращает, а прерывает функцию.
•	Для методов, которые определяют возвращаемый тип, за оператором return должно сразу следовать возвращаемое значение этого указанного возвращаемого типа.
•	Функция может возвращать только одно значение с помощью оператора return.
• Объя вление области видимости с оператором :: называется неявнььм заданием области видимости.
Области видимости объявляются с ключевым словом namespace.
Указатели и ссылки
178 Объявление указателей
181 Основные операции над указателями
181 Операции адресации и разыменования
184 Нулевой указатель (null)
187 Операции сравнения и логические операции
187 Математические действия с указателями
192 Присвоение указателю одного типа значения указателя другого типа
196 Особенности операций с указателями
199 Указатели на константы
201 Константный указатель
201 Константный указатель на константу
202 Средства использования динамической памяти. Операторы new и delete
204 Связь между указателями и массивами
206 Понятие ссылки
207 Виды ссылок
207 Передача ссылки в качестве параметра функции
210 Создание независимой ссылки
211 Использование ссылок для передачи значений из функции
213 Заключение
Объявление указателей
Указатели и ссылки используются при работе со сложными типами данных — массивами, классами.
Указатель — это переменная, которая хранит адрес памяти. Адрес памяти, хранимый указателем, показывает адрес другой переменной. Поэтому, если сложить все эти определения вместе, получается, что указатель указывает на переменную. То есть в C+ + указатель — это переменная, которая хранит адрес другой переменной.
В результате переменная PeremPerem указывает на адрес переменной Perem
Как и обычные переменные, указатели имеют тип данных. Например, указатель типа int может хранить адрес переменной типа int. Указатель типа double может хранить адрес переменной типа double. Понятие указателя является сложным в восприятии обучающегося.
Синтаксис объявления указателей можно представить так:
Тип_Переменной *Имя_Указателя,
Указатель необходимо привязать к оператору взятия адреса (&). После этого код будет выглядеть так:
int Perem;
int *PeremPerem = &Perem;
Когда в программе на C++ объявляется переменная, при инсталлировании программы ей выделяется некоторое пространство в памяти компьютера. Значение этой переменной сохраняется в назначенном месте.
Чтобы узнать в памяти компьютера место, где хранятся данные, C++ предоставляет оператор &, а этот оператор возвращает адрес, который занимает переменная. То есть, если abc — переменная, &abc возвращает адрес переменной. Еще раз: не значение, а адрес, по которому это значение хранится. Но можно с помощью адреса получить и значение, которое по этому адресу хранится.
Кроме термина указателя, используется еще один термин — оператор разыменовывайте (*)•
Мы объявили о создании указателя PeremPerem на переменную Perem. Дальше мы просто забываем о переменной Perem и начинаем работать с PeremPerem.
int Perem = 1041;
int *PeremPerem = &Perem; cout« *PeremPerem;
В этом коде мы выводим на экран не саму переменную, а указатель на нее, через оператор разыменовывания ^PeremPerem.
Пример:
ftinclude <iostream> using namespace std; int main()
{
int perem = 1041, int ’peremperem; peremperem = &perem; cout« "Значение perem равно = cout« perem « "\n";
cout« "Значение peremperem равно = ";
cout « peremperem « "\n"
cout« "Значение ’peremperem равно = ";
cout« *peremperem « "\n";
return 0;
Ответ:
Значение perem равно = 1041
Значение peremperem равно = 0x6ffel4
Значение *peremperem равно = 1041
В некоторых описаниях можно встретить развитие этих операторов — так называемый указатель на указатель, который можно представить так:
**PeremPeremPerem
Указатель *PeremPerenriPerem можно представить как другую переменную, для которой также можно создать указатель.
Оператор разыменовывания (*) стоит перед указателем, а объявление указателя стоит перед типом этой переменной и означает, что сейчас последует объявление указателя. Поэтому, несмотря на то, что внешне оба они обозначены одним символом (*), отличить
их легко.
Основные операции над указателями
Указатели поддерживают ряд операций: разыменование, присваивание, получение адреса указателя (&), получение значения по указа! елю, а также арифметические операции (присваивание, сложение с константой, вычитание, инкремент ++, декремент —, операции сравнения).
Операции адресации и разыменования
Пример:
^include <iostream> using namespace std;
int main()
{
int x = 3;
int *y = &x;
cout« x « "\n";
cout« у « "\n";
}
Ответ:
з
0x6ffel4
Указателю можно присвоить адрес объекта того же типа или значение другого указателя. Для получения адреса объекта используется операция &
int х{10};
int *ukaz{&x}; указатель ukaz хранит адрес
переменнойх
При этом указатель и переменная должны иметь один и тот же тип (в данном примере это тип целого int).
ИМ1/1ЯЭЭ И Ик/Э1Е£ЕМД
(N oo
Операция разыменования указателя представляет выражение в виде *имя указателя. Эта операция позволяет получить объект по адресу, который хранится в указателе. В данном примере мы присваиваем указателю ukaz значение переменной х. Выводим на консоль значение указателя ukaz и переменной х. Оба параметра равны 10. Далее мы присваиваем указателю ukaz значение 5, которое также присваивается переменной х. Например:
ttinclude <iostream> using namespace std. int main() { int x =10;
int *ukaz(&x);
cout« "*ukaz = " « *ukaz « "\n"; cout« "x = " « x « "\n";
cout « "*ukaz = " « *ukaz « "\n"; cout« "x = " « x « "\n";
}
Ответ:
*ukaz = 10
x= 10
*ukaz = 5
x = 5
Через выражение *ukaz мы можем получить значение по адресу, который хранится в указателе ukaz, а через выражение типа *ukaz = «значение» — вложить по этому адресу новое значение.
И так как в данном случае указатель ukaz указывает на переменную х, то при изменении значения по адресу, на который указывает указатель, также изменится и значение переменной х.
Присвоение указателю другого указателя:
ttinclude <iostream> using namespace std;
int mainQ
{
int x =100;
int у =155;
int *px(&x};
int *py(&y); //указать
cout« "px: адрес = " « px « "\t значение = " « ’px « "\n";
cout« "py: адрес = " « py « "\t значение = " « *py « "\n";
px = py; //теперь указ переменной у
cout« "рх: адрес = " « px « "\t значение = " « +px «"\n";
*px = 125;
cout« "у-значение = " « у « "\n";
}
Когда указателю присваивается другой указатель, фактически первый указатель начинает тоже указывать на тот же адрес, на который указывает второй указатель
Ответ:
px: адрес - Oxbffdfc py: адрес = 0x6ffdf8 px: адрес = 0x6ffdlS у-значение = 125
значение = 100
значение = 155
значение = 155
Нулевой указатель (NULL)
Нулевой указатель — это указатель, который не указывает ни на какой объект. Если не нужно, чтобы указатель указывал на конкретный адрес, то можно присвоить ему условное нулевое значение.
В Dev C++ константа nullptr не работает даже с подключением файла <cstddef> или <stddef.h> Поэтому нулевой указатель нужно указывать или NULL, или О
Можно создать нулевой указатель любого типа, присвоив указателю значение NULL:
int *ptrName - NULL;
int *ptrName = nullptr;
int *ptrName = 0,
Нулевой указатель представлен значением 0 или ключевым словом NULL. Можно использовать константу nullptr для обозначения нулевого указателя; nullptr указывает константу указателя NULL типа std:: nullptr_t, которая преобразуется в любой необработанный тип указателя. Хотя можно использовать ключевое слово nullptr без включения заголовков, но если код использует тип std:: nullptr_t, то необходимо определить его. включив заголовок <cstddef>.
Пример:
ttinclude <iostream> using namespace std;
int main()
{
int *x = NULL;
cout« "Значение x=:" « x,
return 0;
}
Ответ:
Значение x=: 0
Применение нулевого указателя в С ++.
Нулевой указатель можно использовать в следующих случаях.
Инициализация указателей на нулевое значение помогает избежать
неопределенного поведения, явно указывая, что указатели не указывают на допустимые ячейки памяти.
Нулевые указатели действуют как значения по умолчанию или начальные значения для указателей, когда указателям не присвоен действительный адрес.
Обработка ошибок полезна при наличии ошибки или для обозначения отсутствия данных, что позволяет лучше обрабатывать исключительные случаи.
Для освобождения ресурсов, например присвоения указателям значение NULL после удаления, можно использовать нулевой указатель, чтобы избежать случайного использования освобожденной памяти или доступа к ней.
Нулевой указатель можно использовать как контрольное значение для указания конца структуры данных или списка (например, в связанном списке последний узел имеет нулевой указатель).
186
	Следующий пример показывает разыменование и присвоение нулевого
Нулевой указатель можно использовать	указателя другому значению: tfincluae <iostream> ^include <stddef.h> using namespace std,
как контрольное значение для указания конца структуры данных или списка.	int main() { int *ukaz = NULL; // проверяем, равен ли указатель NULL, перед if(ukaz == NU LL){ cout« "Указатель в данный момент равен нулю" « "\п"; } else{ cout« "Указатель не равен null" « "\п"; } int х = 1000; ukaz = &х; if(ukaz == NULL) { cout« "Указатель в данный момент равен null" « "\п"; } else{ cout« "Указатель не равен null" « "\п" cout« "Значение в ячейке памяти, на которую указывает указатель:" « *ukaz « "\п"; } return D; } Ответ: Указатель в данный момент равен нулю Указатель не равен null Значение в ячейке памяти, на которую указывает указатель: 1000
Операции сравнения и логические операции
К указателям могут применяться операции сравнения == и логические операции >, >=, с, <=,!=. Операции сравнения применяются только к указателям одного типа. Для сравнения используются номера адресов:
#include <iostream> using namespace std; int main()
{
int a = 111;
int b = 222;
int *xa(&a);
int *xb(&b};
if(xa == xb)
cout« "ха (" « ха « ") больше, чем xb (" « xb « ")" « "\n";
else
cout« "ха (" « ха « ") меньше или равно xb (" « xb « ")" « "\n";
}
Ответ:
хз (OxSffeOc) меньше или равно xb (Cx6ffeC8)
187
Математические действия
с указателями
К указателю можно прибавлять целое число; также можно вычитать из указателя целое число. Кроме того, можно вычитать из одного указателя другой указатель.
Рассмотрим операции инкремента и декремента. Для этого возьмем указатель на объект типа int:
Указатели и
ttinclude <iostream>
using namespace std;
int main()
{
int x = 999;
int *ax(&x);
cout« "адрес = " « ax « "\t значение = " « *ax «
ax++;
cout« "адрес = " « ax « "\t значение = " « *ax «
ax—;
cout« "адрес = " « ax « "\t значение = " « *ax «
Ответ:
адрес = 0x6ffe04 адрес = 0x6ffe08
адрес = 0x6ffe04
значение = 999 значение = 7339528 значение = 999
Операция инкремента ++ увеличивает значение на единицу. В случае с указателем увеличение на единицу будет означать увеличение адреса, который хранится в указателе, на размер типа указателя. В данном примере — указатель на тип int, а размер объектов int обычно равен 4 байтам. Поэтому увеличение указателя типа int на единицу означает увеличение адреса в указателе на 4.
Здесь видно, что после инкремента значение указателя увеличилось на 4 — с 0x6fl'e04 до 0x6ffe08. А после декремента, т. е. уменьшения на единицу, указатель получил предыдущий адрес в памяти. Фактически увеличение на единицу означает, что мы хотим перейти к следующему объекту в памяти, который находится за текущим и на который указывает указатель. А уменьшение на единицу означает переход назад к предыдущему объекту в памяти.
После изменения адреса мы можем получить значение, которое находится по новому адресу, однако это значение может быть неопределенным, как показано в случае выше.
В случае с указателем типа int увеличение или уменьшение на единицу означает изменение адреса на 4. Аналогично для указателя типа short эти операции изменяли бы адрес на 2, а для указателя типа char — на 1.
^include <iostream> using namespace std; int mam()
{
double x = 999.999;
double *ax(&x);
cout« "указатель ax: адрес:" « ax « "\n";
ax—;	. меньшен1 /е adp т i на ба i
cout« "указатель ax: адрес:" « ax « "\n"; short у = 25;
short *ay(&y);
cout « "указатель ay: адрес:" « ay « "\n"; ay—; //уменьшение адреса на .
cout « "указатель ay: адрес:" « ay « "\n";
}
Ответ:
указатель ax: адрес.0x6ffe08 указатель ax: aflpec:OxbffeOO указатель ay: appec:0x6ffe06 указатель ay адрес 0x6tfe04
Как видно из примера, уменьшение на единицу указателя типа double привело к уменьшению хранимого в нем адреса на 8 единиц, а уменьшение на единицу указателя типа short дало уменьшение хранимого в нем адреса на 2 (размер типа short — 2 байта).
Помните, что адреса хранятся в шестнадцатеричных значениях.
190
Аналогично указатель будет изменяться при прибавлении или вычитании не единицы, а любого другого числа:
ttinclude <iostream>
using namespace std.
int main()
{
float x = 10.6;
float *ax(&x);
cout« "указатель ax: адрес:" « ax « "\n";
ax = ax + 2; //увеличение адреса
о6ъ< float
cout« "указатель ax: адрес:" « ax « "\n";
short у = 5;
short *ay(&y);
cout« "указатель ay: адрес:" « ay « "\n";
ay = ay — 3;
размер 3 ооъектов short
cout« "указатель ay: адрес:" « ay « "\n";
}
Ответ:
указатель ax: aftpec:0x6ffe0c
указатель ax: aflpec:0x6ffel4
указатель ay: адрес:0х6йе0э
указатель ay: адрес:0x6ffe04
Добавление к указателю типа double числа 2:
ах = ах + 2;
означает, что необходимо перейти на два объекта double вперед, что подразумевает изменение адреса на 2 х 8 = 16 байт.
Вычитание из указателя типа short числа 3:
ау = ау — 3;
означает, что мы хотим перейти на три объекта short назад, что подразумевает изменение адреса на 3 х 2 = 6 байт.
В отличие от сложения, операция вычитания может применяться не только к указателю и целому числу, но и к двум указателям одного типа:
include <iostream> using namespace std.
int main})
{
int a - 10;
int b = 23;
int *pa(&a);
int *pb(&b);
auto abipa -pb);
cout« "pa:" « pa « "\n";
cout« "pb: " « pb « "\n";
cout« "ab:" « ab « "\n";
}
К указателю можно прибавлять целое число, можно вычитать из указателя целое число. Кроме того, можно вычитать из одного указателя дру| ой указатель.
Разность указателей представляет тип std:: ptrdiff_t, который является псевдонимом для типов int, long и long long Поэтому переменная ху, которая хранит разность адресов, определена с помощью оператора auto.
Ответ:
ах: 0x6ffe08 ay: 0x6ffe04 ху-1
Результатом разности двух указателей является «расстояние» между ними. Например, в примере выше адрес из первого указателя на 4 больше, чем адрес из второго указателя (0x6ffe04 + 4 = 0x6ffe08). Так как размер одного объекта int равен 4 байтам, то расстояние между указателями будет (0x6ffe08-0x6ffe04) /4=1.
Указатели одного типа значений могут быть преобразованы в указатели другого типа значений. Однако результат может быть неопределенным из- за размеров различных типов в памяти, а также требований к выравниванию. Указатель на один объект может быть преобразован в указатель на другой объект, где выравнивание в памяти менее строгое или одинаково строгое1.
Указатели на тип void могут быть преобразованы в указатели любого типа и из указателя на любой тип без ограничений и потери данных без каких-либо ограничений или потери данных. Когда результат преобразования возвращается к исходному типу, восстанавливается исходный указатель.
Значения указателей также могут быть преобразованы в целочисленные значения. Путь преобразования зависит от размера указателя и размера целочисленного типа и подчиняется следующим правилам:
если размер указателя больше или равен размеру целочисленного типа, указатель ведет себя как неопределенное значение, за исключением того, что при преобразовании он не может быть преобразован в вещественное значение;
если размер указателя меньше размера целочисленного типа, указатель сначала преобразуется в указатель того же размера, что и целочисленный тип, а затем в целочисленный тип.
1 См., напр.: https://learn.microsoft.com/ru-ru/
cpp/c-language/conversions-to-and-from-pointer-types.
И наоборот, целочисленный тип может быть преобразован в тип указателя в соответствии со следующими правилами:
если размер целочисленного типа совпадает с размером типа указателя, процесс преобразования просто рассматривает целочисленное значение как указатель (беззнаковое целое);
если размер целочисленного типа отличается от размера типа указателя, то целочисленный тип сначала преобразуется алгоритмом преобразования в размер указателя7.
Для преобразования указателя к другому типу в скобках перед указателем ставится тип, к которому надо преобразовать. Причем если нельзя создать объект, например переменную типа void, то для указателя это вполне возможно. То есть можно создать указатель типа void.
Указатель можно преобразовать к другому типу. Эти преобразования бывают двух видов: с использованием указателя типа void* и без его использования.
Необходимо напомнить, что по умолчанию значение указателя выводится в шестнадцатеричной системе счисления. Если мы хотим его вывести в десятичной системе счисления, то нужно преобразовать указатель в целое число.
cout« (unsigned int)р;
2 См., напр.: https://learn.microsoft.com/ru-ru/ cpp/c-language/conversions-from-unsigned-integral-types.
Для примера рассмотрим следующие преобразования типов:
float *х;
int *у;
X = у; типа у — х: типа
х = (f loat* }у; можно присвоить у = (int*)x;
Рассмотрим это подробнее. Присвоения х = у и у = х невозможны, так как являются разными типами данных.
Присвоения х = (float*)y и у = (int*)x возможны, так как речь идет не о данных, а об указателях на данные.
Типы данных float и int взяты только с одной целью: они занимают по 4 байта в памяти.
Пример:
ttinclude <iostreain> using namespace std: int mainQ
{
int x - 555;
int *ax = (&x);
float у = 44.67;
float *ay = (&y);
*ax = *ay;
cout « *ax « "\n";
}
Ответ:
44
Мы получили не совсем то, чт о ожидали. Число-то мы получили, но тип не изменился, так как нет явного приведения типов данных.
Создадим явное приведение типов:
^include <iostream> using namespace std. int main()
{
char x = ('Y’)j
char *ax(&x);
int *ay = f(int*)ax);
void *az = ((void*)ax);
cout« "az=" « az « "\n";
cout« "ay=" « ay « "\n";
cout« "ax=" « ax « "\n";
}
Ответ — на рис. 20.
az=0x6ffe07 af=0x6ffe07 ak=qeo
rocess exited after 0.5371 seconds with return value 0 ля продолжения нажмите любую клавишу . . .
Рис. 20. Результаты приведения типов указателей
Необходимо напомнить, что речь идет не о приведении типов данных, а о приведении типов указателей, показывающих на память.
Указатели и
Особенности операций
с указателями
При работе с указателями надо различать операции с самим указателем и операции со значением по адресу, на который указывает указатель:
^include <iostream>
using namespace std;
int main()
{
int x = 100;
int *ax(&x);
int у = *ax + 50;
на который указывает указатель ах++;
cout« "у:" « у « "\п";
В данном примере через операцию разыменования *ах получается значение, на которое указывает указатель ах, т. е. число J 00, и выполняется операция сложения. В данном примере выполняется операция сложения между двумя числами, так как выражение *ах представляет число.
В то же время есть особенности, в частности — с операциями инкремента и декремента. Операции * и префиксные операции ++ и — имеют одинаковый приоритет и при размещении рядом выполняются справа налево.
Например, выполним префиксный инкремент:
int х = 999;
int *ах(&х);
cout « "ах: адрес = " « ах « "\t значение = " « *ах « "\п";
int у = ++*ах:
указателя
cout « "у: значение = " « у « "\п";
cout« "ах: адрес = " « ах « "\t значение = " « *ах « "\п";
В выражении у = ++*ах; сначала происходит разыменовывание указателю — получается значение по адресу указателя, т. е. число 999. Затем к этому числу прибавляется единица.
Ответ:
ах: адрес = 0x6ffe00 у:значение = 1С00 ах: адрес = 0x6ffe00
значение = 999
значение = 1000
Изменим выражение:
int у = *++ах;
Операции * и префиксные операции ++ и — имеют одинаковый приоритет и при размещении рядом выполняются справа налево.
Теперь сначала к указателю прибавляется единица (т. е. к адресу добавляется 4, так как указатель — типа int), затем по этому адресу получается значение и значение присваивается переменной у.
Ответ:
ах. адрес = 0x6ffe00 значение = 999 у. значение = 0
ах адрес = 0x6fte04 значение = 0
В отличие от префиксных инкремента и декремента постфиксные версии операций имеют больший приоритет, чем операция разыменования *. Выполним следующую программу:
int х = 999;
int *ах(&х);
cout« "ах: адрес = " « ах « "\t значение = " « *ах « "\п";
int у = *ах++; // инкремент адреса указателя с последующим разыменовыванием cout« "у; значение = " « у « "\п";
cout« "ах: адрес = " « ах « "\t значение = " « *ах « "\п";
В отличие от префиксных инкремента и декремента постфиксные версии операций имею’ больший приоритет, чем операция разыменования *.
Поскольку постфиксный инкремент имеет больший приоритет, то в выражении *ах++ сначала увеличивается адрес указателя ах на единицу (фактически на 4, так как указатель — типа int) и затем получается значение по адресу. Так как постфиксный инкремент возвращает значение до увеличения, то в переменной у мы получаем значение, которое было по адресу до инкремента.
Ответ:
ах: адрес = 0x6ffe0D	значение = 9S9
у: значение = 999 ах-адрес = 0x6ffe04	значение = 999
Изменим выражение:
int у = (*ах)++;
Скобки изменяют порядок выполнения операций. Сначала выполняется операция разыменования (999) и получения значения (999), затем это значение увеличивается на 1. То есть по адресу в указателе находится число ] ООО. Таким образом, в отличие от предыдущего примера, все операции производятся над значением по адресу, который хранит указатель, но не над самим указателем. Результат работы изменится.
Ответ:
ах’адрес = 0x6ffe0u	значение = 999
у: значение = 999 ах: адрес = 0x6ffe00
значение = 1000
Указатели на константы
Указатели могут указывать как на переменные, так и на константы.
Чтобы определить указатель на константу, указатель тоже должен объявляться с ключевым словом const:
include <iostream> using namespace std, int mam() {
const int x = 999;
const int *ax(&x);
cout« "адрес = " « ax « "\t значение = " « *ax « "\n";
}
Ответ:
адрес - 0x6ffe04	значение = 999
Здесь указатель ах указывает на константу х. Поэтому, даже если изменить значение по адресу, который хранится в указателе, мы не сможем это сделать, например, так:
*ах = 998;
В этом случае будет получена ошибка во время компиляции: [Error] assignment of read-only location '* ax' ([Ошибка] присвоение местоположения, доступного только для чтения, '* ах').
Указатель на константу может указывать на переменную:

He изменяйте значение переменной или константы чеоез указатель на константу.
tfinclude <iostream>
using namespace std;
int main()
{
int x = 999;
const int *ax(&x);
cout« "значение = " « *ax « "\n";
x = 777;
cout« "значение = " « *ax « "\n";
*ax = 555;
}
В данном примере переменная может изменяться отдельно, но изменить ее значение через указатель нельзя, так как указатель — на константу.
Через указатель на константу нельзя изменять значение переменной или константы. Но можно присвоить указателю адрес любой другой переменной или константы, например:
ttinclude <iostream> using namespace std; int main()
{
const int x = 999;
const int *ax(&x);
const int у = 555;
ax = &y;
cout« "значение *ax = " « *ax « "\n"; cout « "значение x = " « x « "\n";
}
Ответ:
значение *ax = 555
значение x = 999
Константный указатель
От указателей на константы нужно отличать константные указатели. Они не могут изменять адрес, который в них хранится, но могут изменять значение по этому адресу, например:
^include <iostream> using namespace std, int mam()
{
int x = 888;
int *const ax(8ix);
cout« "значение = " « *ax « "\n";
*ax = 777;
cout« "значение = " « *ax « "\n";
int v = 555;
ax = &y,
([Ошибка] присвоение переменной 'ax', доступной только для чтения)
}
201
Константный указатель
на константу
Константный указатель на константу не позволяет изменять ни хранимый в нем адрес, ни значение по этому адресу, например:
int rrrain()
{
int х = 10;
const int *const ax(&x);
int у = 45;
ax = &y;
([Ошибка] присвоение переменной 'ax', доступной только для чтения)
}
В C++ можно создавать динамические объекты.
Продолжительность их жизни не зависит от места создания. Они существуют, пока не будут удалены. Динамические объекты размещаются в динамической памяти (free store).
Средства использования динамической памяти. Операторы new и delete
В C++ объекты создаются динамически с помощью new-выражений и очищаются из памяти с помощью delete-выражений.
Синтаксис оператора new следующий:
new Тип_Данных;
Тип_Данных вовсе не обязательно является простым типом данных переменных, но и типом любого класса, который создает производные типы данных.
Например, для целого типа данных объявление может быть таким:
int *АВС = new int;
Динамический массив объявляется следующим образом:
int X = 100;
double *СВА = new int[X];
Динамический массив создается в данном случае под 100 элементов массива.
Синтаксис оператора delete очень прост:
delete АВС,
deleted СВА;
В данном случае удаляются все элементы массива или все указанные объекты (если это объекты).
Пользователи также могут добавлять собственные функции выделения и освобождения в качестве статических членов класса или свободных функций в глобальном пространстве имен. Такие пользовательские функции должны соблюдать семантику встроенных функций (например, не выделять уже выделенные адреса).
Огератор new выделяет место для обьекта в динамической памяти и возвращает указатель на этот объект.
Оператор delece получает указатель на динамический объект и удаляет его из памяти.
Связь между указателями и массивами
Указатели можно применять не только для переменных, но и в массивах. Например, можно объявить массив и ссылку на него
так:
double MyMassyw[25];
double *MyMassywMassyw = &MyMassyw[O]j
Мы объявили о создании массива из 25 элементов и установили указатель в первый элемент в массиве, т. е. на элемент с индексом 0. После этого можно осуществлять перебор всех элементов массива, используя операторы инкремента или декремента:
*(++MyMassywMassyw)
или:
*(—MyMassywMassyw)
В C++ указатели и массивы тесно связаны. Обычно компилятор преобразует массив в указатели. С помощью указателей можно манипулировать элементами массива, как и с помощью индексов. Это означает, что не следует использовать амперсанд (&) для присвоения адреса массива указателю.
Имя массива является адресом его первого элемента. Например:
^include <iostream^ using namespace std, int main(){ int *perem;
int arr[] = {10, 34, 13, 76, 5, 46, 31, 99, 40, 88};
perem = arr;
for(int x = 0; x < 10; x++) {
cout« *perern « H\t"; perem++;
}
return D
}
Ответ:
10	34	13	76	5	46	31
99	40	88
Имя массива всегда хранит адрес самого первого элемента. Для перемещения по элементам массива используются отдельные указатели:
ftinclude <iostream> using namespace std, int main()
{
int arr[] = {10, 34, 13, 76, 5, 46, 31, 99, 40, 88};
int *uka(arr), int arr4 = *(uka + 3); cout« "arr4:" « arr4 « 'Дп";
return 0;
}
Ответ:
76 (четвертый элемент массива)
Здесь указатель uka изначально указывает на первый элемент массива. Увеличив указатель на 3, мы пропустим три элемента в массиве и перейдем к элементу агг[4].
205
Им,я массива всегда хранит адрес первого элемента.
Понятие ссылки
Ссылка является псевдонимом для переменной. Синтаксис объявления ссылки следующий:
Тип_Данных & Имя_Ссылки;
Чтобы инициализировать ссылку, нужно связать ее с переменной:
Ти п^Данных & Имя_Ссылки = Переменная;
Например:
int Ssylka;
int & MySsylka = Ssylka
В резулы аге MySsylka становится ссылкой на Ssylka.
Ссылки можно использовать как с отдельными переменными, так и с функциями:
void Funkz(int& Zwet)
{
Zwet++;
}
int MyZwet = 10;
Funkz(MyZwet); cout« MyZwet;
Значение MyZwet увеличивается на единицу, так как в момент вызова функции Funkz(Zwet) становится ссылкой на MyZwet.
Ссылки более удобны и применяются чаще всего.
Виды ссылок
Ссылка является скрытым указателем и во всех случаях и для любых целей ее можно употреблять просто как еще одно имя переменной. Ссылку допустимо использовать тремя способами: во-первых, ссылку можно передать в функцию; во-вторых, ссылку можно возвратить из функции; в-третьих, можно также создать независимую ссылку.
Передача ссылки в качестве параметра функции
Наиболее важное применение ссылки — это передача ее в качестве параметра функции. Например:
tfinclude <iostream> using namespace std. void funk(int & x)
{
X++;
}
int main})
{
int a - 999;
cout« a « "\n";
funk|a);
cout« a « "\n";
}
Ссылка создается для одной переменной и не может быть «переброшена» на другую переменную.
В данном примере оператор & обозначает значения, передаваемые по ссылке в функции. Передача по ссылке позволяет функции изменять переменную без копирования. Передаваемая переменная и параметр имеют одно и то же место в памяти. Поэтому любые изменения, внесенные в параметр, отражаются в переменных основной функции. Такая возможность отражать изменения позволяет функциям возвращать несколько значений.
208
Сначала функция определяется с возвращаемым типом данных void и принимает значение по ссылке (что обозначается знаком & адреса в формальных параметрах).
Функция увеличивает значение своего формального параметра на 1.
После чего внутри функции main целочисленная переменная с именем а инициализируется значением 999.
Значение э выводится на консоль. Вызывается функция f(), и переменная передается в качестве аргумента.
Внутри функции значение переменной увеличивается на 1.
При возврате из функции снова отображается значение переменной, которое оказалось на 1 больше исходного значения.
Изменения переменной, передаваемой по ссылке на функцию, отражаются в вызывающей функции.
Пример:
ttindude <iostream>
Помните, что изменения переменной, передаваемой по ссылке на функцию, отражаются в вызывающей функции.
using namespace std;
void f int & r);
int mainf)
{
int i = 0;
f(i);
cout« "Новое значение i: " « i « "n\";
return 0;
}
// в функции f() используется пораметр-ссылка void flint & n)
{
п — 101
//используемый при вызове функции /()
Так как переменная п является ссылкой, не нужно использовать оператор *. Вместо этого всякий раз, когда п упоминается в f(), она автоматически рассматривается как указатель на аргумент, испол ьзуемый в вызове f(). Инструкция п = 100; означает, что указанное число 100 помещается в переменную i, используемую в вызове f(). При вызове функции f() перед аргументом не нужно ставить знак &. Так как функция f() объявлена как получающая парахметр-ссылку, ей автоматически передается адрес аргумента.
Рассмотрим другой пример:
^include <iostream> using namespace std, void funk(int & x);
параметра
int main()
{
int i = 0;
funk(i);
cout« "Новое значение i = " « i « "\n"; return 0;
}
void funk(int & x)
{
x = 999;
При вызове функции f() перед аргументом не нужно ставить знак &. Так как функция f() объявлена как получающая параметр ссылку, ей автоматически передается адрес аргумента
}
В объявлении функции void funk(int
& х) символ & является ссылкой на переменную х. Далее, при исполнении (в функции main) функция funk вызывается, инициализируется и выводится на консоль со значением 999.
При использовании параметра-ссылки компилятор автоматически передает функции адрес переменной, указанной в качестве аргумента. Не нужно получать адрес аргумента с помощью символа &. Внутри функции компилятор автоматически использует переменную, на которую указывает параметр-ссылка.
При использовании параметра-ссылки не нужно ставить знак * Параметр-ссылка полностью автоматизирует механизм передачи параметра с помощью вызова функции по ссылке.
Создание независимой ссылки Независимая ссылка — это ссылка, которая является просто другим именем переменной, т. е. псевдонимом. Поскольку ссылкам нельзя присваивать новые значения, независимая ссылка должна быть инициализирована при ее объявлении.
Например:
^include <iosrream> using namespace std. int main() { int abc;
int &reference = abc;
abc = 50;
reference = 100;
abc = 20;
cout« abc « "\t" « reference « "\t" « abc;
return 0;
}
Ответ:
20
20
20
Казалось бы, reference = 100 (так как мы присвоили этой переменной такое значение), a abc = 20, но дело в том, что abc и reference - это одно и то же (так как reference является ссылкой на abc), a abc мы изменили сахмой последней, поэтому и reference получило значение 20. Потому и значения у них одни и те же.
Немного изменим программу.
Поставьте комментарий перед строкой: // abc =20;
Снова скомпилируйте программу — ответ будет: 100 100 100. Снова все значения одинаковые, так как и abc, и reference — одно и то же, ведь в последнем примере значение 100 reference получила последней.
Если и reference = 100; сделать комментарием, то reference и abc получат значение 50.
Функция может возвращать ссылку.
В этом случае вызов функции становится синонимом той переменной, которая стоит в операторе return в теле функции. Иногда это бывает очень удобно, однако может служить источником ошибок. Нельзя возвращать автоматическую локальную переменную по ссылке, потому что она исчезает по выходе из функции, и вызов функции оказывается в этом случае синонимом исчезнувшей переменной. Возвращать по ссылке можно глобальные или статические переменные или ссылки на них, а также формальные параметры, переданные по ссылке.
Нельзя возвращать автоматическую локальную переменную по ссылке, потому что она исчезает по выходе из функции Возвращать по ссылке можно глобальные или статические переменные или ссылки на них, а также формальные параметры, переданные по ссылке.
Например:
^include <iostream> using namespace std; int &reference();
int y;
int main()
{
reference() = 999.6655;
cout« y;
return 0;
}
int &reference()
{
return y;
}
Ответ:
999
Как видно из примера, мы решили немного ошибиться и присвоили функции reference вещественное число с дробной частью после запятой. Но так как переменная у является целым числом, то дробная часть была отброшена.
Заключение
Указатель — это переменная, которая хранит адрес памяти другой переменной.
Указатели поддерживают ряд операций: разыменование, присваивание, получение адреса указателя (&), получение значения по указателю, а также арифметические операции (присваивание, сложение с константой, вычитание, инкремент ++, декремент—, операции сравнения).
Нулевой указатель — это указатель, который не указывает ни па какой объект.
Нулевые указатели действуют как значения по умолчанию или начальные значения для указателей, когда указателям не присвоен действительный адрес.
К указателям могут применяться операции сравнения == и логические операции >, >=, <, <=,!=. Операции сравнения применяются только к указателям одного типа.
К указателю можно прибавлять целое число; также можно вычитать из указателя целое число. Кроме того, можно вычитать из одного указателя другой указатель.
Указатели на тип void могут быть преобразованы в указатели любого типа и из указателя на любой тип без ограничений и потери данных без каких-либо ограничений или потери данных.
При работе с указателями надо различать операции с самим указателем и операции со значением по адресу, на который указывает указатель.
Указатели могут указывать как на переменные, так и на константы. Чтобы определить указатель на константу, указатель тоже должен объявляться с ключевым словом const.
Через указатель на константу нельзя изменять значение переменной или константы. Но можно присвоить указателю адрес любой другой переменной или константы.
О г указателей на константы нужно отличать константные указатели. Они не могут изменять адрес, который в них хранится, но могут изменять значение по этому адресу.
Константный указатель на константу не позволяет изменять ни хранимый в нем адрес, ни значение по этому адресу.
В C++ объекты создаются динамически с помощью new-выражений
и очищаются из памяти с помощью delete-выражений.
Указатели можно применять не только для переменных, но и в массивах.
Ссылка является псевдонимом для переменной.
Ссылки можно использовать как с отдельными переменными, так и с функциями.
Ссылка является скрытым указателем и во всех случаях и для любых целей ее можно употреблять просто как еще одно имя переменной.
Наиболее важное применение ссылки — это передача ее в качестве параметра функции.
При использовании параметра-ссылки компилятор автоматически передает функции адрес переменной, указанной в качестве аргумента.
Независимая ссылка — это ссылка, которая является просто другим именем переменной, т. е. псевдонимом. Поскольку ссылкам нельзя присваивать новые значения, независимая ссылка должна быть инициализирована при ее объявлении.
Функция может возвращать ссылку.
В этом случае вызов функции становится синонимом той переменной, которая стоит в операторе return в теле функции.
Типы данных, определяемые пользователем
218 Перечисляемый тип
222 Переименование типов с помощью typedef
225 Структурный шаблон и синтаксис его объявления
227 Понятие «поле шаблона»
229 Объявление, инициализация и обработка структурных переменных
231 Указатели на структуру
232 Вложенные структуры
234 Переменные типа объединения и особенности их использования
239 Заключение
Типы данных, определяемые пользователем

Перечисляемый тип
Перечисление — это определяемый пользователем тип, состоящий из набора именованных целочисленных констант, которые называются перечислителями.
Перечисление имеет следующую форму: enum class имя_перечисления {константа_1, константа_2,... константа N};
После ключевых enum class идет название перечисления, и затем в фигурных скобках перечисляются через запятую константы перечисления.
Определим простейшее перечисление:
enum class Year{January, February, March, April, May, June, July, August, September, October, November, December}
В Dev-C++ в данном примере при использовании слова class генерируется ошибка, так как описания класса Year (а также Day и других пользовательских классов) у нас нет, а до классов мы еще не дошли. Поэтому слово class игнорируем.
В данном случае перечисление называется Year и представляет месяцы года.
В фигурных скобках заключены все месяцы года. Фактически они представляют по умолчанию числовые константы от 0.
Каждой константе сопоставляется некоторое числовое значение.
По умолчанию первая константа получает в качестве значения 0, а остальные увеличиваются на единицу. Так, в примере выше January будет иметь значение 0, February — 1 и т. д. Таким образом, последняя константа — December — будет равна 11.
После создания перечисления мы можем определить его переменную и присвоить ей одну из констант:
Year Month [Year:, March};
// Year Month - March;
В данном случае определяется переменная Month, которая равна Year:: March, т. е. третьей константе перечисления Year (с индексом 2).
Чтобы вывести значение переменной на консоль, можно использовать преобразование к целочисленному типу:
ftinclude <iostream> using namespace std, enum Year{January, February,, March. April, May, June, July, August, September, Oct .ber, November, December};
int mam() {
Year Month = March;
cout« "Month: " « Month « "\n", return 0;
}
To есть в данном случае на консоль будет выведено Month: 2, так как константа March имеет значение 2.
По умолчанию индексация элементов перечисления начинается с 0, но можно стартовое значение в первом элементе изменить на «1». Во всех других элехментах перечисления индекс увеличится на стартовое значение. То есть March будет уже не вторым индексом, а третьим. Например:
enum Year{January = 1, February, March, April, May, June, July, August, September. October, November, December}
4.
Чтобы вывести значение переменной на консоль, используйте преобразование к целочисленному типу.
219
Типы данных, определяемые пользователем
Все перечисления и перечислители находятся в одном пространстве имен, поэтому повторение перечислителей не допускается. Например:
enum Year{January, February, March, April, May, June, July, August, September, October, November, December};
enum MonthfJanuary, February, March, April, May,. June};
В перечислениях Year и Month встречаются одни и те же элементы, что недопустимо. Выходом будет или переименование элементов в перечислении Month, или создание отдельных областей видимости:
ttindude <iostream> using namespace std;
namespace A{
enum Year{January = 1, February. March, April, May, June, July, August, September, October, November, December};
};
namespace Б{
enum Month(January, February, March, April, May, June};
}
int main()
{
A Yearperem = A March;
cout« "Month: " « perem « "\n";
В Month pere = B:: Mlarch, cout« "Month: " « pere « "\n"; return 0;
}
Ответ:
Month 3 Month 2
Ответ 3 потому, что в перечислении Year индексация начинается с 1, а значит March имеет индекс 3.
Во втором примере индексация начинается с О, поэтому March имеет индекс 2.
Перечисление может быть анонимное, т. е. имя перечисления не указывается. Например:
#include <iostream> using namespace std, enum{first second, third};
int main()
{
cout« second « "\n";
return 0;
}
Ответ: 1, так как индексация начинается с 0.
Основные типы данных в языке C++
int - целое число;
float - неточный тип, который позволяет хранить целую идробные части;
double - аналог предыдущего, но с большей точностью;
char - тип данных, отвечающий за запись символов;
bool - логический тип, который монет быть true или false.
Типы данных, определяемые пользователем
Переименование типов с помощью typedef
Квалификатор typedef — это зарезервированное ключевое слово в языке программирования C++. Он используется, чтобы создать дополнительное имя (псевдоним) для другого типа данных, но не создает новый тип, за исключением неявного случая квалифицированного typedef типа массива, где квалификаторы typedef передаются типу элемента массива. Как таковой он часто используется для упрощения синтаксиса объявления сложных структур данных, состоящих из структурных и союзных типов, хотя он также обычно используется, чтобы предоставить конкретные описательные имена типов для целочисленных типов данных различных размеров.
Объявления typedef можно использовать для создания более коротких или более понятных имен для типов, уже определенных в C++, или для объявленных типов. В качестве заменяемых типов могут использоваться void, char, short, int, long, float, double, signed, unsigned.
Объявление typedef следует тому же синтаксису, что и объявление любого другого идентификатора C++.
Ключевое слово само по себе является спецификатором. Это означает, что, хотя оно обычно появляется в начале объявления, оно также может появляться после описателей типа или между двумя из них. Например:
typedef int length;
где int — тип данных целых чисел; length — синоним типа mt.
Объявление typedef может использоваться в качестве документации, указывая значение переменной в контексте программирования. Например, оно может включать выражение единицы измерения или счетчиков (могут быть выражены путем объявления типов, специфичных для контекста):
typedef int km_per_hour;
typedef int points,
km_per_hour current_speed;
points high_score;
To есть объявленные с помощью typedef типы-синонимы могут использоваться так же, как и привычные типы. То есть объявления:
int current_speed;
и
km_per_hour current_speed;
означают одно и то же, но тип km_per_ hour может оказаться удобнее для работы с переменными но определению скоростей объектов, например автомобилей или самолетов, чем тип int.
Объявления typedef можно использовать для создания более коротких или более
понятных имен
для типов, уже определенных в C++, или для объявленных типов.
NJ UJ
Объявление typedef можно использовать для упрощения объявления объектов, имеющих типы с подробными именами, такие как типы структуры (struct), объединения (union) или указателя (pointer).
Типы данных, определяемые пользователем
Например:
struct MyStruct {
int datal;
double data2;
};
typedef int *intptr; intptr ptr;
В данном примере переменная ptr имеет тип intptr, который является синонимом типа int.
'гг
r-.j
Г\1
Так как это константный указатель, он должен быть инициализирован в объявлении.
Поскольку typedef определяет тип, а не расширение, то объявления, использующие квалификатор const, могут привести к неожиданным или неинтуитивно понятным результатам. В следующем примере объявляется константный указатель на целочисленный тин, а не указатель на константное целое число:
typedef int *intptr;
const intptr ptr = NULL,
Так как это константный указатель, он должен быть инициализирован в объявлении.
Структурный шаблон и синтаксис его объявления
Кроме классов, существует еще два понятия группирования: структура и объединение. Структура была наследована от языка С, но в языке C++ это понятие подверглось очень серьезному пересмотру.
Структура представляет собой набор данных различных типов, объединенных общим именем. Структура может включать как данные-элементы, так и функции-элементы. В состав структуры могут входить конструкторы и деструкторы. Все это делает классы и структуры очень похожими. Но есть принципиальное расхождение между ними. Оно заключается в том, что члены класса по умолчанию являются закрытыми, а члены структуры по умолчанию являются открытыми.
Синтаксис описания структуры:
struct TEG{
private
}список_объектоБ
Здесь TEG — тег, или обозначение структуры, или, если быть еще точнее, имя нового типа, объявляемого в структуре. Классы создают новые производные типы данных. Структуры в этом отношении не отличаются от классов и тоже порождают новые типы данных.
Типы данных, определяемые пользователем
Внутри структуры
объявляются закрытые
члены, если они есть. Описание структуры происходит наоборот в сравнении с классами: если
в классах указываются открытые члены
класса словом
public, а остальные
по умолчанию считаются закрытыми, то в структурах специально
Внутри структуры объявляются закрытые члены, если они есть. Описание структуры происходит наоборот в сравнении с классами: если в классах указываются открытые члены класса словом public, а остальные по умолчанию считаются закрытыми, то в структурах специально указываются только закрытые члены структуры словом private, а остальные члены структуры по умолчанию считаются открытыми.
Наличие структур в языке у многих вызывает недоумение: зачем наряду с классами создавать еще и структуры? Объяснение этому обычно дается в двух формах — строгой и мягкой. Строгое объяснение состоит в том, что необходимо поддерживать единство с языком С. Мягкое объяснение заключается в том, что это понятие хоть и не особенно нужно, но и не мешает языку C++. Обычно это понятие редко используется в языке C++, но активно используется в различных библиотеках и функциях.
Кроме того, структуры по-прежнему могут использоваться при различных действиях вместо классов.
указываются только закрытые члены структуры словом private, а остальные по умолчанию считаются открытыми.
Понятие «поле шаблона»
Объявление структуры создает шаблон структуры, определяющий новый тип, имя которого можно использовать наряду со стандартными типами.
Переменные, которые объединены структурой, называются ее полями (или элементами). Это могут быть обычные переменные, массивы, указатели, другие структуры, обьединения. Структуры похожи на массивы, но в массивах хранятся однородные объекты, а в структурах объекты могут быть разных типов.
Описание элемента (поля) складывается из указания типа элемента и имени элемента, поэтому подробное описание структуры выглядит так:
struct имя_структуры {
тип_элемента_1 имя_элемента_1; тип_элемента_2 имя_элемонта_2;
гип_элемента_п имя_элемента_ п; } "писатель;
где тип_элемента_1, тип злемента_2, ..., тип_элемента_п — любые основные типы (int, char, double и г. д.), массив, указатель, структура (struct), объединение (union).
Как видно из описания, в одну структуру может входить другая структура, или, по-другому, вложенная структура.
На месте конструкции описатель может указываться одна переменная или более (через запятую), которые будут использоваться впоследствии в программе как переменные указанного структурного типа.
Типы данных, определяемые пользователем
Объявление структуры является оператором, поэтому после такого объявления должна стоять точка с запятой. Точка с запятой вводится или после закрывающей фигурной скобки, если нет описателей, или сразу после последнего описателя, если они предусмотрены.
Тип string не входит в число ключевых слов языка C++. Поэтому он не выделен полужирным начертанием.
Необходимо отметить, что объявление структуры не приводит к выделению памяти под переменную. Это всего лишь описание каркаса будущей переменной, ее шаблон. С точки зрения компилятора объявление структуры является описанием нового пользовательского типа данных. Далее можно описывать переменные, используя имя шаблона.
Рассмотрим структуру типа book, т. е. структуру книги. Если открыть библиографическую запись о любой книге, то там описывается следующая информация: автор, название книги, издательство, год выпуска, объем в страницах, ISBN бумажный и электронный, а также другая информация (номер издания, соавторы и т. д.).
]/1з перечисленных параметров книги мы для примера возьмем только «название книги», «автор» и «год выпуска»:
struct book
{
string title;
string author;
int year;
Объявление, инициализация и обработка структурных переменных
Рассмотрим пример:
struct Person { string name; bool citizenship: int age, };
Здесь структура Person представляет собой структуру с тремя членами. Члены Person включают имя (имеется в виду’ Ф. И. О.), гражданство и возраст. Один член имеет тип данных string, один является bool, один — целым числом. Гражданство получило 1ип bool, так как человек может быть гражданином (значение 1) или негражданином (значение 0).
В приведенном примере создана структура с именем Person. Структурную переменную можно создать следующим образом:
Person р;
где р — структурная переменная типа Person.
Эту переменную можно использовать для доступа к членам структуры с оператором точка. Например:
(ЛГ)
229
Типы данных, определяемые пользователем
^include <iostream> using namespace std, struct Person
{
string name;
bool citizenship;
int age,
};
int rnain(void)
{
struct Person p:
p name = "Шитов Виктор Николаевич";
p citizenship = 1;
p age = 66;
cout« "Ф. И. " « p name « "\n";
cout« "Гражданство:" « p citizenship « "\n";
cout« "Возраст: " « p age « "\n";
p name = "Успенский Кирилл Евгеньевич";
p citizenship = 0;
p age = 47;
cout« "Ф. И. O.:" « p name « "\n";
cout« "Гражданство:" « p citizenship « "\n";
cout« "Возраст: " « p age « "\n";
return D, }
Ответ:
Ф. И. О. Шитов Виктор Николаевич
Гражданство: 1
Возраст: 66
Ф. И. О.: Успенский Кирилл Евгеньевич Гражданство: О Возраст: 4 7
Указатели
на структуру
Можно создать указатель, указывающий на структуру. Это делается так же, как указатели указывают на собственные типы данных, такие как int, float, double и т. д. Указатель в C++- хранит ячейку памяти. Например:
ttinclude <iostream> using namespace std, struct academic
{
string subject; int estimation;
};
int main()
{
academic xptr. p; ptr = &p;
(*ptr) subject = "Программирование C++";
(*ptr) estimation = 5;
cout« "Предмет:" « (*ptr).subject« "\n"; cout« "Оценка:" « (*ptr).estimation « "\n";
(*ptr) subject = "Теория механизмов и машин"; (*ptr) estimation = 4;
cout « "Предмет:" « (’ptr).subject« "\n"; cout« "Оценка:" « (*ptr).estimation « "\n"; return 0, }
Ответ:
Предмет: Программирование C++
Оценка: 5
Предмет: Теория механизмов и машин
Оценка: 4
Необходимо отметить, что оператор (academic *ptr, р;) создает переменную-указатель *ptr и обычную переменную р типа academic (тип academic создается структурой academic). Адрес переменной р сохраняется в указателе переменной *ptr (ptr = &р;). Указатель связывается с членами структуры оператором «точка».
Оператор (academic *ptr, р;) создает переменную-указатель *ptr и обычную переменную р типа academic.
Типы данных, определяемые пользователем
см со гм
Вложенные структуры
В качестве полей структур можно использовать любые типы данных, в том числе и другие структуры.
Создадим структуру для хранения имени, отчества и фамилии сотрудника:
struct fio{
string name;
string patronymic;
string family;
};
После этого создадим структуру для общих данных о сотруднике, включая его Ф. И. О.:
struct personal_data{
struct tio;
bool gender;
unsigned short age;
string date_of_birth;
string home address;
};
Немного изменим пример — создадим одну структуру сразу внутри другой структуры:
struct personal_data{
struct fio{
string name;
string patronymic;
string family;
};
bool gender;
unsigned short age;
string date_of_birth, string home address;
}>
Структура struct fio стала вложенной в структуре struct personal_data.
Пример с вложенной структурой и инициализацией обеих структур:
^include <iostream>
^include <stdio.h> using namespace std. struct vnesh
{
int a;
struct vnut
{
int b;
int c;
} b;
};
int main()
{
struct vnesh c = {10, {12,15}};
cout« c a « " " « c b.b « " " « c. b.c; return 0;
}
Ответ:
10	12	15
Обратите внимание, что после вложенной структуры введен описатель Ь, который сообщает, что перед обращением к членам вложенной структуры vnut нужно обращаться как «Ь, точка, имя переменной» в структуре vnut. То есть b.b и Ь. с.
В нашем примере для обращения к структуре vnesh объявлена переменная с, поэтому при обращении к вложенной структуре vnesh к переменной а мы должны через точку обратиться к этой переменной: с. а. А когда мы обращаемся к вложенной структуре vnut, то точек будет уже две: с. b.b и с. Ь. с. То есть сначала мы обращаемся к переменной struct vnesh с, а затем через описатель b — к объектам структуры vnut.
Обратите внимание,
что после вложенной
структуры введен описатель Ь, который сообщает, что пеоед обращением к членам вложенной структуры vnut нужно обращаться как «Ь, точка, имя переменной» в структуре vnut.
I4J
Go
Типы данных, определяемые пользователем
Переменные типа объединения и особенности их использования
Еще одним вариантом группировки данных являются объединения, В языке C++ существуют ограничения на их применение; во-первых, они не могут наследовать какой бы то ни было класс и не могут являться базовым классом для другого класса; во-вторых, объединения не могут иметь статических членов; в-третьих, они не могут содержать объекты с конструктором или деструктором, хотя сами могут иметь и конструкторы, и деструкторы.
"Г
ГГ) гч
Одним из вариантов применения объединения являются анонимные объединения, которые не имеют имени типа, поэтому нельзя объявить переменную с таким типом. Единственное назначение анонимных объединений — объявить компилятору, что все его члены находятся в одной области памяти. На этом назначение объединений и заканчивается.
Синтаксис анонимного объединения:
union{
int X;
double у;
string zet;
};
В отличие от классов и структур, доступ к членам анонимного объединения осуществляется непосредственно, без использования оператора «точка». Анонимное объединение не может содержать закрытых членов.
Объединения, так же как и структуры, используются в основном в библиотеках и функциях.
Объединение union — это определяемый пользователем тип, в котором все члены совместно используют одно расположение памяти. Это определение означает, что union в любое время может содержать не более одного объекта из списка элементов. Это также означает, что, независимо от количества элементов, union всегда используется достаточно памяти для хранения самого большого элемента. Поэтому размер объединения равен размеру его наибольшего члена. В любой момент объединение хранит значение только одного из членов.
Объединения разделяются на обычные и анонимные.
Использование обычного объединения обозначает, что имеется намерение задействовать только одну ячейку памяти компьютера, в которую будут подставляться значения переменных, объединенных в одну группу и имеющих разные типы. Например:
union RecordType {
string ch;
int i;
long I;
float f; double d;
int *int ptr;
};
int main()
{
RecordType t;
Перед использованием переменные объявляются. Для каждой переменной указывается тип значения, которое может храниться в переменной.
Тип переменной определяется через ключевое слово — идентификатор типа (самые актуальные базовые типы: int (целые числа), double (действительные числа), char (символы)).
UJ
(Л
t i = 5;
tf = 7.25;
Типы данных, определяемые пользователем
Необходимо напомнить, что объединения хранят в памяти только последний использовавшийся объект. Например:
#incluae <iostream> using namespace std; union MicroUnion { short x;
int y:
};
int main() {
MicroUmon un;
MicroUnion un x = 1000; un.y - 222; cout« un x; return [J; }
Ответ:
222
Ответ кажется неожиданным: мы только что присвоили переменной un.x = 1000, а ответ почему-то пришел совсем от другой переменной. Это произошло потому, что последним объявлением была переменная un.y = 222, а в памяти хранится именно последняя использовавшаяся переменная. Поэтому переменная ип.х тоже получила значение 222.
Анонимные объединения — это те же объединения, но у них нет имени и объектов, созданных на их основе. У таких объединений есть несколько особенностей:
в анонимном объединении должны быть сгруппированы только нестатические данные-члены;
в анонимных объединениях нельзя объявлять вложенные типы, анонимные объединения и функции (компиляторы мотут компилировать код, в котором анонимные объединения вложены в другие анонимные объединения, но это нарушает правила языка С4-+);
имена членов анонимного объединения должны отличаться от имен других объектов в области видимости, в которой объявлено анонимное объединение;
анонимные объединения, объявленные в именованных или глобальных пространствах имен, должны быть объявлены как статические;
анонимные объединения, объявленные в объявлениях области видимости блока, должны быть объявлены в любом классе памяти, разрешенном для переменных в области видимости блока, или без указания класса памяти;
анонимные объединения в объявлениях области видимости класса могут не указывать класс памяти;
анонимные объединения не должны иметь скрытых или защищенных членов;
анонимные объединения не должны содержать функции-члены.
Типы данных, определяемые пользователем
Если для объединения объявлены объект, указатель или ссылка, оно не считается анонимным объединением. Например:
ttinclude <iostream.h> using namespace std: int main()
{
union{
int i;
char ch[2];
/* обращение к i и ch без ссылки на объединение и без использования операторов "точка " или ’стрелка" */
i = 120:
cout« i « " " « ch[O];
return J,
}
со m rsj
Ответ:
120 x
Английская строчная буква х в таблице ANSI находится в 120-й ячейке. Поэтому эта буква и была выдана в ответе. Если переменная i получит значение 88, то буква будет прописная — X.
Заключение
•	Перечисление enum — это определяемый пользователем тип, состоящий из набора именованных целочисленных констант, которые называются перечислителями.
•	Индекс перечисления enum начинается с 0, но можно указать стартовое значение отсчета, например «1». Во всех других элементах перечисления индекс увеличится на стартовое значение.
•	Перечисление enum может быть анонимное, т. е. имя перечисления не указывается.
•	Квалификатор typedef — это зарезервированное ключевое слово в языке программирования С-1-+. Он используется, чтобы создать дополнительное имя (псевдоним) для другого типа данных, но не создает новый тип, за исключением неявного случая квалифицированного typedef типа массива, где квалификаторы typedef передаются типу элемента массива.
•	Структура представляет собой набор данных различных типов, объединенных общим именем. Структура может включать как даппые-элементы, так и функции-элементы. В состав структуры могут входить конструкторы и деструкторы.
•	Объявление структуры создает шаблон структуры, определяющий новый тип, имя которого можно использовать наряду со стандартными типами.
•	Объединения union в C++ могут создаваться для экономии памяти, когда нужно хранить и использовать данные разных типов; но обращаться
239
Типы данных, определяемые пользователем
к ним можно не одновременно, так как в памяти можно хранить только одну — последнюю — переменную.
•	Объединение union - эго определяемый пользователем тип, в котором все члены совместно используют одно расположение памяти.
•	В отличие от классов и структур, доступ к членам анонимного объединения осуществляется непосредственно, без использования оператора «точка».
•	Анонимное объединение не может содержать закрытых членов.
ГЧ
Основы объектно ориентированного программирования
242 Основные принципы объектно ориентированного программирования
243 Инкапсуляция
245 Полиморфизм
251 Наследование
254 Определение класса и структуры в С++
258 Поля и методы класса
261 Спецификаторы управления доступом
268 Объекты
270 Конструкторы
273 Деструкторы
274 Правила объявления конструкторов и деструкторов в производных классах
278 Дружественные функции
282 Заключение
Основы объектно ориентированного программирования
Не всегда нужно, чтобы к некоторым компонента класса был прямой доступ извне.
Для разграничения доступа к различным компонентам класса применяют спецификаторы доступа.
Спецификатор public делает члены класса открытыми, доступными из любой части программы. Спецификатор private скрывает реализацию членов класса, то есть делает их закрытыми, инкапсулирует внутри класса.
Основные принципы объектно ориентированного программирования
Язык C++ базируется на трех понятиях: инкапсуляция, полиморфизм и наследование.
Инкапсуляция
Инкапсуляция в программировании — это способ предотвращения несанкционированного доступа к закрытым частям программы. Она основана на понятии объектов и классов. В C++ инкапсуляция реализуется через указание уровня доступа к членахМ класса: public («публичный»), protected («защищенный») и private («закрытый»), В C++ структуры и классы отличаются лишь тем, что у структур по умолчанию уровень доступа и тип наследования публичные, а у классов — закрытые.
Проверка доступа происходит во время компиляции. Попытка обращения к недоступному члену класса вызовет ошибку компиляции.
Рассмотрим пример с использованием инкапсуляции:
^include <iostream> using namespace std; class Rectangle{ private
// переменные, необходимые для расчета площади int length, int breadth, public
void setLengthfint !en){
length = ien;
}
// функция настройки ширины
void setBreadth(int brth){
breadth = brth;
}
// функция для получения длины
int getLength(){
return length;
}
// функция для получения ширины
int get Brea drh(){
return breadth;
}
// функция иля вычисле ния площади
int get Area(){
return length * breadth;
}
};
int mam(){
// создание объекта класса Rectangle
Rectangle rectanglcl;
// инициализоц	Олины с помощью функции
set Length
rectanglel setLcngth(134);
// инициализация ширины с помощью функции
rectanglel setBreadth(159);
на доступа с иг	функции
получения
cout« "Длина = " « rectanglel getlengthf) « "\n"; // ширина доступа с помощью функции получения cout« "Ширина = " « rectanglel getBreadth() « "\n";
// вызов функции getArea()
cout« "Площадь = " « rectanglel getArea();
return 0;
}
Ответ:
243
Все компоненты, KOTOObie определяются после спецификатора private и идут до спецификатора public, — закрытые, приватные.
Длина = 134
Ширина = 159
Площадь = 21306
Основы объектно ориентированного программирования
Если для каких то компонентов отсутствует спецификатор доступа, то по умолчанию применяется спецификатор private.
К инкапсуляции относится такое понятие, как «функции-друзья», — это функции, не являющиеся функциями-членами и тем не менее имеющие доступ к защищенным и закрытым членам класса. Они должны быть объявлены в теле класса как friend Например:
class Matrix{
friend Matrix MultiplyjMatrix ml, Matrix m2);
};
Полиморф ИЗМ
Полиморфизм — это возможность использовать конкретное действие для разных ситуаций. Например, арифметическое действие обозначается одним знаком (+, —, *, /), одним действием, несмотря на то, что в конкретной переменной могут быть различные типы данных (целые, короткие целые, длинные целые, числа с плавающей запятой разной длины и т. д.).
Реализовать полиморфизм в Он можно следующими способами:
•	перегрузкой функций;
•	перегрузкой операторов; переопределением функций; виртуальными функциями.
C++ поддерживает динамический полиморфизм и параметрический полиморфизм.
Параметрический полиморфизм в C++ — это возможность многократно использовать один и тот же код применительно к разным типам данных.
Параметрический полиморфизм представлен:
•	аргументами по умолчанию для функций.
К примеру, для функции void f(int х = 1, int у = 5, int z = 10) вызовы f( 1), f(l, 5) и f(l, 5, 10) эквивалентны;
•	перегрузкой функций.
Функция с одним именем может иметь разное число и разные по типу аргументы, например:
void Printfint х);
void Print(double х);
void Printfint x, int y);
Частным случаем перегрузки функций можно считать перегрузку операторов.
Динамический полиморфизм реализуется с помощью виртуальных методов и иерархии наследования. Полиморфным в C++ является тип, имеющий хотя бы один виртуальный метод. Пример иерархии:
245
Наследование — поинцип повторного использования кода, при котором один объект может приобретать свойства доугого. Полиморфизм подтипов — СВОЙСТВО системы, позволяющее использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
Основы объектно ориентированного программирования
class Figure
{
public
virtual void Draw}) = 0;
метод
virtual "Figured;
виртуального метода деструктор следует сделать виртуальным
};
class Square: public Figure
{
public
void Draw() override;
};
class Circle: public Figure
{
public
void Draw() override;
};
Здесь класс Figure является абстрактным, так как метод Draw не определен. Объекты данного класса нельзя создать, зато можно использовать ссылки или указатели с типом Figure. Выбор реализации метода Draw будет производиться во время выполнения, исходя из реального типа объекта.
Полиморфизм с перегрузкой функций.
В нашем примере используется три функции с одним и тем же именем и именами переменных. В первой функции sum используются целые числа numl и num2. Во второй функции sum используются дробные числа numl и num2. В третьей функции используются цельте числа numl, num2 и num3. В С++-мы можем использовать несколько функций с одинаковыми именами, если они имеют разные параметры (типы или количество аргументов). И в зависимости от количества или типа аргументов вызываются разные функции, например:
ttinclude <iostream>
using namespace std,
// функция с двумя целыми параметрами
int sumjint numl, int num2){
return numl + num2;
}
// функция с двумя дробными параметрами double sum(double numl, double num2){ return numl + num2;
}
// функция с тремя целыми параметрами
int sum(int numl, int num2, int num3}{
return numl + num2 + num3,
}
int mainf)
{
функции с	.рамс
cout« "Sum 1 = " « sum(ll, 19) « "\n";
// вызов функции с двумя дробными параметрами cout « "Sum 2 = " « sum(11.5, 22.6) « "\n";
// вызов функции с тремя целыми параметрами cout« "Sum 3 = " « sum(14,17, 67) « "\n";
return 0;
}
Ответ:
Sum 1 - 30
Sum 2 = 34.1
Sum 3 = 98
В зависимости от количества или типа аргументов вызываются разные функции.
247
Полиморфизм с перегрузкой операторов, В C++ можно перегружать оператор, если используются пользовательские типы, такие как объекты классов или структур. Нельзя использовать перегрузку операторов для базовых типов, таких как int, double и т. д. Перегрузка операторов — это, по сути, перегрузка функций, когда разные операторные функции имеют один и тот же символ, но разные операнды.
В зависимости от операндов выполняются различные операторные функции.
Основы объектно ориентированного программирования
Например:
^include <iostream>
using namespace std:
class Count{
private
int value;
public
//конструктор для инициолизоции число до.
Count(): vaIue(5){}
// псрв^рузко при использовании в качеств префикса
void operator 4-+()
{
value = value + 1;
}
void display(){
cout« "рассчитано:" « value « "\n";
}
};
int main()
{
Count countl;
++countl;
countl display();
return D.
}
Ответ:
6
Полиморфизм с переопределением функции C++. В наследовании C++ можно использовать одну и ту же функцию как в базовом классе, так и в сто производных классах. При вызове функции с помощью объекта производного класса вместо функции в базовом классе выполняется функция производного класса. То есть в зависимости от объекта, вызывающего функцию, выполняются разные функции. В С+т это называется переопределением функции. Например:

^include <iostream> using namespace std, class Base
public
virtual void print(){
cout« "базовая функция” « "\n";
class Derived: public Base
249
public
void print(){
cout« "производная функция" « "\n";
int main(){
Derived derived 1;
//вызов функции printf) производного класса
derivedl pdnt();
return 0;
Ответ:
производная функция
Основы объектно ориентированного программирования
Полиморфизм с виртуальными функциями C++. В C++ нельзя переопределить функции, если используется указатель базового класса для указания на объект производного класса. Использование виртуальных функций в базовом классе гарантирует, что функция в этих случаях может быть переопределена. Виртуальные функции фактически подпадают под переопределение функций. Например;
^include <iostream>
using namespace std;
class Base{
public
virtual void print(){
cout « "базе лая функция" « "\n";
}
};
class Derived, public Base<
public
void print(){
cout« "производная функция" « "\n";
}
};
int main()
{
Derived derivedl;
Base * basel = &derivedl;
basel -> print();
return 0;
}
Ответ:
производная функция
Наследование
Наследование — это возможность объекта наследовать свойства других объектов. Для более широкого понимания можно привести конкретный пример. Возьмем понятие транспорта. Эго понятие включает такие характеристики, как скорость и грузоподъемность. Транспорт, в свою очередь, разделяется на сухопутный, морской и воздушный, каждый из которых добавляет свои уникальные свойства к общему. Например, воздушный транспорт имеет высоту полета; воздушный транспорт, в свою очередь, делится на гражданский и военный и т. д.
В C++ можно использовать множественное наследование. В заголовке описания класса указываются базовые классы (классы-предки), возможно, с указанием спецификаторов доступа. Наследование от каждого класса может быть публичным, защищенным или закрытым. По умолчанию базовый класс наследуется как private.
При наследовании класс-потомок получает все поля и методы классов-предков. Экземпляр класса-потомка содержит подэкземпляр каждого из классов-предков. Если один класс-предок наследуется несколько раз, то экземпляры класса-потомка будут содержать соответствующее количество подэкземпляров данного класса-предка. Чтобы избежать этого эффекта, C++ поддерживает виртуальное наследование. При виртуальном наследовании создается только один подэкземпляр класса-предка в дереве наследования класса-потомка.
Производный класс объявляется с помощью следующего синтаксиса: class <имя потомка> кодификатор наследования> <имя родительского класса>{};
го
СП
При наследовании класс-потомок получает все поля и методы классов-предков. Экземпляр класса-потомка содержит подэкземпляр каждою из классов-предков.
Основы объектно ориентированного программирования
После имени класса следует двоеточие и список базовых спецификаций. Базовые спецификации могут содержать описатель доступа, который является одним из ключевых слов public или protected. Эти описатели доступа отображаются перед именем базового класса и применяются только к базовому классу. Описатель доступа protected работает как private, но распространяется и на свойства предка. Эти описатели контролируют разрешение производного класса на использование членов базового класса.
Если описатель доступа опущен, доступ к этой базе считается private. Базовые спецификации могут содержать ключевое слово virtual для указания виртуального наследования. Это ключевое слово может отображаться до или после описателя доступа, если таковой имеется. Если используется виртуальное наследование, базовый класс называется виртуальным базовым классом.
Можно определить несколько базовых классов, разделив их запятыми. Если указан один базовый класс, модель наследования является одним наследованием. Если указано несколько базовых классов, модель наследования называется множественным наследованием. Использовать можно public и protected родительского класса. Например:
class Ammals{ public int counter; щее количество животных protected int penguin;
int boa; int hog; //функция вычисления общего количество
животных
count_animals(){ counter = hog + boa + penguin;
}
set_hogs(int count_.of_hogs){ hogs = count_of_hogs;
} };
class Hog public Ammals{
public
int count_hogs(){ return hogs;
} };
С описателем доступа private можно пользоваться только свойствами (не функциями) родителя. Чтобы использовать функции, нужно разрешить это напрямую (и без круглых скобок, только имя), и разрешать нужно в публичном доступе (public). Делается это так:
<родительский клэсс>::<свойства>;
Пример:
class Pig: private Animals{ public
int count_pigs(){ return pigs, }
Animals: set_pigs;
};
int main(){
Pig piggy int p,-cout« "Введите количество хрюшек: cin » p;
Piggy set ptgs(p);
cout« "Количество хрюшек равняется:" « piggy ccunt_pigs();
return 0;
Основы объектно ориентированного программирования
Список_объектоБ в объявлении классов необязателен. Их можно объявить позже.
Определение класса и структуры в C++
Классы в языке C++ являются фундаментом, расширяющим возможности этого языка. При изучении переменных были перечислены основные типы данных. Теперь мы переходим на качественно новый этап изучения типов данных — производные типы данных. Одно из главнейших достоинств классов заключается в том, что классы создают новые производные типы данных. Это уже не основные типы данных int, double и так далее, а принципиально новые типы.
Класс объявляется с помощью ключевого слова class:
class Имя_класса{
private:
закрытые переменные и функции класса
public:
открытые переменные и функции класса
protected
защищенные переменные и функции класса
} список_объсктов;
Последнее понятие — список_объектов -в объявлении классов необязателен. Они могут быть объявлены позже.
Все члены класса изначально являются закрытыми и недоступными для нечленов класса. Если спецификатор доступа не указан для переменных и функций класса, то они считаются закрытыми, причем спецификатор private считается присутствующим по умолчанию и его можно не указывать явно. Члены класса, объявленные после слова public, доступны как для других членов класса, так и для любой части программы. Спецификаторы
доступа (public, private, protected)
указываются после двоеточия, за которым следует перечисление открытых, закрытых или защищенных членов класса.
Все члены класса указываются между фигурных скобок, после чего следует точка с запятой, которая сообщает, что объявление класса закончено.
Пример объявления класса:
class MyClass{
int АА-
double ВВ;
char string! nJ;
public
void Summa(int XX);
};
В закрыт ой части класса объявлены три закрытых члена класса (при этом слово private опущено), в открытой части класса объявлена одна функция с аргументом. Функции, которые объявляются внутри класса, называются функциями-членами.
Кроме использования встроенных типов, таких как int, doable и т.д., можно определять свои собственные типы или классы. Класс представляет составной тип, котооый может использовать другие типы
Использовать все три переменные, объявленные в закрытой части класса, можно только с помощью единственной функции, объявленной в открытой части класса. Функция-член, объявленная в открытой части класса, может вызываться из любой части программы, использующей объявленный класс MyClass.
Функция, объявленная внутри класса, не определена. Чтобы определить функцию-член, необходимо связать имя класса, частью которою является функция-член с именем функции. Эта связь осуществляется через оператор расширения области видимости:
Основы объектно ориентированного программирования
Если закрытой части класса нет, то и искусственных функций создавать не нужно.
void MyClass Summafint XX) {
AA = XX
return AA;
}
Единственное назначение функции Summa() в данном случае — это связать закрытые члены класса с программой.
Если закрытой части класса нет, то и искусственных функций создавать тоже не нужно. Например, если все три переменные определить как открытые, то доступ к ним облегчен:
class MyClass{
public int AA double BB; char string[n]; };
В самом начале изучения классов уже говорилось, что классы создают новые типы данных, их объявление абсолютно не отличается от объявления переменных:
MyClass Objectl, Object2;
Тип этого объекта будет не double, не char и не int, с которыми мы до сих пор работали, а совершенно иной, описанный именно классом MyClass. Но сущность их содержания принципиально меняется. Если основными типами данных мы обьявляли переменные, то теперь — с помощью производных типов данных, созданных на основе классов, — мы об ьявляем не переменные, а объекты. Создание объектов позволило сделать революционный скачок в программировании.
Если при объявлении класса не был создан ни один объект, то в памяти ничего не создается. Объявление класса всего лишь абстракция, подготовка к созданию нового типа объекта. Созданные ранее классы можно использовать в дальнейшей работе, подключив файл, в котором описан класс с помощью директивы ttinclude
Кроме классов, существуют еще две возможности группирования: структуры и объединения.
Структура представляет собой набор данных различных типов, объединенных общим именем. Структура может включать как данные-элементы, так и функции-элементы. В состав структуры могут входить конструкторы и деструкторы. Все это делает классы и структуры очень близкими понятиями. Принципиальное расхождение между ними заключается в гом, что если члены класса по умолчанию являются закрытыми, то члены структуры являются открытыми.
Основы объектно ориентированного программирования
Л__/с
о<>
оо in сч
Поля и методы класса
После объявления класса в нем определяют поля и методы. Поля класса — это объекты любого типа. Набор полей и их значения определяют состояние объекта. Методы — это функции, связанные с классом. В список переменных, доступных для метода, неявно попадают все поля структуры или класса, в котором он объявлен. В теле класса (между фигурными скобками) могут находиться данные (переменные базовых типов и строки), функции, принадлежащие классу. Функции, которые объявлены и (или) определены в теле класса, — это методы класса.
Например:
class Ва$е{
// по умолчанию необъявленная область является private
double t_;
double x_;
public
// константный публичный метод
double t() const{
return t_;
}
// константный публичный метод
double x() const[
return x_;
}
// публичный метод
double & t(){
return t_j
}
// публичный метод
double & x(){
return x_;
}
};
Поля и методы класса могут быть открытыми (public) или закрытыми (private). К публичным методам и полям можно обращаться при работе с объектом класса. Приватные поля и методы доступны только внутри методов самого класса. Ключевые слова private и public выполняют переключение на закрытую и открытую части класса. Б соответствии с принципом инкапсуляции поля объявлены в закрытой части класса.
Поля и методы могут быть константными. Делая метод константным, разработчик гарантирует, что при вызове объекта видимое состояние этого объекта не изменится. Указывать константность метода не обязательно.
C++ требует, чтобы каждый метод класса был упомянут в определении этого класса.
Существует два способа определения функций, принадлежащих классу:
•	внутреннее определение класса;
•	определение внешнего класса.
В следующем примере функция myMethod определяется внутри класса:
class MyClass{ public
void myMethcd(){
деленн; внутри класса
cout« "Функция myMethod определяется внутри класса MyClass!";
}
};
int main(){
MyClass myObj;
MyClass
myObj myMethod();
return 0;
259
Основы объектно ориентированного программирования
В C++ есть не только обычные указатели, но и специфические — указатели на члены класса. Это особый вид указателей, который указывает не на конкретный объект, а на само поле или метод внутри определения класса.
Чтобы определить функцию вне определения класса, нужно объявить ее внутри класса, а затем определить ее вне класса. Это делается путем указания имени класса, за которым следует оператор разрешения области::, а за ним — имя функции:
class MyClass{ public
void myMethod();
};
MyClass myMethodO
void{ определение метода или функции вне класса cout« "Функция myMethod определяется вне класса MyClass!";
}
int main(){
MyClass myObj;
myObj myMethod();
return 0;
}
Если обычный указатель хранит абсолютный адрес в памяти, то указатель на член класса хранит смещение (offset) поля данных или адрес функции-члена относительно начала любого объекта этого класса. Эти указатели применяются только к конкретному экземпляру класса.
Спецификаторы управления доступом
Спецификаторы доступа — это ключевые слова в объектно ориентированных языках, которые задают доступность классов, методов и других членов. Спецификаторы доступа — это особая часть синтаксиса языка программирования, используемая для облегчения инкапсуляции компонентов.
В C++ есть три спецификатора доступа (табл. 15).
Таблица 15
Управление доступом к членам класса
Спецификатор доступа	Значение
private	Члены класса, объявленные как private, могут использоваться только функциями-членами и «друзьями» (классами или функциями) класса
protected	Члены класса, объявленные как protected, могут использоваться функциями-членами и «друзьями» (классами или функциями) класса. Кроме того, они могут использоваться производными классами данного класса
public	Члены класса, объявленные как public, МОЖНО ИСПОЛьЗОВсТЬ любой функцией
261
Управление доступом с помощью спецификаторов доступа помогает предотвратить использование объектов запрещенными способами. Эта защита теряется при выполнении явных преобразований типов (приведения типов).
Основы объектно ориентированного программирования
Управление доступом в производном классе. Доступность в производном классе членов базового класса и унаследованных членов определяется двумя следующими факторами:
•	объявляет ли производный класс базовым классом public с помощью спецификатора доступа;
•	какой доступ к членам класса предоставляется в базовом классе.
В табл. 16 показана взаимосвязь этих факторов и определен доступ к членам в базовом классе.
Таблица 16
Доступ к членам в базовом классе
private	protected	public
Всегда недоступно с любым доступом к производным данным
private в производном классе, если используется private-производное
protected в производном классе, если используется protected-производное
public в производном классе, если используется public-пооизводнос
В следующем примере показано наследование доступа:
class BaseClass
{
private
int PrivateFunc();
public
int PublicFuncf);
protected
int ProtectedFunc();
},
// объявление двух классов, производных
class DerivedClassl. public BaseClass
{
void foo()
{
PubiicFunc();
ProtectedFuncf);
PrivateFunc();
}
};
class DerivedClass2: private BaseClass
{
void foo()
{
Pub!icFunc();
ProtectedFunc();
PrivateFunc();
}
};
int main() {
DerivedClassl denvod_classl;
DerivedClass2 derived_class2; derived_classl PublicFunc(); derived_class2 PublicFunc(); }
В DerivedClassl функция-член PublicFunc является членом класса BaseClass co спецификатором public. Функция-член ProtectedFunc является членом класса BaseClass со спецификатором protected, так как BaseCEass является базовым классом public. Функция-член PrivateFunc является членом класса BaseClass со спецификатором private и недоступна для всех производных классов.
263
Основы объектно ориентированного программирования
В классе DerivedClass2 функции PublicFunc и ProtectedFunc считаются private-членами, так как BaseClass объявляется базовым private-классом. Это значит, что функция PrivateFunc со спецификатором private класса BaseClass недоступна для любых производных классов.
Производный класс можно объявить без спецификатора доступа базового класса. В таком случае производный класс считается private, если объявление производного класса использует ключевое слово class. Производные считаются public, если объявление производного класса использует ключевое слово struct.
Например, приведенный ниже код:
class Derived: Base
эквивалентен правилу:
class Derived: private Base
Аналогично код:
struct Derived Base
эквивалентен правилу:
struct Derived: public Base
Члены, объявленные как private- имеющие
Тип union не может иметь базовый класс
доступ, недоступны для функций или производных классов, если эти функции или классы не объявлены с помощью
дружественных функций (friend) объявления в базовом классе.
Тип union не может иметь базовый класс.
При указании private базового класса рекомендуется явно использовать ключевое слово private, чтобы пользователи производного класса понимали порядок доступа к члену.
При указании базового класса как private он влияет только на нестатические члены. Открытые статические члены но-прежнсму доступны в производных классах. Однако доступ к членам базового класса с помощью указателей, ссылок или объектов может потребовать преобразования, который снова применяет управление доступом. Например:
class Base
{
public
int Print();
static int CountOff);
};
class Derivedl: private Base {
};
265
class Derived2 public Derivedl
{
int ShowCountO;
};
Если переменные или функции в базовом классе являются закрытыми, то есть объявлены со спецификатором private, го производный класс хоть и наследует эти переменные и функции, он не может к ним обращаться.
int Derived2 ShowCount() {
int cCount =:: Base CountOff);
cCount = this -> CountOff);
return cCount;
Основы объектно ориентированного программирования
Иногда возникает необходимость в
таких переменных и функциях базового
класса, которые были бы доступны
в производных классах, но не были бы доступны извне. То ость тот же private, только с возможностью доступа для производных классов.
Для определения
уровня доступа подобных членов класса используйте спецификатор protected
В предыдущем примере код управления доступом запрещает преобразование указателя на Derived? к указателю на класс Base. Указатель this неявно имеет тип Derived?*. Чтобы выбрать функцию CountOf, необходимо преобразовать this в тип Base*. Такое преобразование не допускается, так как класс Base является косвенным базовым классом Derived? со спецификатором private. Преобразование в private-тип базового класса допустимо только для указателей на непосредственные производные классы. Поэтому указатели типа Derived 1* можно преобразовать в тип Base*.
Явный вызов CountOf функции без использования указателя, ссылки или объекта для его выбора не подразумевает преобразования. Именно поэтому вызов разрешен.
Доступ к виртуальным функциям. Управление доступом, применяемое к виртуальным функциям virtual, определяется типом, используемым для вызова функции. Переопределение объявлений функции не влияет на управление доступом для данного типа.
Например:
class VFuncBase
{
public
virtual int GetState(){return _state;}
protected
int _state, };
class VFuncDerived; public VFuncBase
{
private
int GetState(){return state;}
};
int main()
{
VFuncDerived vfd;
VFuncBase *pvfb = &vfd;
VFuncDerived *pvfd = &vfd;
int State;
State = pvtb > GetState();
State = pvtd -> GetState();
}
В предыдущем примере вызов виртуальной функции GetState с помощью указателя на вызовы VFuncDerived:: GetState типов VFuncBase и GetState рассматривается как спецификатор public. Однако вызов GetState с помощью указателя типа VFuncDerived является нарушением управления доступом, так как GetState объявляется со спецификатором private в классе VFuncDerived.
Виртуальную функцию GetState можно вызвать с помощью указателя на базовый класс VFuncBase. Это не означает, что вызываемая функция является базовой версией этой функции.
267
Основы объектно ориентированного программирования
Объекты
Классы в Си- — это абстракция, описывающая методы и свойства еще не существующих объектов. Объекты — конкретное представление абстракции, имеющее свои свойства и методы. Созданные объекты на основе одного класса называются экземплярами этого класса. Эти объекты могут иметь различное поведение и свойства, но все равно будут являться объектами одного класса.
Объекты создаются из классов. Объекты класса объявляются аналогично объявлению переменных. Имя класса должно начинаться с имени объекта.
Синтаксис объекта следующий: class-name object-name;
где class-name (имя класса) — это имя класса, из которого должен быть создан объект; object-name (имя объекта) — это имя, которое будет присвоено новому объекту.
Процесс создания объекта из класса называется созданием экземпляра.
Для получения доступа к открытым членам класса (public) используется оператор «точка». Например:
ttinclude <iostream> using namespace std, class Port{ public double cost;
int slots:
};
int main()
{
Port abc;
Port def,
abc cost = 199.0;
abc slots = 23;
def cost = 399.0;
def slots = 24;
cout « "Стоимость abc: " « abc cost « "\n";
cout« "Стоимость def:" « def cost« "\n";
cout« "Число портов abc: " « abc slots « "\n"; cout« "Число портов def:" « def slots « "\n"; return 0;
}
Ответ:
Сюимосгь abc: 199
Стоимость def: 399
Число портов abc: 23
Число портов def: 24
269
Основы объектно ориентированного программирования
Конструкторы
Конструктор и деструктор класса являются особыми функциями. Конструктор предназначен для инициализации создаваемых объектов, а деструктор — для освобождения памяти от созданных объектов этого класса.
Конструктор вызы вается всякий раз, как только создается объект.
Конструктор получает то же имя, что и имя класса. Десзруктор отличается от имени класса тем, что его первый символ — тильда (~). Например:
class MyClass{
int АА
double SB,
char Family[25];
public
MyClass();
~MyC lass();
void Summafint XX);
};
Так как это функции, их, так же как и обычные функции, необходимо связать с именем класса:
MyClass MyClassf);
(...)
MyClass :~MyClass();
{...}
В фигурных скобках описывается тело функции. В этом примере конструктор и деструктор приведены без аргументов.
Конс1руктор и деструктор являются функциями, поэтому они могут производить любые операции. Но использовать их для других, неспецифичиых операций считается признаком плохого стиля программирования. Поэтому их нужно использовать в общепринятых случаях.
Конструктор может получать аргументы как обычная функция. Деструктор не может получать никаких аргументов, так как его единственное назначение — освободить память от объектов класса. Например:
class dwa{
int nnomer:
char name[25];
dauble koi;
double zena.
double itogo;
public
dwafint nn, char *n, double, double z);
~dwa();
void show();
};
dwa dwa(int nn, char *n, double, double z)
{
nnomer = nn;
strcpy(name, n);
koi = k;
zena = z;
itogo = ko! * zena,
}
dwa::~dwa()
{
cout« "Удаление объекта: \n";
}
void dwa show()
{
return nnomer + 1;
Конструктор получает аргументы и выполняет инициализацию объектов, конструктор без деструктора применяться может, а деструктор без конструктора — нет.
Основы объектно ориентированного программирования
В закрытой части данното примера объявлены пять переменных, доступ к которым возможен через конструктор. В конструкторе объявлены другие пять переменных, которые не я вляются самостоятельными, они всего лишь псевдонимы переменных из закрытой части класса и нужны только для их обслуживания.
В закрытой части имеется пять переменных, к которым подобраться можно только через открытую часть. В этой открытой части создается конструктор, в котором объявлены не пять переменных, а только четыре. Пятый аргумент просто рассчитывается в ходе привязки конструктора к имени класса.
Деструкторы
Деструктор, как правило, не имеет аргументов, но в процессе привязки к имени класса может содержать операторы, например сообщение о начале работы деструктора:
dwa::'Jawa()
{
cout « "Удаляется объект \п";
}
После того как мы объявили о создании класса, после фигурных скобок ставится точка с запятой; после привязки конструктора, деструктора и обычных функций (например, void dwa:: show()) точка с запятой не ставится ни после каждой функции, ни после общего блока привязки этих функций к имени класса.
Обратите внимание на особенность конструктора и деструктора: хотя они и являются функциями, мы не объявляем их тип. В обычной функции show(), которую мы используем в этом же примере, в качестве типа данных используется тип void, в связке функции с именем класса опять используется этот же тип, а при работе с конструктором и деструктором тип не указывается, так как их тип определяет класс.
Основы объектно ориентированного программирования
Правила объявления конструкторов и деструкторов в производных классах
При объявлении конструкторов и деструкторов в производных классах языка C++ действуют следующие правила:
•	имя конструктора, если он есть, совпадает с именем класса;
функция деструктора, если он есть, имеет имя, совпадающее с именем класса, но ему предшествует символ тильда (~);
•	при создании объекта производного класса конструкторы вызываются вниз по иерархии наследования классов, начиная с самого базового класса и заканчивая производным классом;
•	деструкторы вызываются в обратном порядке;
•	при множественном наследовании при объявлении производного класса базовые классы перечисляются через запятую, при создании объекта конструкторы выполняются в порядке следования базовых классов слева направо.
Пример:
^include <iostream.h>
class Base{
public
Base(){cout « "\n Создание Base \n";}
};
class A classf): public Base{
public
A_class(){cout« "Создание A_class \n";}
};
int mam()
{
A_class al;
return 0;
}
Данная программа создает производный класс A_class, а затем создает объект al типа A_dass. Все сообщения выводятся на консоль для наглядности выполнения программы. На консоль выводится сообщение «Создание Base», а затем — сообщение «Создание A_class».
Здесь al является объектом типа A_class, производным класса Base. При создании объекта al сначала вызывается конструктор Base(), а затем вызывается конструктор A_class().
Конструкторы классов вызываются в том же порядке, в каком классы следуют друг за другом в иерархии наследования классов. Инициализация базового класса предшествует инициализации производного класса. В противном случае инициализация производного класса не может быть выполнена, поскольку производный класс наследует от базового.
СП
Конструкторы классов вызываются в том же порядке, в каком классы следуют друг за другом в иерархии наследования классов.
Основы объектно ориентированного программирования
Для деструкторов производных классов все выполняется наоборот. Деструктор производного класса вызывается раньше деструктора базового класса. Деструктор производного объекта должен быть вызван до вызова деструктора базового объекта, потому что уничтожение объекта базового класса приведет к уничтожению объекта производного класса. Например:
tfindude <iostream.h>
class Base{ public Base(){cout« "\n Выполнение конструктора Base \n";}
~Base(){cout« "Выполнение деструктора Base \n\n";}
};
class A_class(): public Base{
public
A_class(){cout« "Вэшолнение конструктора A_class \n";}
~A_class(){cout« "Выполнение деструктора A_class \n”;}
};
int main() {
A_class al;
cout« " \n";
return 0;
}
При выполнении программы на консоль будут выведены следующие сообщения:
Выполнение конструктора Base Выполнение конструктора A_class Выполнение деструктора A_class Выполнение деструктора Base
Производный класс может выступать в качестве базового класса для создания следующего производного класса. В этом случае конструкторы выполняются в порядке наследования, а деструкторы — в обратном порядке:
^include <iostream.h>
class Base{
public
Base(){ccut « "Выполнение конструктора Base \n";} ~8ase(){cout« "Выполнение деструктора Base \n";} };
class A_class(): public Base{
public
A_class(){cout« "Выполнение конструктора A_class
\n";}
~A_class(Kcout« "Выполнение деструктора A_dass \n";}
};
class B class public A_class{
public
B_class(){cout « "Выполнение конструктора B_dass \n";}
~B_class('{cout « "Выполнение деструктора B_class \n",}
};
int mainp
{
A class al;
B_class Ы;
cout« "\n";
return i)
}
На консоль будут выведены сообщения в порядке выполнения команд программы:
Выполнение конструктора Base
Выполнение конструктора A_class
Выполнение конструктора Base
Выполнение конструктора A_class
Выполнение конструктора B_class
Выполнение деструктора B_class
Выполнение деструктора A_class
Выполнение деструктора Base
Выполнение деструктора A_class
Выполнение деструктора Base
Основы объектно ориентированного программирования
К закрытой части класса можно подобраться не только открытым членам класса, и не только членам данного класса. Просто поставьте перед именем нужной функции ключевое слово friend.
Дружественные функции
Основой инкапсуляции в C++ являются классы. К членам класса подобраться со стороны довольно трудно, а чаше — просто невозможно. На первый взгляд, классы созданы для того, чтобы искать на свою голову приключений, создавать себе и другим дополнительные трудности. Но поскольку именно классы явились прорывом в этом языке, следовательно, это представление ошибочно. Действительно, к членам классам подобраться, как я уже сказал, трудно или даже невозможно. Но эти трудности созданы, так сказать, для «чужих», а не для «своих». Л для того, чтобы объяснить классу, что мы именно «свои», надо подробно ему это объяснить и объявить. До этого мы все время рассматривали класс как нечто изначально закрытое, связь с закрытой частью которого возможна только через открытую часть. Но к закрытой части класса можно подобраться и не только открытым членам классам, и даже не членам данного класса. Для этого надо только объявить себя другом этого класса. Для этой роли существуют дружественные функции, или «друзья». Так как это тоже функция, ее, конечно, тоже надо объявить. Чтобы объявить дружественную функцию, надо поставить перед именем этой функции ключевое слово friend.
Объявляется дружественная функция следующим образом:
class Termo{ int a, b, с;
public
Termofint x, int y, int z){a = x; b = у; c = z;} friend int DrujockfTermo Object);
Дружественная функция не является членом класса, для которого она дружественна. Поэтому невозможно вызвать дружественную функцию, используя имя объекта и оператор доступа к члену класса, стрелку или точку; нельзя использовать и дружественную функцию как функцию-член. Если записать:
Objectl -> Drujock();
Дружественная функция объявляется в открытой части класса.
то будет выдано сообщение об ошибке.
Дружественная функция хотя и имеет доступ к закрытым членам класса, но не прямо, как, скажем, конструктор или специальная функция для связи с закрытой частью класса, а только через объект, который объявлен внутри (функции или передан ей.
Одна и та же дружественная функция может входить в различные классы. Если одна и та же дружественная функция входит в несколько классов, то она должна получить доступ к каждому классу через их объекты:
class Тегпло;
279
class Micro{
int ras;
int dwa;
public
friend int Drujock(Termo Object, Micro Object), };
class Terrno{
int try.
int tschetyry.
public
friend int Drujock(Termo Object, Micro Object);
Основы объектно ориентированного программирования
Обратите внимание на два обстоятельства:
1) дружественная функция объявляется в каждом классе, которому она дружественна;
2) посмотрите, как объявляются сразу два класса, в которых есть одна и та же дружественная функция.
Я обращаю на это внимание, потому что здесь имеется как бы замкнутый круг: так как в дружественной функции есть объекты сразу двух классов, то необходимо объявить эти классы сразу одновременно, но это невозможно. Но если объявлять последовательно один класс за другим, то нельзя объявить дружественную функцию вдогонку этим объявлениям. Поэтому сначала один класс объявляется предварительно — этим мы говорим компилятору, что объявление этого класса будет позже. Такое предварительное объявление еще называется ссылкой вперед. Дальнейшее объявление классов и дружественной им функции сразу становится понятно.
Дружественная функция не наследуется, поэтому нет и проблем с ее виртуальностью, как в случае множественного наследования классов.
Функция может быть членом одного класса и дружественной — другому:
class Plus;
class Minus{ int bnm, int cxz;
public
Minus(int b, int c){bnm = b, cxz = c} int FunctionylPius Objecty);
};
class PIus{
int rty int cxz;
public
Plusjint r, int cxz){rty - r; cxz = c)
friend int Minus FunctionyfPlus Objecty);
};
int Minus FunctionyjPlus Objecty)
{
return cxz / Objecty cxz;
В данном случае функция-член класса Minus используется как дружественная в классе Plus. Так как эта функция является членом одного класса, то при объявлении этой функции, дружественной другому классу, об этом прямо указывается через оператор расширения области видимости внутри класса Plus. В данных двух классах используется именно такая ситуация, так как происходит обработка одной и той же переменной cxz, используемой в обоих классах.
281
Оснозы объектно ориентированного программирования
см ос СМ
Заключение
•	Язык C++ базируется на трех понятиях: инкапсуляция, полиморфизм и наследование.
•	Инкапсуляция — это способ предотвращения несанкционированного доступа к закрытым частям программы. Она основана на понятии объектов и классов.
Полиморфизм — это возможность использовать конкретное действие для разных ситуаций.
Реализовать полиморфизм в C++ можно следующими способами:
1)	перегрузкой функций;
2)	перегрузкой операторов;
3)	переопределением функций;
4)	виртуальными функциями.
•	C++ поддерживает динамический полиморфизм и параметрический полиморфизм.
•	Динамический полиморфизм реализуется с помощью виртуальных методов и иерархии наследования. Полиморфным в C++ является тип, имеющий хотя бы один виртуальный метод.
Параметрический полиморфизм в C++ — это возможность многократно использовать один и тот же код применительно к разным типам данных.
•	Наследование — это возможность объекта наследовать свойства других объектов.
Класс в C++ — это пользовательский тип данных, который содержит собственные данные-члены и функции-члены. Класс предназначен для описания специального л ипа объектов.
Все члены класса изначально являются закрытыми и недоступными для нечленов класса. Если спецификатор доступа нс указан для переменных и функций класса, то они считаются закрытыми, причем спецификатор private считается присутствующим по умолчанию и его можно не указывать явно.
После объявления класса в нем определяют поля и методы. Поля класса — это объекты любого типа. Набор полей и их значения определяют состояние объекта. Методы — это функции, связанные с классом.
Спецификаторы доступа — это ключевые слова в объектно ориентированных языках, которые задают доступность классов, методов и других членов. Спецификаторы доступа — это особая часть синтаксиса языка программирования, используемая для облегчения инкапсуляции компонентов.
283
Основы объектно ориентированного программирования
В C++ есть три спецификатора доступа:
Спецификатор доступа	Значение
private	Члены класса, объявленные как private, могут использоваться только функциями-членами и «друзьями» (классами или функциями) класса
protected	Члены класса, объявленные как protected, могут использоваться функциями членами и «друзьями» (классами или функциями) класса. Кроме того, они могут использоваться производными классами данного класса
public	Члены класса, объявленные как public, можно использовать любой функцией
•	Объекты — конкретное представление абстракции, имеющее свои свойства и методы. Созданные объекты на основе одного класса называются экземплярами этого класса.
•	Конструктор и деструктор класса являются особыми функциями. Конструктор предназначен для инициализации создаваемых объектов, а деструктор — для освобождения памяти от созданных объектов этого класса.
Дружественной функцией в C++ называется функция, которая не является членом класса, но имеет доступ к его закрытым членам — переменным и функциям, которые имеют спецификатор private.
Приложения
287
Приложение 1
288
Приложение 2
292
Приложение 3
294
Приложение 4
300
ЗАКЛЮЧЕНИЕ
301
ЛИТЕРАТУРА
Приложения
Приложение 1
Математические константы
Имя константы		Описание константы	Значение константы
М.	_1_Р|	1/п	0.318305885163790671538
М.	_1_SQRTPI	корень из 1/п	0.564189583547756286948
м.	_2_Р1	2/п	0.636619772367581343076
м.	_2_5QRTPI	2/а/п	1.12837916709551257390
м.	_Е	число е	2.73828182845904523536
м.	LN1O	натуральный логарифм от 1С 1п(10)	2.30258509299404568402
м.	LN2	натуральный логарифм от 2 1п(2)	0.693147180559945309417
м.	_LOG10E	десятичный логарифм от е loglO(e)	0.434294481903251827651
м	LOG2E	логарифм по основанию 2 от натуральною числа Iog2(ej	1.44269504088896340736
м.	Pi	число	3.14159265358979323846
м.	_PI_2	л/2	1 57079632679489661923
м	Pl_4	л/4	0.785398163397448309616
м	_SQRT_2	корень из 1, деленный на 2	0.707106781186547524401
м.	.SQRT2	корень из 2	1.414213562.37309504880
При работе с математическими константами необходимо подключать библиотеку math.h с помощью директивы tfinclude <math.h>.
Приложение 2
Арифметические и алгебраические функции
Имя функции	Синтаксис	Описание функции	Файл
Jrotl	unsigned long _lrotl(unsigned long val, int count)	Циклический сдвиг val влево на count битов	stdlib.h
_hotr	unsigned long _lrctr(unsigncd long val, int count)	Циклический сдвиг val вправо на count битов	stdlib.h
_rotl	unsigned short _rotl(unsigned short value, int count)	Циклический сдвиг val влево на count битов	stdlib.h
_rotr	unsigned short _ rotr(unsignecf short vaiue, int count)	Циклический сдвиг val вправо на count битов	stdlib.h
abs	int abs(int x)	Абсолютное значение целого числа	math.h std'ib h
cabs	double cahs(struct complex z) struct cornplex{double x, y;};	Модуль комплексного числа z	math.h
cabsl	long double cabsl(struct _complex z) struct _complex{long double x, y;};	Модула комплексного числа z	math.h
ceil	double ceil {double	Округление вверх: наименьшее целое число,	math.h
		не менэшее х	
Ceil	mt Ceil(Extended X)	Округление вверх: наименьшее целое число, не меньшее X	Math, hpp
ceill	long double cediflong double x)	Скругление вверх: наименьшее целое число, не меньшее х	math.h
	div_t div(int numer, int denom) typedef struct{		
div	int quot; // частное	Целочисленное деление numer/denom	math.h
	int rem; // остаток		
	) div_t;		
287
ажо
Имя функции	Синтаксис	Описание функции	Файл
ехр	double exp(double x)	Экспонента числа с плавающей запятой	math.h
expl	long double expl(long double x)	Экспонента длинного числа с плавающей запятой	math.h
tabs	double fabs(double x)	Абсолютное значение числа с плавающей запятой	math.h
fabsl	long double fabsl(long oouble x)	Абсолютное значение длинного числа с плавающей запятой	math.h
floor	double floor(double x)	Округление вниз: наибольшее целое, не большее х	math.h
Floor	int Floor(Extended X)	Округление вниз: наибольшее целое, не большее X	Math, hpo
floor 1	long double f1oorl(long double x)	Округление вниз: наибольшее целое, не большее х	math.h
fmod	double fmod(double x, double y)	Остаток от деления х/у	math.h
fmodl	long double fmodl(long double x, long double y)	Остаток от деления х/у	math h
frexp	oouble frexp(double x, int ’'“exponent)	Разделяет х на мантиссу и степень exponent	math.h
Frexp	void Frexp(Extended X, Extended & Manbssa, int & Exponent)	Разделяет X на мантиссу Mantissa и степень Exponent	Math, hpo
frexpl	long double frexplflong double x, int * exp-ment)	Разделяет х на мантиссу и степень exponent	math.h
Int Powe г	Extended lntPower(Fxtended Base, int Exponent)	Возводит Base в целую степень Exponent	Math, hpp
Имя функции	Синтаксис	Описание функции	Файл
labs	long labsflong int x)	Абсолютное значение длинного целого числа	math.h stdlib.h
Idexp	double Idexpldouble x, int exp)	х х 2ехр	math.h
Ldexp	Extended Ldexp(Extended X, int P)	X х 2Р	Math hpp
Idcxpl	long double ldexpl(long double x, int exp)	х х 2ехр	math.h
	typedef struct{		
	long int quot, // целое		
Idiv	long int rem; // остаток } ldiv_t;	Целочисленное деление: numer/denom, quot — результат, rem — остаток	math.h stdlib.h
	ldiv_t ldiv(long int numer, long int denom)		
LnXPl	Extended LnXPl(Extended X)	Натуральный логарифм (Х + 1)	Math, hpp
log	double !og(double x)	Натуральный логарифм	math.h
loglO	double loglOfdouble x)	Десятичный ло1арифм	math.h
LoglO	Extended LoglO(Extcnded X)	Десятичный лотрифм	Math, hpp
loglO!	long double loglul(long double x)	Десятичный логарифм длинного числа с плавающей запятой	math.h
Log2	Extended Log2(Extended X)	Логарифм по основанию 2	Math, hpp
logl	long double loglflong double x)	Натуральный логарифм, длинного числа с плавающей точкой	math.h
LogN	Extended LogN(Extended Base, Extended X)	Логарифм X по основанию Base	Math hpp
289
ажо
Имя функции	Синтаксис	Описание функции	Файл
max	max(x, y)	Макрос возвращает максимальное значение из х и у любых типов данных	stdlib.fi
min	min(x, b)	Макрос возвращает минимальное значение из х и у любых типов данных	stdlib.h
modf	double modf(double x, double * ipart)	Разделяет х на целую часть ipart и возвращаемую дробную часть	math.h
modfl	long double modfl(long double x, long double * ipart)	Разделяет х на целую часть ipart и возвращаемую дробную часть	math.h
poly	double polyfdouble x, int degree, double coeffs'])	Полином от х степени degree с коэффициентами coeffs	math.h
Poly	Extended Poly(Extended X, const double * Coefficients, const int Coefficients-Size)	Полином от X степени Coefficients_Size с коэффициентами Coefficients	Math, hpp
polyl	long double po!yl(long double x, int degree, long double coeffsf])	Полином от х степени degree с коэффициентами coeffs	math h
pow	double powfdouble x, double y)	Ху	math.h
Power	Extended Power(Extended Base, Extended Exponent)	Возводит Base в степень Exponent	Math, hpp
powl	long double powlflong double x, long double y)	ху	math.h
sqrt	double sqrt(double x)	Корень квадратный	math.h
sqrtl	long double sqrtl(long double x)	Корень квадратный длинного числа с плавающей запятой	math.h
Функции подключаются директивой ttinclude.
Extended — число с плавающей запятой типа Extended.
291
Приложения
Приложение 3
Тригонометрические функции
Имя функции	Синтаксис	Описание функции	Файл
acos	double acos(double x)	Арккосинус	math.h
acosl	long double acosl(long double x)	Арккосинус длинного числа с плавающей точкой	math.h
ArcCos	Extended ArcCos(Extended X)	Арккосинус	Math.hpp
ArcCosh	Extended ArcCosh(Extended X)	Арккосинус гиперболический	Math.hpp
ArcSin	Extended ArcSin(Extended X)	Арксинус	Math.hpp
ArcSinh	Extended ArcSinh(Extended X)	Арксинус гиперболический	Math.hpp
ArcTan2	Extended ArcTan2(Extended У Extended X)	Арктангенс (Y/X)	Math.hpp
ArcTanh	Extended ArcTanh(Extended X)	Арктангенс гиперболический	Math.hpp
asin	double asin(doubie x)	Арксинус	math.h
asinl	long double asrnl(long double x)	Арксинус	math.h
atan	double atan(double x)	Арктангенс	math.h
atan 2	double atan2(dcuble y, double x)	Арктангенс у/х	math h
anan2l	long double anan2l(long double y, long double x)	Арктангенс у/х	math.h
atanl	long double atanl(long double x)	Арктангенс	math.h
cos	double cosfdouble x)	Косинус	math.h
cosh	double cosh(double x)	Косинус гиперболический	math.h
Cosh	Extended Cosh(Extended X)	Косинус гиперболический	Math hpp
Имя функции	Синтаксис	Описание функции	Файл
coshl	long double coshl(lcng double x)	Косинус гиперболический	math.h
cosl	long double cosl(long double x)	Косинус	math.h
Cotan	Extended CotanfExtended X)	Котангенс	Math.hpp
CycleToRad	Extended CycleToRad) Extended Cycles)	Вычисление угла в радианах по его значению в периодах Cycles: 2п х Cycles	Math hpp
DegToRad	Extended DegToRad(Extended Degrees)	Вычисление угла в радианах по его значению в градусах Degrees: Degrees х д / 180	Math.hpp
hypot	double hypot(douPle x, double y)	Гипотенуза треугольника с катетами х и у	math.h
Hypot	Extended Hypot(Exlended X, Extended Y)	Гипотенуза треугольника с катетами X и Y	Math hpo
hypotl	long double hypotl(long double x, long double y)	Гипотенуза треугольника с катетами х и у	math.h
RadToCycle	Extended RadToCycle(Extended Radians)	Вычисление угла в периодах по его значению в радианах Radians Radians / (2д)	Math.hpp
RaaTcDeg	Extended RadToDeg(Extended Radians)	Вычисление угла в градусах по его значению в радианах Radians: Radians х 180/д	Math.hpp
sin	double sinfdouble x)	Синус	math.h
SinCos	void SinCos(Extended Theta, Extended & Sin, Extended & Cos)	Расчет синуса Sin и косинуса Cos угла Theta	Math hpp
Sinh	Extended Sinh(Extended X)	Синус гиперболический	Math.hpp
293
оже
Имя функции	Синтаксис	Описание функции	Файл
sinh	double sinh(double x)	Синус гиперболический	math.h
sinhl	long double sinhl(long double x)	Синус гиперболический	math.h
sinl	long double sinl(long double x)	Синус	math.h
Tan	Extended Tan(Extended X)	Тангенс	Math.hpp
tan	double tan(double x)	Тангенс	math n
Tanh	Extended Tanh(Extended X)	Тангенс гиперболический	Math.hop
tanh	double tanh(double x)	Тангенс гиперболический	math.h
tanhl	long double tanhl(long double x)	Тангенс гиперболииеский	math.h
tanl	long double tanl(long double x)	Тангенс	math.h
Приложение 4
Константы err по
Константы еггпо — это значения, назначенные еггпо для различных условий ошибки. Константы еггпо — переменная, хранящая целочисленный код последней ошибки. Обычно еггпо реализуется в виде макроса, вызывающего функцию, возвращающую указатель на целочисленный буфер. При запуске программы значение еггпо равно 0.
Если вызов функции завершился ошибкой, то она устанавливает переменную еггпо в ненулевое значение. Если вызов прошел успешно, функция обычно не проверяет и не меняет переменную еггпо.
При работе с константами еггпо устанавливаются заголовочные файлы:
ttinclude <stdio.h>
#include <errno.h>
Значение еггпо необязательно совпадает с фактическим кодом ошибки, возвращаемым системным вызовом из операционной системы Windows.
Поддерживаются следующие значения еггпо
295
ЭЖО1/И
Значения errno и их описания
Сообщение Код Сообщение Описание ошибки об ошибке
E2BIG	20	Arg list too long
EACCES	5	Permission denied
EAGAIN	42	Resource temporarily unavailaole
EBADF	6	Bad file number
Список аргументов очень длинный. Список аргументов превышает 128К, или пространство, требуемое для информации окружения, превышает 32К
Доступ запрещен: разрешение, установленное для файла, не задает требуемого доступа. Эта ошибка возникает в тех случаях, когда сделана попытка доступа к файлу путем, который несовместим с атрибутами файла. Например, ошибка возникла при чтении из файла, который не является открытым; при записи в открытый файл, предназначенный только для чтения; при открытии директория вместо файла. В старших версиях MS-DOS EACCFS может указывать на нарушение блокировки или режима разделения. Ошибка возникает также при переименовании файла или оглавления, при уничтожении существующего директория
Ресурсы временно недоступны
Неверное файловое число. Значение handle для файла не является правильным, либо оно не ссылается на открытый файл, либо сделана попытка записи в файл или на устройство, открытые только для чтения (и наоборот)
Сообщение об ошибке	Код	Сообщение	Описание ошибки
EBUSY	44	Resource busy	Все ресурсе: заняты
ECHILD	24	No child process	Нет дочернего (зависимого) процесса
ECONTR	7	Memory blocks destroyed	Блокировка памяти разрушена
ECURDIR	36	Attempt to remove CurDir	Попытка удаления CurDir
EDEADLOCK	36	Locking violation	Может возникнуть зависание. Принудительная блокировка: файл не может быть блокирован после 10 попыток (для всех версий MS DOS)
EDOM	33	Math argument	Математический аргумент. Аргумент для математической функции не принадлежит области определения этой функции
Е EXIST	35	File already exists	Файл существует Флаги O_CREATE и O_EXCL определены при открытии файла, но файл с заданным именем уже существует
Е FAULT	14	Unknown error	Неизвестная ошибка
EFBIG	27	В MS-DOS не занято	Только для операционной системы UNIX
EINTR	39	Interrupted function call	Прерывание вызова функции
EINVACC	12	Invalid access code	Ошибка кода доступа
297
ажс
Сообщение об ошибке	Код	Сообщение	Описание ошибки
EINVAL	19	Invalid argument	Неверный аргумент. Задан неверный аргумент для одного из аргументов функции. Например, значение для origin (адрес начала программы) задается, когда указатель на файл находится перед началом файла
EINVDAT	13	Invalid da:a	Ошибка в данных
EINVDRV	15	Invalid drive specified	Ошибка в определении
EINVENV	10	Invalid environment	Ошибка программного окружения
EINVFMT	11	Invalid format	Ошибка формата
EINVFNC	1	Invalid function number	Ошибка списка исполнения
EINVMEM	9	Invalid memory block address	Ошибка блокировки адреса памяти
ЕЮ	40	Input / output error	Ветвить / Удалить ошибку
EISDIR	46	В MS-DOS не занято	Только для операционной системы UNIX
EMFILE	4	Too many open files	Много открытых файлов. Другие handle для файла недоступны, так как нельзя больше открыть другие файлы
EMLINK	31	В MS-DOS не занято	Только для операционной системы UNIX
ENFILE	23	loo many open files	Много открытых файлов Другие handle для файла недоступны, так как нельзя больше открыть другие файлы
Сообщение Код Сообщение Описание ошибки об ошибке
ENMFILE	18	No more files
ENODEV	15	No such device
ENOENT	2	No such file or directory
ENOEXEC	21	Exec format error
ENOFILE	2	File not found
ENOMEM	8	Not enough core
ENOPATH	3	Path not found
Нет больше файлов
Нет такого управляющего файла
Нет данного файла или директория. Заданный файл или директорий не существует или не может быть найден. Это сообщение возникает, если заданный файл не существует или в существующем директории не определена компонента path-имени
Ошибка формата. Сделана попытка создать файл, который не является выполнимым или имеет неверный.ехе-формат
Файл не найден. Неправильно указано имя файла, или неправильно указан путь к этому файлу, или файл не существует (например, уничтожен)
Памяти недостаточно Недостаточно доступной памяти. Это сообщение может возникать, когда для выполнения child-процесса памяти недостаточно или когда для памяти невозможно обеспечить такое расположение, которое требуется при вызовах sbrk или getewd
Неправильное имя файла. Неправильно указано имя файла, или неправильно указан путь к этому файлу, или файл не существует (например, уничтожен)
299
ажс
Сообщение об ошибке	Код	Сообщение	Описание ошибки
ENOSPC	28	No space left on device	На устройстве не осталось свободного места. Свободного пространства на устройстве недостаточно, чтобы произвести запись (например, диск полон)
ENOTBLK	43	В MS-DOS не занято	Только для операционной системы UNIX
ENOTDIR	45	В MS-DOS не занято	Только для операционной системы UNIX
ENOTSAM	17	Not same device	Не тот командный файл
ENOTTY	25	В MS-DOS не занято	Только для операционной системы UNIX
ENXIO	41	No such device or address	Не такой командный файл или адрес
EPERM	37	Operation not permitted	Операция не разрешена
EPIPE	32	Broken pipe	Нарушение пути
ЕRANGE	34	Result too large	Результат очень большой. Аргумент для математической функции очень большой, поэтому происходит частичная или полная потеря значимости результата Эта ошибка также может возникнуть в других функциях, когдг аргумент больше, чем предполагается (например, когда аргумент path-имени для функции getcwd больше, чем предполагается)
EROFS	30	Read-only file system	Ошибка чтения файла системой
ESPIPE	29	Illegal seek	Незаконное действие. Подобное действие не разрешено
Сообщение об ошибке	Код	Сообщение	Описание ошибки
ESRCH	38	В MS DOS не занято	Только для операционной системы UNIX
ETXTBSY	26	В MS-DOS не занято	Только для операционной системы UNIX
EUCLEAN	47	В MS-DOS не занято	Только для операционной системы UNIX
EXDEV	22	Crossdevice link	Перекрестная связь с устройством. Сделана попытка перемещения файла на другое устройство (используется функция rename)
EZERO	0	Error 0	Деление на 0. Один из аргументов, на котоэый делится число, равен 0. Результат такого деления равен бесконечности, а потому невозможен
301
Приложения
=©
ЗАКЛЮЧЕНИЕ
Программирование — это процесс создания программы для выполнения определенной задачи на компьютере. Оно является неотъемлемой частью современного общества и используется во многих областях — от разработки веб-сайтов до создания искусственного интеллекта. Чтобы успешно разрабатывать программы и решать задачи, важно понимать основные концепции и принципы программирования. Использование соответствующих инструментов и языков программирования тоже играет важную роль в процессе разработки. Программирование дает возможность творчески мыслить, решать сложные задачи и создавать новые технологии.
РЕКОМЕНДОВАННАЯ
ЛИТЕРАТУРА
О
0 о
о о
0
о
0 0
Федеральный закон от 27 июля 2006 г. № 149-ФЗ (ред. от 9 марта 2021 г.) «Об информации, информационных технологиях и о защите информации» (с изм. и доп., вступ. в силу с 20 марта 2021 г.).
Федеральный закон от 27 июля 2006 г. № 152-ФЗ «О персональных данных».
Федеральный закон от 23 июня 2016 г. № 208-ФЗ «О внесении изменений в Федеральный закон «Об информации, информационных технологиях и о защите информации» и Кодекс Российской Федерации об административных правонарушениях».
Федеральный закон от 1 мая 2019 г. № 90-ФЗ «О внесении изменений в Федеральный закон «О связи»«. Указ Президента РФ от 6 марта 1997 г. № 188 «Об утверждении перечня сведений конфиденциального характера» (с изм. и доп.).
ГОСТ 19781 «Обеспечение систем обработки информации программное. Термины и определения».
ГОСТ 34.11 «Информационная технология. Криптографическая защита информации. Функция хеширования».
ГОСТ Р 50922 «Защита информации. Основные термины и определения». ГОСТ Р 51275 «Защита информации. Объект информатизации. Факторы, воздействующие на информацию. Общие положения».
303
Приложе
ф ф
ф
ф
ф
ф ф
ф
ГОСТ Р 54593 «Информационные технологии. Свободное программное обеспечение. Общие положения». ГОСТ Р 56939 «Защита информации. Разработка безопасного программного обеспечения. Общие требования».
ГОСТ Р 58412 «Защита информации. Разработка безопасного программного обеспечения.
Угрозы безопасности информации при разработке программного обеспечения».
ГОСТ Р 58412-2019 «Защита информации. Разработка безопасного программного обеспечения. Угрозы безопасности информации при разработке программного обеспечения». ГОСТ Р 71206-2024 «Защита информации. Разработка безопасного программного обеспечения. Безопасный компилятор языков C/C++. Общие требования» (дата введения: 01.04.2024).
ГОСТ Р ИСО 10007 «Менеджмент организации. Руководящие указания по управлению конфигурацией».
ГОСТ Р ИСО/МЭК 12207 «Информационная технология. Системная и программная инженерия. Процессы жизненного цикла программных средств».
ГОСТ Р ИСО/МЭК 27000 «Информационная технология. Методы и средства обеспечения безопасности. Системы менеджмента информационной безопасности. Общий обзор и терминология».
ГОСТ Р ИСО/МЭК 27001-2006 «Информационная технология. Методы и средства обеспечения безопасности. Системы менеджмента информационной безопасности.
Требования».
Давыдова Н. А. Программирование: учебное пособие / И. А. Давыдова, Е. В. Боровская. — 4-е изд. — Москва: Лаборатория знаний, 2020. — 241 с. — (Педагогическое образование). — ISBN 978-5-00101-788-2. — Текст: электронный. — URL: https://znanium. com/catalog/product/1201350 (дата обращения: 15.03.2024). — Режим доступа: но подписке.
Дейл Н. Программирование на C++: учебник / Н. Дейл, Ч. Уимз, М. Хедингтон; пер. с англ. А. С. Цемахмана. — 2-е изд. — Москва: ДМК Пресс, 2023. — 674 с. — (Учебник). — ISBN 978-5-89818-342-4. — Текст: электронный. — URL: https://znanium. com/catalog/product/2102629 (дата обращения: 15.03.2024). — Режим доступа: по подписке.
Затонский А. В. Программирование и основы алгоритмизации.
Теоретические основы и примеры реализации численных методов: учебное пособие / А. В. Затонский, Н. В Бильфельд. — 2-е изд. — Москва: Р14ОР: ИНФРА-М, 2022. — 167 с. — (Высшее образование). — ISBN 978-5-369-01195-9. — Текст: электронный. — URL: https://znanium. com/catalog/product/1860435 (дата обращения: 15.03.2024). — Режим доступа: ио подписке.
иложе

©
Копырин А. С. Программирование на C# в Visual Studio 2013: учебное пособие / А. С. Копырин, Т.Л. Салова. — Москва: ФЛИНТА, 2021. — 54 с. — ISBN 978-5-9765-4754-4. — Текст: электронный. — URL: https://znanium.com/catalog/ product/1851994 (дата обращения: 15.03.2024). — Режим доступа: по подписке.
Корнеев В. И. Программирование графики на C++. Теория и примеры: учебное пособие / В. И. Корнеев, Л. Г. Гагарина, М. В. Корнеева. — Москва: ИНФРА-М, 2024. — 517 с. + Доп. материалы [Электронный ресурс]. — (Высшее образование: Бакалавриат). — DOI 10.12737/23113. —
ISBN 978-5-16-017914-8. — Текст: электронный. — URL:https://znanium. com/catalog/product/2111934 (дата обращения: 15.03.2024). — Режим доступа: по подписке.
Кузин А. В. Программирование на языке Си: учебное пособие / А. В. Кузин, Е. В. Чумакова. — Москва: ФОРУМ: ИНФРА-М, 2024. — 143 с. — (Среднее профессиональное образование). — ISBN 978-5-00091-556-1. — Текст: электронный. — URL: https://znanium.ru/catalog/ product/2137197 (дата обращения: 15.03.2024). — Режим доступа: по подписке.
ф
ф
ф
Немцова Т.Н. Программирование на языке высокого уровня.
Программирование на языке C++: учебное пособие / Т.Н. Немцова, С. Ю. Голова, А. И. Терентьев; под ред. Л. Г. Гагариной. — Москва: ФОРУМ: ИНФРА-М, 2024. — 512 с. + Доп. материалы [Электронный ресурс]. — (Среднее профессиональное образование). — ISBN 978-5-8199-0699-6. — Текст: электронный. — URL: https://znanium.com/catalog/ product/2083383 (дата обращения: 15.03.2024). — Режим доступа: по подписке.
Перцев И. В Программирование на языке Си: учебно-методическое пособие / Сибирский государственный университет телекоммуникаций и информатики; каф. прикладной математики и кибернетики. — Новосибирск: СибГУТИ, 2022. — 106 с. — Текст: электронный. — URL: https://znanium.ru/catalog/ product/2136515 (дата обращения: 15.03.2024). — Режим доступа: по подписке.
Пош М. Программирование встроенных систем на C++ 17: моно!рафия / пер. с англ. А. В. Снастина. — Москва:
307
ДМК Пресс, 2020. — 394 с. — ISBN 978-5-97060-785-5. — Текст: электронный. — URL: https://znamum.com/catalog/ product/1094950 (дата обращения: 15.03.2024). — Режим доступа: по подписке.
awoi/и
ф
©
©
о
©
©
Шитов В.Н. Менеджмент информационного контента: учебное пособие. — Москва: ИНФРА-М, 2022. — 209 с. — (Среднее профессиональное образование). Шитов В. Н. Обработка отраслевой информации: учебное пособие. — Москва: ИНФРА-М, 2022. — 184 с. — (Среднее профессиональное образование).
Шитов В. Н. Основы проектирования баз данных: учебное пособие. — Москва: ИНФРА-М, 2024. — 236 с. — (Среднее профессиональное образование).
Шитов В. Н. Пакет прикладных программ: учебное пособие. — Москва: ИНФРА-М, 2021. — 334 с. — (Среднее профессиональное образование).
Шитов В. Н. Разработка информационного контента (по отраслям): учебное пособие. — Москва: ИНФРА-М, 2022. -178 с. — (Среднее профессиональное образование).
Шитов В. Н. Внедрение информационных систем: учебное пособие. — Москва: КНОРУС, 2024. — 342 с. — (Среднее профессиональное образование). Шитов В. Н. Инженерно-техническая поддержка сопровождения информационных систем: учебное пособие. — Москва: КНОРУС, 2024. — 282 с. — (Среднее профессиональное образование).
е
е
Шитов В.Н. Устройство и функционирование информационной системы: учебное пособие. — Москва: КНОРУС, 2024. — 282 с. — (Среднее профессиональное образование). Шитов В.Н. Автоматизация рутины в Excel VBA: лайфхаки для облегчения скучных рабочих задач. — Москва: Эксмо, 2023. — 448 с. — (Excel для всех).
309
310
Для заметок
Все права защищены Книга или любая ее часть не может быто скопирозана воспроизведена в электронной или механической форме, в виде фотокопии, записи в память ЭВМ, репродукции или каким-либо иным способом, а также использована в любой информационной системе без получения разрешения от издателя. Копирование воспроизведение и иное использование книги или ее части без согласия издателя является незаконным и влечет уголовную, административную и гражданскую О1ветственнос1ь.
Производственно практическое издание
ПРОГРАММИРОВАНИЕ ДЛЯ НАЧИНАЮЩИХ
Шитов Виктор Николаевич
С+4 ДЛЯ НАЧИНАЮЩИХ
Главный редактор Р Фасхутдинов Руководителе направления В. Обручев Ответственный редактор Л Салихова Литературный редактор Е. Ерошкина Младший редакюр М. Назаренко Художественный редактор К. Доброслов Компьютерная верстка Т. Лукина Корректор М. Джалая
Страна происхождения: Российская Федерация Шытарушы ел: Ресей Федерациясы
ООО «Издательство «Эксмо»
123308, Россия, г. Москва, ул. Зорге, д. 1, стр. 1, эт. 20, каб. 2013. Тел.: 8 (495) 411-68-86.
Home раде: www.eksmo.ru E-mail: info@eksmo.ru Онд|руил: «Издательство «Эксмо» ЖШК, 123308, Ресей, Маскеу каласы, Зорге кешео, 1-уй, 1-курылыс, 20к,абат, 2013-каб. Тел.: 8 (495) 411 -68-86. Home раде: www.eksmo.ru E-mail: info@eksmo.ru.
Тауар белпа: «Эксмо»
Интернет-магазин: www.book24.ru
Интернет-магазин : www.book24.kz Интернет-дукен : www.book24.kz
Импортёр в Республику Казахстан ТОО «РДЦ-Алматы». Казахстан Республикасына импорттаушы «РДЦ-Алматы» ЖШС.
Дистрибьютор и представитель по приему претензий на продукцию в Республике Казахстан: ТОО «РДЦ-Алматы»
ТОО РДЦ Алматы, Алматы, ул. Домбровского, 3«а», литер Б, офис 1.
Дистрибьютор жене Казахстан Республикасындаенмге шагымдар кдбылдау жен!ндеп ект: «РДЦ-Алматы» ЖШС.
Алматы к.. Домбровский кош., 3 «а», литер Б, офис 1.
Тел.: 8 (727) 251-59-90/91/92. E-mail: RDC-Almaty@eksmo.kz
Сведения о подтверждении соответствия издания согласно законодательству РФ о техническом регулировании можно получить на сайте Издательства «Эксмо»: www.eksmo.ru/certification
Техникалык, реттеу гуралы РФ зацнамасына сай басылымныцсэйкеслпн растау туралы мал!меттерд| мына адрес бойынша алуга болады: http://eksmo.ru/certification/
Произведено в Российской Федерации Ресей Федерациясындаендршген
Сертификаттауга жатпайды
Дата изготовления / Подписано в печать 16 09 2025 Формат 70х1001/16. Печать осрсетная Усл. печ. л. 25,93.
Тираж экз. Заказ
ООО ''Издательство Вперед
Москва. ООО «Торговый Дом «Эксмо» Адрес: 123308. г. Москва ул Зорге, д.1, строение 1 Телефон. +7 (495) 411 -50-74 E-mail: ieception@eksmc-saie.ru
По вопросам приобретения книг «Эксмо» зарубежными оптовыми покупателями обращаться в отдел зарубежных продаж ТД «Эксмо» E-mail: international@eksmo-sale ru
Iriternatioi tai Sales. International wholesale customers snouio contact Foreign Sales Department of Tracing house -<EKsmo-> foi their oroers.
international@eksmo-sale.ru
По вопросам заказа книг корпоративным клиентам в том числе в специальном оформлении, обра даться по тел.: +7 (495) 411-68 59 доб. 2151
E-ma'I borodkin da@eksmo.ru
Оптовая торговля бумажно-беловыми
и канцелярскими товарами для школы и офиса «Канц Эксмо»: Компания «Канц-Эксмо»: 142702, Московская обл. Ленинский р-н, i Видное-2, Белокаменное ш., д. 1 а/я 5. Тел./факс: +7 (495) 745-28-87 (мно!оканальный).
e-mail: kanc@eksmo saie.ru, сайт: www kanc eksmo.ru
Филиал «Т-. pi оного Дома «Эксмо» в Нижнем Новгороде
Адрес: 603094 г. Нижний Новгород, улица Карпинского, д. 29, бизнес-парк «Грин Плаза» Телефон:+7 (831) 216-15 91 (92, 93 94). E-mail.ieception@eksmonn.ru
Филиал ООО «Издательство «Эксмо» в г. Санкт-Петербурге
Адрес 192029, г Санкт-Петербург пр Обуховской обороны, д 84 лит. «Е»
Телефон: +7 (812) 365-46-C3 / 04 E-mail: server@szko.ru
Филиал ООО 'Издательство «Эксмо» в г. Екатеринбурге
Адрес: 620024, г. Екатеринбург, ул Новинская, д 2щ
Телефон. +7 (343) 272-72-01 (02/03/04/05/06/08)
Филиал ООО «Издательство «Эксмо» б г. Самаре
Адрес 443052, г. Самара, пр-т Кирова д 75/1, лит. «Е»
Телефон: +7 (846) 207-55-50. Е-mail: RDC-samara@mail.ru
Филиал (."С «Издательство «Эксмо » в г. Ростове-на-Дону
Адрес: 344023 г. Ростов-на-Дсну, ут. Страны Советов, 44А
Телефон - 7(863) 303-62 10 E-mail.info@rndeksmo.ru
Филиал ООО «Издательство «Эксмо» в г. Новосибирске
Адрес. 630015, г. Новосибирск, Комбинатский пер , д 3
Телефон: +7(383) 289-91-42. E-mail: eksmo-nsK@yandex.ru
Обособленное подразделение в ,. Хабаровске
Фактический адрес: 680000, г. Хабаровск, ул Фрунзо 22. оф. 703 Почтовый адрес: 680020, г. Хабаровск, А/Я 1006
Телефон: (4212) 910-120, 910-211. E-mail: eksino-khv@mail.ru
Республика Беларусь: ООО «ЭКСМО ACT Си энд Си» Центр оптово розничных продаж Cash&Catry в г. Минске Адрес 220014, Республика Беларусь, г Минск, проспект Жукова, 44, пом 1-17, ТЦ «Outleto» Телефон: +375 17 251 40 23; -«375 44 581 -81 -92
Режим работы с 10 00 до 22 00. E-mail: exmoast@yandex оу
Казахстан: «РДЦ Алматы»
Адоес. 050039 г. Алматы ул. Домбровского, ЗА
Телефон. +7 (727) 251-58-12, 251-59-90 (91,92,99). E-mail. RDC-Almaiy@eksmo.kz
Полный ассортимент продукции ООО «Издательство «Эксмо» можно приобрести в книжных магазинах «Читаи-гсрод» и заказать в интернет-магазине: www.ch'tai gorod ru.
Телефон единой справочной службы 8 (800) 444-8-444. Звонок по России бесплатный.
Интернет-магазин ООС «Издательство «Эксмо»
www eksmo.ru
Розничная продажа кни« с доставкой по всему миру
Тел +7 (495) 745 89-14. Е mail, imarket@eksmo-sale.ru
ПОСЛЕ ПРОЧТЕНИЯ этой книги вы НАУЧИТЕСЬ ПРОГРАММИРОВАТЬ НА C++
ЦВЕТНАЯ РАЗМЕТКА СДЕЛАЕТ КОД ПОНЯТНЕЕ, И ВЫ БЕЗ ТРУДА СМОЖЕТЕ:
•	ПИСАТЬ ПРОГРАММНЫЙ КОД НА C++
•	ОБРАБАТЫВАТЬ ОДНОМЕРНЫЕ И ДВУМЕРНЫЕ МАССИВЫ
•	ИСПОЛЬЗОВАТЬ ПРИНЦИПЫ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ
С помощью этих значков ваше обучение станет проще и понятнее
ПОЛЕЗНЫЕ СОВЕТЫ

£.4.i
НЮАНСЫ. КОТОРЫЕ СТОИТ ЗАПОМНИТЬ

ПРЕДУПРЕЖДЕНИЕ и ПОТЕНЦИАЛЬНОЙ ОПАСНОСТИ
СКАЧАЙТЕ ПРИМЕРЫ КОДА БЕСПЛАТНО И ПРИСТУПАЙТЕ К РАБОТЕ СРАЗУ ЖЕ!
Благодаря практическим заданиям вы получите отличное представление об основах программирования на языке C++. Просто следуйте инструкциям -и вы научитесь создавать простые программы, разберетесь с ключевыми концепциями разработки и поймете, как применять C++для решения практических задач.
9 785942 225932 >
t БОМБОРА
ИЗДАТЕЛЬСТВО
БОМБОРА — лидер на рынке полезных
и вдохновляющих книг Мы любим книги и создаем их, чтобы вы могли творить, открывать мир, пробовать новое, расти. Быть счастливыми Быть на волне.