Вы находитесь на странице: 1из 668

руководство ДЛЯ начинающих

Второе издание
А Beginner's Guide
Second Edition

HERBERT SCHILDT

МсGга\\'-Нill/0sЬогпе

J'\C\\' \"OJ'k
Cllicago SaIl r:raIlCISCO
Lj,IЮII 1\1;JIJI'i(\ Мсхн;о Cil\' Мilап
L,1'11I\01l
;-\l'\" Dcll11 ~ап.lШJl SCOII\ Sll1gal"JI'(" SY(\IlC\' ')urUlllU
РУКОВОДСТВО дпя начинающих

Второе издание

ГЕРБЕРТ шилдт


!\10СКВ(\ • C<J.hkt-ПетсрGург
2005
• KIlt'B
ББК 32.973.26-018.2.75
Ш57
УДК 681.3.07

Издательский дом "ВИЛЬЯМС"

Зав. редакцией е.н. Трuгyб

Перевод с английского и редакция н.м Ручка

По общим вопросам обращайтесь в Иэдательс.:киЙ дом "Вильямс" по адресу:


info@williamspubIishing.com. hllp://ww\v. williamspubI ishing.com
115419. Москва. aJя 783; 03150. Киев. aJя 152

Шилдт, Герберт.

Ш57 С++: руководство для начинаlOЩИХ, 2-е издание. : Пер. сангл. - М. : Издатель-
ский дом "Вильямс", 2005. - 672 с. : ил. - Парал. тит. аш·л.

ISBN 5-8459-0840-Х (рус.)

в этой книге описаны ocHoBныe средства языка С++, которые необходимо осво­
ить начинающему программисту. После рассмотрения элементарных поWJТИЙ
(переменнblX, операторов, инструкций управления, функций, классов и объеК10В)
читатель легко перейдет к изучениlO таких БОJtее сложных тем, как перегрузка опе­
раторов, механизм обработки исключительных ситуаций (искточений), наследова­
ние, полиморфизм, виртуальные функции, средства ввода-вывода и шаблоны. Aв'rop
справочника - общепризнанный авторитет в области программирования на языках
С и С++, Java и С# - включил в свою книry множество тестов для саМОКОНТРОJIJl,
которые ПОЗВОJIJlЮТ быстро проверить степень освоеиия материала, а также раздcлы
"воnpосов и ответов", способствующие более глубокому изучения основ програм­
мирования даже на начальном этапе.

ББК 32.973.26-018.2.7S

все названИJI про'1'8ммных ПРОДУКТОВ JПIJlIIЮI"CЯ зapemстрированными тoproaыMH марками с001'ВCl'Cl1i)'Ю1IIИX


фирм.
НикаКaJI часть настоящ~ro Н3Д8.НIUI нн В каких. целях не мож<:Т бlolТЪ воспроизведена в J(aкoA бы то НlI было
форме н J(UHMH бы ТО HII было средствами. будь то :mCКТPOHНI.le или мех.анические. ВКЛЮЧaJI фотокопнрова­
нне н запнсь на магнитный носитель. ссли на зто нст письменно:'О разрешении издательства Osbome Мediз.
Authorized trnпslаliоп from the Епglish luпguаgе editiоп publisllcd Ьу Osbome РuЫishiпg. Copyrighl © 2004 Ьу
Тhc МсGrпw-Нi11 Соmр3пiеs.
АН righls reserved. No ршt of this book тау Ье reproduced or trапsmittеd iп IlПУ form or Ьу anу mеалs. еlесtrопiс
ог mесhалiсаl. iпсludiпg рhОlосоруiпg. reсогdiпg or Ьу anу iпfоrmаtiоп slocage rctrievul syslem. withoul реnnissiоп
from Ihe Publisher.
Russiзп lзпguаgе editiоп published Ьу Williams РuЫishiпg House ассогdiпg 10 tbe АgreemеПI wilh R&l
ЕПlеrprises lnlоmаliопаl. Copyrighl © 2005

ISBN 5-8459-0840-Х (рус.) © Издательскнli дом "Вильямс". 2005


JSBN 0-07-223215-3 (8.Нгл.) © Тhc МсGrзw-Нill Соmралies. 2004
Оглавление

Об авторе 15
Введение 17
Модуль 1. Основы С++ 21
Модуль 2. Типы данных и операторы 69
Модуль З. Инструкции управления 109
Модуль 4. Массивы, СТрОI<И и указатели 157
Модуль 5. Введение в фУНI<ЦИИ 211
Модуль 6. О функциях подробнее 261
МОДУЛЬ 7. Еще о типах данных и операторах ЗОЗ
Модуль 8. I<лассы и объекты З49
Модуль 9. О классах подробнее З97
Модуль 10. Наследование 465
МОДУЛЬ 11. С++-система ввода-вывода 521
Модуль 12. Исключения, шаблоны и кое-что еще 571
Приложение А. Препроцессор 639
Приложение Б. Использование устаревшего С++-компилятора 65з
Предметный указатель 656
Содержание

Об авторе 15
Введение 17
Как организована эта книга 17
Практичсские навыки 1.8
Тсст для самоконтроля 18
Вопросы для текущего контроля 18
Спросим у опытного программиста 18
Учсбные проекты 18
Никакого предыдущего опыта в области программирования не требуется 18
Требуемое программное оБССllсчение 19
Программный код - из Web-пространства 19
Для далЫlсйшего изучения программирования 19
Модуль 1. Основы С++ 21
1.1. Из истории создания С++ 22
Язык С: начало эры современного программирования 23
Предпосылки ВОЗIШКlЮВСНИЯ языка С++ 24
Рождение С++ 25
Эволюция С++ 26
1.2. Связь С++ с языками Java и С# 27
1.3. Объектно-ориентированное программирование 29
Инкапсуляция 30
Полиморфизм 31
Наследование I
32
1.4. Создание, компиляция и выполнение С++-программ 32
Ввод текста программы 34
Компилирование программы 34
Выполнение программЬ! 35
Построчныii "разбор полетов" первого ПРИl\fера IJporpaMMbl 36
Обработка синтаксических ошибок 38
1.5. Использование нсремснных 1\0
1.6. Использование операторов 41
1.7. Сt"пываllие данных с клавиатуры 44
Вариации на тему вывода данных 46
Познакомимся еше с одним ТIlIЮМ даJlНЫХ 47
1.8. Использование IfНСТРУКЦИЙ управления if и (ог 52
С++: PYI<OBOACTBO для. начинающих 7

Инструкция if 52
Цикл for 54
1.9. Использование блоков кода 56
Точки с запятой и расположение инструкций 58
Практика отступов 59
1.10. Понятие о функциях 62
Библиотеки С++ 64
1.12. Ключевые слова С++ 65
1.13. Идентификаторы 66
Модуль 2. Типы данных и операторы 69
Почему типы данных столь важны 70
2.1. Типы данНЫХ С++ 70
Целочисленный тип 72
Символы 75
Типы данных с плавающей точкой 77
Тип данных Ьооl 78
Тип void 80
2.2. Литералы 83
Шестнадцатеричные и восьмеРИЧllые литералы 84
Строковые литералы 84
Управляющие символьные последователыfстии 85
2.3. Со:щаиие инициализироваlfНЫХ переменных 87
Инициализация псременной 87
Динамическая инициалllзация переменных 88
Операторы 89
2.4. Арифметические операторы 89
Инкремент и декремент 90
2.5. Операторы отношений и логические операторы 92
2.6. Оператор присваинания 98
2.7. Составные операторы приспаивания 99
2.8. П реобраэопание типов в операторах присваиваиия 100
Выражения 101
2.9. Прео6раэование типов в оыраЖСIlИЯ-Х 101
Пре06разооаIlИЯ, связанные с типом bool 1()2
2.10. Приведение тшlOВ 102
2.11. Использование пробелов If КРУГЛЫХ скобок 104
8 Содержание

МОДУЛЬ 3. ИНСТРУКЦИИ управления 109


3.1. Инструкция if 110
Условное выражение 112
Вложенные if-инструкции 114
"Лестничная" конструкция if-else-if 115
3.2. Инструкция switch 117
Вложенные инструкции switcb 121
3.3. Цикл for 125
Вариации на тему цикла for 127
Отсутствие элементов в определении цикла 129
Бесконечный цикл for 130
Циклы без тела 131
Объявление управляющей переменной цикла в заголовке
инструкции for 132
3.4. Цикл while 134
3.б. Использование инструкции break для выхода из цикла 143
3.7. Использование инструкции сопtiпuе 145
3.8. Вложенные циклы 151
3.9. Инструкция goto 152
МОДУЛЬ 4. Массивы, строки и ука3атели 157
4.1. Одномерные массивы 158
На границах массивов без пограничников 162
4.2. Двумерные массивы 163
4.3. Многомерные массивы 165
4.4. Строки 169
Основы представления строк 169
Считывание строк с клавиатуры 170
4.5. Некоторые библиотечные функции обработки строк 173
Функция strcpyO 173
Функция strcatO 173
Функция strcmp() 173
Функция strlenO 174
Пример использования строковых функций 174
Использование признака завершения строки 175
4.б. Инициализация массивов 177
Инициализация "безразмерных" массивов 180
4.7. Массивы строк 182
4.8. Указатели 183
С++: PYI<OBOACTBO для начинающих 9

Что представляют собой указатели 184


4.9. Операторы, используемые с указателями 185
О важности базового типа указателя 186
Присваивание значений с помощью указателей t 89
4.10. Использование указателей в выражениях 190
Арифметические операции над указателями 190
Сравнение указателей. 192
4.11. Указатели и массивы 193
Индексирование указателя 196
Строковые константы 198
~ассивыуказателей 203
Соглашение о нулевых указателях 205
4.12. ~ноroуровневая непрямая адресация 206
Модуль 5. Введение в функции 211
Основы использования функций 212
5.1. Общий формат С++-Функций 212
5.2. Создание функции 213
5.3. Использование аргументов 215
5.4. Использование инструкции return 216
Возврат значений 220
5.5. Использование функций в выражениях 222
Правила действия областей видимости функций 224
5.6. Локальная область видимости 225
5.7. Глобальная область видимости 231
5.8. Передача указателей и массивов в качестве аргументов функций 235
Передача функции указателя 235
Передача функции массива 237
Передача функциям строк 240
5.9. Возвращение функциями указателей 242
Функция mainO 243
5.10. Передача аргументов командной строки функции mainO 244
Передача числовых аргументов командной строки 246
5.11. Прототипы функций 248
Стандартные заголовки содержат прототипы функций 250
5.12. Рекурсия 250
Модуль 6. О функциях подробнее 261
6.1. Два способа передачи аргументов 262
6.2. Как в С++ реализована передача аргументов 262
10 Содержание

6.3. Использование указателя ДЛЯ обесПечения вызова по ссылке 264


6.4. Ссылочные параметры 266
6.5. Возврат ссылок 271
6.6. Независимые ссылки 275
Ограничения при использовании ссылок 276
6.7. Пере грузка функций 277
Автоматическое пре06разование типов и п€регрузК2 282
6.8. Аргументы, передаваемые функции 110 УМО.lчанИю 292
Сравнение возможности передачи аргументов по умолчаllИЮ
с перегрузкой функций 294
Об использовании аргументов, псредаваемых по умолчанию 296
6.9. Перегрузка функций и неОДlIозначность 298
Модуль 7 303
Еще о типах данных и операторах 303
7.1. Специфи каторы типа const и volatile 304
Спеl!ифик:атор типа
const 304
Спецификатор типа уоl .. Ше 307
Специфю<аторы классов памяти З08
Спецификатор класса памяти auto ЗОВ
7.2. Спецификатор класса памяти extern 308
7.3. Статические переменные 3\0
7.4. Рсшстровые переменные 315
7.5. Перечисления 318
7.6. Ключевое слово typedef 322
7.7. Поразрядные операторы 322
ПоразряДныс операторы И, ИЛИ, исключающее ИЛИ и НЕ 323
7.8. Операторы сдвига ЗЗО
7.9. Оператор "знак вопроса" ЗЗ9
7.10. Оператор "запятая" 340
7.11. Составные опсраторы I1РИСваивания 342
7.12. Использованис ключевого слова sjzcof 343
С~ОДllая таблица приоритеТО8 С++-операторов 345
Модуль 8. Классы и объекты 349
В.1. Общи ii формат объявления класса 350
В.2. Определение класса и со:щание объектов 351
8.3. Добавление в класс функций-членов 357
8.4. Конструкторы и деструкторы 3б7
С++: РУКОВОДСТВО АЛ~ начинающих 11

8.5. Параметризованные конструкторы 370


Добавление конструктора в класс Vehicle 373
Альтернативный вариант инициализации объекта 374
8.6. Встраиваемые функции 376
Создание встраиваемых функций R объявлении класса 378
8.7. Массивы объектов 388
8.8. Инициализация массивов объектов 389
8.9. Ука:~атели на объекты 391
Модуль 9. О классах подробнее 397
9.1. Переl"рузка КОIiСТРУКТОРОВ 398
9.2. Присваивание объектов 399
9.3. Передача объектов функциям 402
Конструкторы. деструкторы и передача объектов 403
Передача объектов по ссылке 405
Потенциальные проблемы при передаче параметров 407
9.4. Возвращение объектов функциями 408
9.5. Создание и использование конструктора копии 411
9.6. Функции-"друзья" 415
9.7. Структуры и объединения 421
Структуры -121
Объединения 424
9.8. Ключевое слово this 428
9.9. Персгрузка операторов 430
9.10. Перегрузка операторов с использованием Функций-членов 431
О значении порядка операндов 435
Использование функций-членов для Ilерегрузки
унарных операторов 435
9.11. Перегрузка операторов с ИСПО-!lьзованисм функций-не членов класса 441
Испо~ьзование Функций-"друзей" для переrpузки
унарных операторов 447
Советы по реализащш перегрузки операторов 448
Модуль 10. Наследование 465
10.1. ПОlIятие о наследовании 466
Доступ к членам класса и наследование ·170
10.2. Управление доступом к членам базового класса 4. 74.
10.3. Использование защищенных членов 477
10.4. Вызов конструкторов базового I(ласса -183
12 Содержание

10.5. Создание многоуровневой иерархии 493


10.6. Наследование нескольких базовых классов 497
10.7. Когда выполняются функции конструкторов и деструкторов 498
10.8. Указатели на производные типы 501
Ссылки на производные типы 5(12
10.9. Ви.ртуальные функции и полиморфизм 502
Понятие о виртуальной функции 502
Наследование виртуальных функций 50б
Зачем нужны виртуальные функции .507
Применеtlие виртуальных функций .509
10.10. Ч исто виртуальные функции и абстрактн ые классы 514
Модуль 11. С++-система ввода-вывода 521
Сравнение старой и новой С++-систем ввода-вывода 522
11.1. Потоки С++ 523
Встроенные С++-потоки 524
11.2. Классы потоков 524
11.3. Перегрузка операторов ввода-вывода 526
Создание перегруженных операторов вывода 527
Использование функций-"друзей" для перегрузки
операторов вывода 529
Перегрузка операторов ввода 530
Форматированный ввод-вывод данных 533
11.4. Форматирование данных с использованием
функций-членов класса ios 5З3
11.5. Использование манипуляторов ввода-вывода 540
11.6. Создание co6cтвeНlfЫx манипуляторных функций 543
Файловый ввод-вывод данных 545
11.7. Как открыть и закрыть файл 546
11.8. Чтение и запись текстовых файлов 549
11.9. Неформатированный ввод-вывод данных n двоичном режиме 551
Считывание и запись в файл блоков данных 554
11.10. Использование других функций ввода-вывода 556
Версии функции getO 557
Функция getlineO 558
Функция обнаружения конца файла 559
Функции peekO и putbackO 559
Функция flushO 559
С++: PYI<OBOACтeO дl\Я начинающих 13

11.11. Произвольный доступ 565


11.12. Получение информации об операциях ввода-вывода 568
Модуль 12. Исключения, wаблоны и кое-что еще 571
12.1. Обработка исключительных ситуаций 572
Основы обработки исключительных ситуаций 572
Использование нескольких саtсh-инструкций 578
Перехват всех исключений 581
Определение исключений, генерируемых функциями 583
Повторное генерирование исключения 585
Шаблоны 587
12.2. Обобщенные функции 587
Функция с двумя обобщенными типами 590
, Явно заданная перегрузка обобщенной функции 591
12.3. Обобщенные классы 594
Явно задаваемые специализации классов 597.
12.4. Динамическое распределение памяти 603
Инициализация динамически выделенной памяти 60i
Выделение памяти для массивов 608
Выделение памяти для объектов 609
12.5. Пространства имен 614
Понятие пространства имен 615
Инструкция usiпg 619
Неименованные пространства имен 622
Пространство имен std 622
12.6. Статические члены класса 623
Статические члены данных класса 623
Статические функции-члены класса 626
12.7. Динамическая идентификация типов (RТГI) 628
12.8. Операторы приведения типов 633
Оператор dупarnic_сast 633
Оператор сопst_cast 635
Оператор static_cast 635
Оператор reinterpret_cast 635
Приложение А. Препроц&Ссор 639
Директива #define 640
Макроопределения, действующие как функции 642
Директива #error 644
14 Содержание

Директива #include 644


ДиреКПIВы условной )(омпиляции 645
Директивы#if, #else, #еlif и #endif 6,15
Директивы#ifdef и #ifl1def МВ
Директива #ulldef 649
ИСПОЛJ,ЗО8ание оператора defined 649
Директива #line 650
Директива #pragma 650
Операторы препроцессора "#" и "##" 651
Зарезероированные макроимена 652
Приложение Б. Использование YCTapeBUlero C++-КОМПИI\IПОра 653
Два простых измеиения 655
Предметный указатель 656
Об авторе
Герберт Шилдт (Herbert Schildt) - признанный авторитет u области програм­
мирования на языках С, С++ Java и С#, профеССИОIl3ЛЬНЫЙ Wiпdоws-програм­
мист, член комитетов ANSI/ISO, ПРИlIимавших стандарт ДЛЯ языков С и С++.
Продано свыше 3 миллионов экземпляров его книг. Они переоедены на все самые
распространенные языки мира. Шилдт - автор таких бестселлероu, как [[олн~й
справочник по С, Полный справочник по С++, Полный cnpae01mUK"0 С#, /lолный
С1lравочник noJava 2, и многих других книг, включая: Руководсm(ю для UQЧUlfаю­
ЩlLТ по С, Ру'Кооодcmво для llаЧ.llнающux ,10 С# И Руководство дл.яНО1lШШЮЩUХ по
Java 2. Ш илдт - обладатель степени маrnстра в области ВЫ'IИС.'lитеЛbtюЙ техни­
ки (университет шт. ИллиноЙс). Его контактный телефон (о консулы'ационном
отделе): (217) 586-4683.
Введение
Язык С++ предназначен для разработки высокопроизводительного ПРQГРамм­
ного обеспечения и чрезвычайно популярен среди ПРОll>аммистов. При этом
он обеспечивает концеl1туальный фундамент (синтаксис If стиль), на который
опираются другие ЯЗЫIШ программирования. Не случайно ведь потомками С++
стали такие почитаемые языки, как С# и ]ауа. Более того, С++ можно назвать
униоерсальным ЯЗЫI<ОМ Ilрограммирования, поскольку практически все профес­
сиональные программисты на том или ином уровне знакомы с С++. Изучив С++,
вы получите фундаментальные знания, которые позволят вам освоить любые
аспекты современиоI'О програММИРОВ3I1ИЯ.

Цель этой книги - помочь читателю овладеть базовыми элементами С++-про­


граммирования. Сначала, например, вы узнаете, как скомпилировать и выпол­
нить С++-l1рограмму, а затем шаг за шагом будете осваивать более сложные темы
(l<J1ючевые слова, языкоuые КОНСТРУКЦИИ, операторы и пр.). Текст книги подкре­
пляется многочислеllНЫМИ примерами программ, тестами для самоконтроля и

учебными проектами, поэтому, про работав весь материал этой книги, вы получи­
те глубокое понимание основ С++-программирования.
Я хочу подчеркнуть, что эта книга - лишь стартовая площадка. С++ - это
большой (по объему средств) и не самый простой язык программирования. Не­
обходимым условием успешного программирования на С++ является знание не
только ключевых слов, операторов и синтаксиса, определяющего возможностн

языка, но и библиотек классов и функций, которые существенно помогают в раз­


работке программ. И хотя HClcoTopble элементы библиотек рассматриваются в
этой книге, все же большинство нз них не нашло здесь своего отражения. Чтобы
стать псрвоклассным программистом на С++, необходимо в совсршенстве изу­
чить и С++-библиотеки. Знания, получснные при изучении этой книги, позволят
вам освоить не только библиотеки, но и все остальные аспекты С++.

Как организована эта книга


Эта книга представляет собой самоучитель, материал которого равномерно
распределен по разделам, причсм успешное освоение каждого следующего пред­

полагает знание всех предыдущих. Книга содержит 12 модулей, посвященных со­


ответствующим аспектам С++. Уникальность этой книги состоит в том, что она
включает несколько специальных элементов, которые позволяют закрепить уже

пройденный материал.
18 Введение

Практические навыки
Все модули содержат рюдслы (отмеченные n и KTO!l)aM мой" Важно! "), которые
важно не ПРОПУСТИТЬ при lIзучеllИИ материала юшги. ИХ ЗШ\ЧИМОСТI. ДЛЯ IJОСЛ~­
доватсльного освоения lюдчеркивается тем, что они про~умерованы и Ilеречис­

лены lJ начале каждого модуля.

Тест ДЛЯ самоконтроля


Каждый модуль завершается тестом для саМ.ЖОJlТРОЛЯ. Ответы можно наifЛI
lIа Web-странице этой КlНIПI по адресу: http://www . osborne. сот.

Вопросы для текущего контроля


в конце каждого значимого раздела содеРЖI1ТСЯ тест, пронеряющий степень
вашего ПОllимания ключевых момеитов, изложснных выше. Отвсты lIа эти 81)-

lIРОСЫ приводятся внизу соответствующей СТрalIIЩЫ.

Спросим у опытного программиста


в разЛИЧIIЫХ местах KНImi пы встретите спецнал bIlbl{' разДСЛЫ"СIiРОСНМ у ОПЫТIII}'
го програмМ\lста", которые содсржат ДОПОЛШIТе.7!I>\lУЮ IIнформацию ЮПI Itнтерссны('
комментарии по nанной теме. ЭП1 разделы преДСТ<lНJlСIIЫ в ~юр:..ta'rе "ВОП!)()С-ОТВС-'''

Учебные проекты
Каждый модуль включает ОДИН [lJ111 нескоЛ\.ко просктов, которые 1l0ЮlзЫВ;t­
ют, как Шl праКТlше можно прнмеНИТf> ИЗJlожеlIныi, здесь материал. ЭТII учебвые
Ilроекты представляют собой реальные примеры, КОТОРЫС можно IIСIЮЛI>ЗОВ"ТЬ JJ
качестве стартовых вариантов для ваших программ.

Никакого предыдущего опыта


в области программирования
не требуется
Для освоения IlредставлеlПЮГО здесь MaTeplI<1..I"IIIIK3KOrO предыдущего опыта
11 области програММНРОВaJlI!Я НС требуется. Поэтому, сели ГlЫ IIIlкогда раньше IIC
IIрограммировми. можете смело браться за эту юшгу. КОJj~ЧII() же. 13 JlаШII /lHII
IШlOгие Чlпат"JJIl уже имеlOТ хотя бы 1\1JшимаЛbllыii опыт 8 I1рограМ:"НI/ЮШШIll1.
Например. вам, возможно, уже приходилось писать IIpOгpaMMbl на .Ji1"a И.'lll С#.
Как вы скоро узнаете, С++ ~шляется "РОДlпеЛС~I" O(jUIIX <>ТИХ языков. Поэтому,
еСЛII вы уже JllaK01\1bI с Java или С#, то ГlaM не со( таlllП труда ОСГlЩIТЬ 11 С+ +.
С++: РУI<ОВОДСТВО ДМ, начинающих 19

Требуемое программное
обеспечение
Чтобы СКОМrII1;IIIРol),l1'Ь и 8ЫПОЛIIIIТl. программы, приведенные в этой книге,
вам ПОllадобится любой 1'13 таких современных компиляторов, как Visual С++
(MicrosQft) JI С++ Builder (Borland).

Программный код - из Web-


пространства
Помните, что IIСХОДНЫЙ код нсех примерОD ПРOJ·рамм 11 учебных IlРОСКТОВ,
Ilриведенных D этоjj книге. можно бесплатно загрузить с Wеl>-сайта по адресу:
httр://www.оSlюrпе.соm. Загрузка кода избавит вас от необходимости ово­
ДИ1Ъ тскп программ ОР}"I"УЮ.

Длt;l дальнейшего изучениt;l


программирования
Книга С#: Р./lКО(jО(kmtю для lta'lIJII(1ЮIЦUХ - это ваш "ключ" к серии книг по
lI(юграммированию, Щ1llнсаНIIЫХ It>p6epTu:\t ШИЛДТОМ. Ниже перечислены те из
них, которые MOI')'T "рсдставлять ДЛЯ вас IIнтерес.

Те, КТО желает подробнее изучить ЖIЫК С++, могут обратиться к следую­
ЩИМ книгам.

• ПОЛllЫU сnравоч"u" 110 С++,


• с + +: баЗО(Jыii курс,
• Освой самuсmоя тулы/() С + + ,

• sn Pro,!?,"IaтmingJmm tlle Grountl ир,


• СnравО1111l1К npOlpa~t.lmcma по С/С++.
Тем, кого JIIпсресует програММllрование на языке java, мы peJ<OMeAдyeM такие
издания.

• .Iozla 2: А Begill11e1"'S Gu;rJe, .


• ПО//1(ЫU cnpo(JO'lIIllK llO.!ava 2,

• .fava 2: РrОl:jnЩllllе1"'S R(jmnlCe.


• !1скуссmвр 1IjЮI]1а\f.'lUроааl/nlЯ I/и.!аиа.
20 Введение

Если вы желаете научиться ПРОq>aМмироваТl' на С#, обратитесь к следующим


книгам.

• С#: А Beginner's Guide,


• ПОЛНЫй справочник по С#.
Тем, кто интересуется Windоws-программированием, мы можем предложить
такие книги Шилдта.

• Windows 98 Pтogrammingfrom the Ground Ир,


• Windows 2000 Programmingjrom the Ground ир,
• MFC Programmingjrom the Ground Ир,
• The Windows Annotated Arcblves.
Если вы хотите поближе познакомиться с языком С, который является фунда­
ментом всех современных языков программирования, обратитесь к следующим
книraм.

• Полный сnравочнuк по С,
• Освой самостолmелыlO С.
Если вам нужны четкие ответы, обращ8ЙТеСЬ к ГербеJ7IY Шилдту, общепризнанво­
му авторитету в области ПрОf1>аммирования.

От издательства
Вы, читатель этой КIIИrn, и есть главный ее критик и комментатор. Мы ценим
ваше мнение и хотим знать, что было сделано нами правильно, что можно было сде­
лать лучше и что еще вы хотели бы увидеть изданным нами. Нам интересно УС.1Ы­
шать и любые другие замечания, которые вам хотелось бы высказать в наш адрес.
Мы ждем ваших комментариев и надеемся t: а них. Вы можете при слать нам
бумажное или электронное письмо, либо просто посетить наш Web-сервер и
оставить свои замечания там. Одним словом, любым удобным для вас способо.\{
дайте нам знать, нравится или нст вам эта книга. а также выскажите свое мнение
о том, как сделать наши книги более интересными ДЛЯ вас.
Посылая письмо или сообщение, не забудьте указать название книги и ее авто­
ров, а также ваш обратный адрес. Мы внимательно ознакомимся с вашим мнением
и обязательно учтем его при отборе и подготовке к изданию последующих книг.
Наши координаты:
E-таН: info@williamspublishing.c:)m
WWW: http://www.williamspublishing.com
Информация для писем из:
России: 115419, Москва, а/я 783
Украины: 03150, Киев, а/я 152
МОДУЛЬ 1
ОСНОВЫ С++

1.1. Из истории создания С++


1.2. Связь С++ с языками Java и С#
1.3. Объектно-ориентированное программирование
1.4. Создание, компиляция и выполнение С++-программ
1.5. Использование переменных
1.6. Использование операторов
1.7. Считывание данных с клавиатуры
1.8. Использование инструкций управления if и for
1.9. Использование блоков кода
1.10. Понятие о функциях
1.12. Ключевые слова С++
1.13. Идентификаторы
22 Глава 1. ОСНОВЫ С++

Если и существует один компьютерный язык, который определяет суп) со­


BpeMeHHoro программирования, то, безусловно, зто С++. Язык С++ предназна­
чен для разработки высокопроизводительного llрограммного обеспечения. ЕI"O
синтаксис стал стандартом для других профессиональных языков программи­
рова.ния, а его принципы ра.lработки отражают идеи развития вычислительной
техники в целом. С++ послужил фундаментом для разработки языков будущего.
Например, K3KJava, так и С# - прямые ПОТОМIСИ языка С++. СеГОДIIЯ быть про­
фессиональныM программистом высокого клас,:а означает быть компетентным в
С++. С++ - это ключ J( современному програм\iированию.
Цель этоro модуля - представить С++ в историческом аспекте, проследить
его истоки, проанализировuть его взаимоотношения с неrюсредствснным пред­

шественником (С), рассмотреть ero возможности (области ПРИМСНСIIИЯ) и ЩНШ­


ципы программирования, которые он поддерживает. Самым трудным 8 изучении
языка программирования, безусловно. является то, что НИ один его элемеlН не
существует изолировашю от других. Компоненты языка работают вместе, можно
сказать, в дружном "коллективе". Такая тесная взаимосвязь усложняет рассмо­
трение одного аспекта С++ без изучения других. Зачастую обсуждение одного
средства предусматривает предварительное знакомство с дрynlМ. Для преодоле­
ния подобных трудностей в этом модуле ПРИВОДIIТСЯ краткое описание таЮIХ эле­
ментов С++, как общий формат С++-программы, основные инструкции управле­
ния и операторы. При этом мы не будем пока УI'лубляться в детали, а сосредото­
чимся па общих концепциях создания С++-программы.

ВАЖНОI
,ММ ИЭИСТnРИId СО3ДnWИАu-С+* /

История создания С++ начинается с языка С. И немудреlfО: С++ построеllllа


фундаменте С. С++ и в самом деле представляе1" собой супермножество язЬ/ка С.
С++ можно назвать расширенной и улучшешю~r версией языка С. предназначен­
ной для поддержки объектно-ориентированного lIрограммирования (ero ПРИН­
ципы описаны ниже в этом модуле). С++ также включает ряд других усовершен­
ствований ЯЗЫI(а С, например расширенный набор библиотеЧIIЫХ функций. При
Э1'ОМ "вкус И запах" С++ унаследовал непосредственно из языка С. Чтобы до кон­
ца понять и оценить достоинства С++, необходимо понять все "как" и "почему" n
отношении языка С.
С++: PYI<OBOACтeO ДМ! начинающих 23

Язык С: начало эры современного


программирования +
+
Изобретение языка С отмстило начало новой эры COBpeMeHHoro программи­ u-
2i
рования. Его влияние нельзя было переоцеtlить, поскольку он коренным образом aI
О
:I:
изменил подход ~ программированию и его восприятие. Его синтаксис и принци­ U
О
I1Ы разработки оказали влияние на ВСС последующие компьютерные языки, по­
этому язык С можно назвать одной из основных революционных СИЛ в развитии
вычислительной техники.
Язык С изобрел Дэнис Ритчи (Dennis Ritchie) для компьютера РОР-ll (раз­
работка компании ОЕС - Digita) Equipment Corporation), который работал под
управлением операционной системы (ОС) UNIX. Язык С - это результат про­
цесса разработки, который сначала был связан с другим языком - BCPL, создан­
ным Мартином Ричардсом (Martin Riсlшгds). Язык BCPL ИНДУUИРОВaJI появле­
ние языка, получившего lIазвание В (его автор - Кен Томпсон (Кеп Thompson»,
который в свою очередь в lIачале 70-х годов привел к разработке языка С.
Язык С стал считаться первым современным "языком программиста", по­
скольку до его изобретения l(!Омпьютерные языки в основном разрабатывались
либо как учебные упражнения, либо как результат деятельности бюрократиче­
ских структур. С языком С все обстояло иначе. Он был задуман и разработан ре­
альными, практикующими программиста.\1И и отражал их подход к I1РОГРамми­

рованию. Его средства были многократно обдуманы, отточены и протестированы


людьми, которые действительно работали с этим языком. В результате этого про­
цесса появился язык, который понравилсяMHomM программистам-практикам и
быстро распространился по всему миру. Ero невиданный успех обусловило то,
что он был разработан программистами для программистов.
Язык С возник в результате реВОЛЮ1{ИИ cmpyкmypup08a,molO npozpa.AWupo-
вания БО-х годов. До появлеllИЯ структурироваююго программировзния 060-
значились проблемы в написания больших программ, поскольку программисты
пользовались логикой, которая ПРИ80ДИJlа к созданию так наЗЫI~аемого "cnareT-
ти-кода", состоящего из множества переХОДО8, последовательность которых было
трудно проследить. В структурированных ЯЗЫI<аХ программирования эта пробле­
ма реmалась путем Ifсполь:ювания хорошо определенных инструкций управле­
ния, подпрограмм, локальных персменных и других средств. Появление структу­
рированных языков позволило писать уже довольно большие nporpaмМbl.
Несмотря на то что в то время уже существовали другие структурированные
языки (например Pascal), С стал первым языком, в котором успешно сочеталисъ
мощь, изящество и выразительность. Ero лаконизм, простота синтаксиса и фило­
софия БЫЛII I-laСl'ОЛЬКО ПРI1Dлекательными, что в мире программирования непо-
24 !Лава 1. Основы С++

стижимо быстро образовалась целая армия его приверженцев. С точки зрения


сегодняшнего ДНЯ этот феномен даже трудно понять, но, тем не менее, язык С
стал своеl'ородадолrожданным "свежим ветром". который вдохнул в программи­
рование новую жизнь. В результате С был общепризнан как самый популярный
структурированный язык 1980-х годов.

ПреДПОСblЛКИ возникновения языка С++


Приведенная выше характеристика языка С может вызвать справедливое не­
доумение: зачем же тогда, мол, был изобретен я;tык С++? Если С - такой успеш­
ный и полезный язык, то почему возникла необходимость в чем-то еще? Оказы­
вается, все дело в сложности. На протяжении всей истории программирования
усложнение программ заставляло программистов искать пути, которые бы позво­
лили справиться со сложностью. Язык С++ можно считать одним из способов ее
преодоления. Попробуем лучше раскрыть взаимосвязь между постоянно возрас­
тающей сложностью программ и путями развития языков программирования.
Отношение к программированию резко измен flЛОСЬ с момента изобретения КО.\{­
пьютера. Например, программирование для первых вычислительных машин состоя­
ло в переключении тумблеров на их передней панели таким образом, чтобы их поло­
жение соответствовало двоичным кодам машинных команд. Пока длины программ
не превышали нескольких сотен команд, такой метод еще имел право на существо­
вание. Но по мере их дальнейшего роста был изобретен язык ассемблер, чтобы про­
граммисты могли использовать символическое представление машинных команд.

Поскольку программы продолжали расти в размерах, желание справиться с более


высоким уровнем сложности ВЫЗВало появление ЯЗЫКОВ высокого уровня, разработ­
ка которых дала программистам больше инструментов (новых и разных).
Первым широко распространенным языком программирования был, конечно
же, FORTRAN. Несмотря на то что это был очень значительный шаг на пути про­
гресса в области программирования, FORTRAN все же трудно назвать языком,
который способствовал написанию ясных и простых для понимания программ.
Шестидесятые годы двадцатого столетия считаются· периодом появления струк­
турированного программирования. Именно такой метод программирования и
был реализован в языке С. С помощью структурированных языков программи­
рования можно было писать программы средней сложности, причем без особых
героических усилий со стороны программиста. Но если программный проект до­
стигал определенного размера, то даже с использованием упомянутых структури­

рованных методов его сложность резко возрастала и оказывалась непреодолимой


для возможностей программиста. К концу 70-х к "критической" точке подошло
довольно много проектов.
С++: PYI<080ACTBO ДМl начинающих 25

Решить эту проблему "DЗЯЛИСЬ" новые технолоmи программирования. Одна из


них получила название объектно-ориентированного nрограм.мuрованuя (ООП).
Вооружившись методами 00 П, программист мог справляться с программами го­ :j:
u
раздо большего размера, чем прежде. Но язык С не поддерживал методов ооп.

Стремление получить объектно-ориентированную версию языка С в конце кон­ о
1:
()
цов и привело к созданию С++. О
Несмотря на то что язык С был одним из самых любимых и распространен­
ных профессиональных языков программирования, настало время, когда его
возможности по написанию сложных программ достигли своего предела. Же­
лание преодолеть этот барьер и помочь программисту легко справляться с еще
более объемными и сложными программами - вот что стало основной причи­
ной создания С++.

Рождение С++
Язык С++ был создан Бьерном Страуструпом (Bjame Stroustrup) в 1979 году
в компании ВеН Laboratories (г. Муррей-Хилл, шт. Нью-Джерси). Сиачала но­
вый язык получил имя "С с классами" (С with Classes), но в 1983 году он стал
называться С++.
Страуструп построил С++ на фундаменте языка С, включающем все его
средства, атрибуты и основные достоинства. Для него также остается в силе
принцип С, согласно которому программист, а не язык, несет ответственность
за результаты работы своей программы. Именно этот момент позволяет понять,
что изобретение С++ не было попыткой создать новый язык программирова­
ния. Это было скорее усовершенствование уже существующего (и при этом
весьма успешного) языка.
Большинство новшеств, которыми Страуструп обогатил язык С, было предна­
значено для поддержки объектно-ориентированного программирования. По сути,
С++ стал объектно-ориентированной версией языка С. Взяв язык С за основу,
Страуструп подготовил плавный переход к ооп. Теперь, вместо того, чтобы из­
учать совершенно новый язык, С-программисту достаточно было· освоить только
ряд новых средств, и он мог пожинать плоды использования 06ъектно-ориенти­
рованной технологии программироваиия.
Создавая С++, Страуструп понимал, иасколько важно, сохранив изначальную
суть языка С, Т.е. его зффективность, гибкость и принципы разработки, внести в
него поддержку объеКТlю-ориеllТИРОВaJlНОl"O орограммирования. К счастью, эта
цель была достигнута. С++ по-прежнему предоставляет программисту свободу
действий и власть над компьютером (которые были присущи языку С), значи­
тельно расширяя при этом его (программиста) возможности за счет использова­
ния объектов.
26 Глава 1. Основы С++

Несмотря на то что С++ изначально был I-I.щелен на поддержку очень БО.1Ь­


ПlИX программ, этим, Конечно же, его использование не ограничивалось. И 8 са­
мом деле, объектно-ориентированные средства С++ можно эффективно приме­
пять практически к любой задаче программирования. Неудивительно, что С++
используется для создания компиляторов, peДёJKTOpOB, компьютерных игр и про­

грамм сетевого обслуживания. Поскольку С++ обладает эффективностью языка


С, то программиое обеспечение многих высокоэффективных систем построено с
использованием С++. Кроме того, С++ - это язык, который чаще всего выбира­
ется для Wiпdоws-программирования.

Эволюция С++
С момента изобретения С++ претерпел т~,и крупные l1ереработки, причем
каждый раз язык как ДОПОJlllЯЛСЯ новыми средствами, так и в чем-то изменялся.
Первой ревизии он был подвергнут в 1985 году. второй - в 1990, а третья произо­
шла в процессе стандартизации, который актюшзировался в начале 1990-х. Спе­
циально для этого был сформирован объединенный АNSI/ISО-комитет (я был
его членом), который 25 января 1994 года принял первый проект предложенного
на рассмотрение стандарта. В этот проект БЫЛII включены все средства, впервые
определенные Страуструпом, и добавлены новые. Но в целом он отражал состоя­
ние С++ на тот момент времени.
Вскоре после завершения работы над первым проектом стандарта С++ про­
изошло событие, которое заставило значительно расширить существующий
стандарт. Речь идет о создании'Ллександром Степановым (Alexander Stepanov)
стандартной библиотеки шаблонов (Standar<\ Template Library - STL). Как
вы узнаете позже, STL - это набор обобщенных функций, которые можно ис­
пользовать для обработки данных. Он доволыio большой по размеру. Комитет
ANSI/ISO проголосовал за включение STL в спеllИфикauию С++. добавление
STL расширило сферу рассмотрения средств С++ далеко за пределы исходнuго
определения ЯЗblка. Однако ВlUlючение STL. помимо прочего, замедлило процесс
стандартизации С++, причем довольно сущест)}еllllO.
Помимо STL, в сам ЯЗblК было добавлено н('сколько новых средств и внесено
множество мелких изменений. Поэтому верси.il С++ после рассмотрения коми­
тетом по стандартизацЮ1 стала намного больше и сложнее по сравнению с ис­
ходным вариантом Страуструпа. Конечный результат работы комитета датиру­
ется 14 ноября 1997 года, а [lеалыlO ЛNSI/ISО-стандарт языка С++ увидел Сllет
в 1998 году. Именно эта спецификация С++ ОnЫЧJlО называется Standard С++.
и именно она описана в данной книге. Эта версия С++ поддерживается всеми
ОСНОВJlЫМИ C++-компилятораМII, включая Vistl<ll С-Н (Мiсrоsоft) и С++ Buildct·
С++: руководство для начинающих 27

(Borland). Поэтому код программ, приведенных в этой ЮiИге. полностью приме­


ним ко всем современным С++-средам.
+
u+
~
ВАЖНО! аз
О

IIII..C8S13hC** с ЯЗЬ'КQМИ 'nуо И с#. :J:


()
О
ПОМИМО С++, существуют два других современных языка программирования:
java н С#. Язык.Jаvа разработан компанией Sun Microsystems, а С# - компанией
Мicrоsоft. Поскольку иногда возникает путаница относительно того, какое ОТIЮ­
шеtlНС эти два языка имеют к С++, попробуем внести ясность о этот вопрос.
С++ является родительским языком· дляjаv~ и'С#. И хотя разработчикиjаvа
и С# добаВIIЛИ к псрвоисточнику, удалили из него или модифицировали различ­
ные средства, D целом синтаксис этих трех языков практически идентичен. Более
того, объектная модель, используемая С++, подобна объеК11iЫМ моделям языков
.Java и С#. Наконец, очень сходно общее впечатщшие и ощущение от использо­
вания всех этих языков. Это зиачит, что, зная С++, вы можете легко изучитьjаvа
или С#. Схожесть синтаксисов и объектных моделей - одна из причин быстрого
освоения (11 одобрения) этих двух языков многими опытными С++-программи­
стам". Обратная ситуация также имеет место: если вы знаетеjаvа или С#, изуче­
ние С++ не доставит вам хлопот.
Основное различие между С++, Java и С# заключается в типе вычислитель­
ной среды, для которой разрабатывался каждый из этих языков. С++ создавался
с целью lIаписания высокоэффективных программ, предназначеНJlЫХ для выпол­
нения под управлением Оllределенной операционной системы и в расчете на ЦП
конкретного типа. Например, если вы хотите написать высокоэффективную про­
грамму для выполнения на процессоре Intel Pentium под управлением операци­
онной системы Windows, лучше всего использовать для этого язык С + +.
Языки java и С# ра.lработаны в ответ на Уliикальные потребности сильно рас­
пределенной сетевой среды Internet. (При разработке С# также ставил ась цель
упростить СО~iДание программных компонентов.) Intemet связывает множество
различных типов ЦП и операционных систем. Поэтому возможность создания
межплатформеНIIОГО (совместимого с несколькими операционными средами)
переносимого программного кода для 1nternet при решеНИII некоторых задач ста­
ло определяющим УСЛОDием при выборе языка программирования.
IIерпым языком, отвечающим таким требованиям, был ]ava. Используя Java.
можно написать программу, которая будет выполняться в различных вычисли­
тельных средах, т.е. в широком диапазоне операционных систем и типов цп.
TaKIIM образом. Java-программа может свободно "бороздить просторы" Intemet.
Несмотря на то чтоjаvа позволяет создавать переиосимый ПРОJ"раммный код, ко-
28 Глава 1. Основы С++

торый работает в сильно распределенной среде, цена этой переносимости - эф­


фективность. )аvа-программы выполняются медленнее, чем С++-программы. То
же справедливо и дЛЯ С#. Поэтому, если вы хотите создавать высокоэффектив­
ные приложения, используйте С++. Если же вам нужны переносимые програм­
МЫ, используйте]аvа или С#.

Спросим у опытного программиста

Вопрос. каким образом. 1I3ы'"Java u С# позволяют созihuJamь м.eжnлoтфopм.ен.­


ные (coвм.ecmuм.ыe с неclcолышAIu оrrераЦUОННbllllll cpeдaмu) nepeнocu­
JltЫe npozpaJl4JllЫ u м..ем.у С nом.ощью С++ невО3АСОЖНО iJocmuчь mmc010
же риультamа?

Ответ. Все дело в типе объектного кода, создаваемого компиляторам


В результате работы С++-компилятора мы получаем машинный код, ко­
торый непосредственно выполняется конкретным центральным процеl;­
сором (ЦП). Друrими словами, С++-компилятор связан с конкретными
ЦП и операционной системой. Если нужно выполнить С++-проrpамму
под управлением другой операционной системой, необходимо пt>реком­
пилировать ее и получить машинный lCOn, подходящий для данной среды.
Поэтому, чтобы С++-программа могла выполняться в различных средах,
нужно создать несколько выполняемых версий этой проrpaммы.

Используя языкиjаvа и С#, можно добиться переносимости програММНО­


го кода за счет специальной компиляции проrpамм, позволяющей пере­
вести исходный проrpаммный код на промежуточный язык, именуемый
nсевдо"одом. Для java-проrpамм этI)т промежуточный язык называют
байт-"одом (bytecode), Т.е. машинно-независимым кодом, генерируемым
jаvа-комnилятором. В результате КОМНИЛЯЦИИ C#-nporpaммw получается
не исполняемый I(ОД, а файл, который содержит специальный псевдоко;х,
именуемый nромежуmочнbI.М. язы."ОА! Мicrosоft (Microsoft Intemlediate
Language - MSI L). В обоих случаях :IТOT псевдокод ВЫnОJПfяется специ­
альной операционной системой, которая дляjаvа называется вuртуШlЬ­
НОй машuнойjаvа Оауа Virtual MaclUne - jVM), а ДЛЯ С# - средством
Соттоп Language Runtime (CLR). Следовательно, java-программа
сможет выполняться D любой среде, содержащей JVM, а C#-проrpамма -
в любой среде, в которой реализовано средство CLR.
ПОСКОЛЬКУ специальные операционные системы ДЛЯ выполнения java-
и С#-кода занимают промежуточное местоположение между проrpаммой
и цп, выполнениеjаvа- и С#-программ сопряжено с расходом определен­
ных системных ресурсов, что совершеllНО излишне при ВЫПОJПfеНЮI C+~'­
программ. Вот поэтому С++-программы обbIЧНО выполняются быстрее,
чем эквивалентные ПРОllJ3.ммы, написанные Hajava и С#.
С++: руководство ДЛ)) начинающих 29

и последнее. Языки C++,java и С# предназначены для решения различных


классов задач. Поэтому вопрос "Какой язык лучше?" поставлен некорректно.
Уместнее сформулировать вопрос иначе: "Какой язык наиболее подходит для ре­ t
u
шения данной задачи?". :D
ID
О

~ПРОСЫ ДI\'iI текущего l<онтрОл'il _ _ _ _ _ _ __


I
U
О

1. От какого языка программирования произошел С++?

2. Какой основной фактор обусловил создание С++?


3. Верно ли, что С++ является предком языков Java и С#?·

ВАЖНОI
58 0 бьектнn-nр и еЫZИРОВQ нн ое
программирование
Основополагающими для разработки С++ стали принципы объектно-ори­
ентированного программирования (ООП). Именно ООП явилось толчком для
создания С++. А раз так, то, прежде чем мы напишем самую простую С++-про­
грамму, важно понять, что собой представляют принципы ООП.
Объектно-ориентированное программирование объединило лучшие идеи
структурированного с рядом мощных концепций, которые способствуют более
эффективной организации программ. В самом общем смысле любую программу
можно организовать одним из двух способов: опираясь на код (действия) или на
данные (информация, на l<ОТОРУЮ направлены эти действия). При использова­
нии лишь методов структурированного программирования программы обычно
опираются на код. Такой подход можно выразить в использовании "кода, дей­
ствующего на данные".
Механизм объектно-ориентированного программирования основан на выборе
второго способа. В этом случае ключевым принципом организации программ яв­
ляется использование "данных, управляющих доступом !( коду". В любом 06ъек­
тно-ориентированном языке программирования определяются данные и процеду­

ры, которые разрешается применить к этим данным. Таким образом, тип данных в
точности определяет, операции какого вида можно примешпь к этим данным.

1. Язык С++ произошел от С.


2. Основной фактор создания С++ - повышеIше сложности ПРОll>амм.
3. Верно: С++ действительно является родительским языком для Java и С#.
30 Глава 1. Основы С++

ДЛЯ поддержки принципов объектно-ориеtIтированноro программирования


все языки ООП, включая С++, характеризуются следующими общими свойства­
ми: иmcaпсуляцией, полиморфизмом н наследованием. Рассмотрим кратко каж­
дое из ЭТИХ свойств.

ИнкапсуМlЦИЯ
Инкапсуляция - это такой механизм программирования, который связывает
воедино код и данные, им обрабатываемые, чтобы обезопасить их как от внешне­
го вмешательства, так и от неправильного исrlOJlьзоваиия. В объекпю-ориеНnf­
рованиом языке код и данные могут быть связаны способом, при котором созда­
ется самодостаточный черный ЯЩlJК. В этом "яшике" содержатся все необходимые
(для обеспечения самостоятельности) данные If код. При таком связывании кода
и данных создается объект, Т.е. 06ьекm - это КО:iСТРУКЦИЯ, котuрая поддерживает
инка.псу ляцию.

Спросим у опытного программиста

Вопрос. Я СЛЫIIUVI, .,то mep.JtIUH ".JtIemoij" прlLNeшrетCR " noдnpozpa.J/l..Jtle. Тогда


прагда ли то, что .JtIe1JIOiJ - это то же Ctl.JtlOe, что и ФУJlJСЦU?

Ответ. В общем CMblCJIe ответ: да. Термин "метод" популяри:ювался t: появлени·


ем языка Java. То, что C++-програММIIСТ называет функцией, Jаvа-про·
граммист называет м('Тодом. С#-программисты также используют термltн
U метод ". В виду такой широкой популярности этот термин все чаще r-та.1И
применять и к C++-фУНКlIии.

Внутри объекта код, данные или обе эти составляющие могут быть закРЫТЫ\fИ
в "рамках" этогообъекта или открытыми. Закрытый код (или данные) известен и
доступен только другим частям того же объекта. Другими словами, к закрытому
коду или данным не может получить доступ та часть программы, которая суще­

ствует вне этого объекта. Открытый код (или данные) доступен любым другим
частям программы, даже если они определены [. других объектах. Обычно откры­
тые части объекта используются для предоставления управляемого интерфейса
с закрытыми элементами объекта.
Базовой единицей инкапсуляции является класс. Класс определяет новый тип
данных, который задает формат 06ьекта. Класс' включает как данные, так и код,
предназначенный ДЛЯ выполнения над этими данными. Следовательно, класс
связы8em данные с "адом. В С++ спецификация класса используется для по-
С++: PYI(OBOACTBO ДЛ~ начинающих 31

строения объектов. Обьекты - это экземпляры класса. По сути, lUIacc представ­


ляет собой набор планов, которые определяют, К3..I( Cl'pUlITb объект.
В lUIacce данные объявляются в виде nереме1lЯЫХ. а КОД оформляется в 8ИДt:
+
+
u
фуmщий (1I0Дl1рограмм). Функции и переменныс, СОС1'авляющнс класс, назьша­ 1i
CD
ются его членами. Таким образом, переменная, объявленная в КЛi!ссе, называется О
1:
U
Ч:lеIlОМ дml1lЫХ, а функция, объявленная в классе, назьшаеТС>1 ФуIt1Щllей-ч/leIIOАI. О
ИlIогда вместо термина I(лен дmmых используется теРМЮI lzере.ме//uйя эюеАmляра
(или nереАfеllНая реализации).

ПолиморфИЗМ
Полиморфизм (от греческого <:Л.ова polym01p11ism, означающего "много форм") -
это свойство, позволяющее исnользовать один интерфейс для целого lUIacca дей­
ствиii. В качестве простого примера полиморфизма можно привести руль автомоби­
ля. Лля руля (т.е. шперфейса) безразлично, какой пш рулеоого механизма исполь­
зуется u автомобиле. Другим словами, руль работает одинаково. не:iависимо от того,
оснащеli ли автомобиль рулевым управлением прямоro деЙСТВIIЯ (без усилителя),
рулевым управлением с УСИЛИТeJlем или механизмом реечной lIсредачи. Если вы
знаете, как обращаться с рулем, вы сможете вести автомоБИЛI, любого ТИП8.
ТОТ же IIРИНЦИП можно применить к программировClНИJO. Рассмотрим, напри­
мер, стек, или список, добавление и удаление элементов к !{оторому осуществля­
ется по ПРИIiЦИПУ "последним прибыл - пеРПl)IМ обслужен". У "ас может быть
программа, А которой используются три различных типа стека. Один стек пред­
назначен ДЛЯ цеЛОЧJ1СЛСIШЫХ значений, второй - для значений с плавающей точ­
кой и третий - для символов. AлrОРlfТМ реализации всех стеков - один и тот
же. несмотря на то, что 1:1 них хранятся данные различных типов. В необъектно­
ориентированном языке программисту пришлось бы создать три различных ,.. а­
бора подпрограмм обслуживания с.тека, причем подпрограммы должны были бы
иметь различные имена, а каждый набор - собственный интерфейс. Но благо­
даря полиморфизму в С++ можно создать одии общий набор подпрограмм (один
интерфейс), который подходит для всех трех конкретных СИ1'УациЙ. Таким обра­
зом, зная, как использовать один стек, вы можете использовать все остальные.

В более общем виде концепция полиморфизма выражается фРaзQй "один ин­


терфейс - много методов". Это означает, что для группы связанных действий
можно использовать один обобщенный интерфейс. Полиморфизм позволяет по­
низить уровень сложности за счет возможности применения одного и того же ИН­

терфейса ДЛЯ задания общею класса действий. Выбор же кою(рemuоzo деиС1llfJUЯ


(т.е. функции) примени.тельно к той или иной ситуации ложится "на плечи" ком­
пилятора. Вам, как программисту, не нужно делать этот выбор вручную. Ваша
задача - использовать общий mперфеЙс.
32 Глава 1. Основы С++

НаслеАование
Ншледованue - это процесс, благодаря которому один объект может при обретать
свойства дpyt·oгo. Благодаря наследованию ПОJl.ll.ерживается концепция иерархи­
ческой классификации. В виде управляемой иерархической (нисходящей) класси­
фикации организуется большинство областей знаний. Например, яблоки Красный
Делишее являются частью классификации яблоки, которая в свою очередь является
частью класса фрукты, а тот - частью еще большего класса пища. Таким образом,
класс пища обладает определеtШЫМИ качествами (съедобность, питательность и пр.),
которые применимы и к подклассу фрукты. Помимо этих качеств, класс фрукты
имеет специфические характеристики (сочность. сладость и пр.), которые отличают
их от других пищевых продуктов. В классе я6JЮКU определяются качества, специ­
фичные для яблок (растут на деревЬЯХ, не тропические и пр.). Класс Красныйде:ш­
шее наследует качества всех предыдущих классов и при этом определяет качес1'ва,

которые являются уникальными для этого сорта яблок.


Ecmf не использовать иерархическое представление признаков, для каждого объ­
екта пришлось бы в явной форме определить все присущие ему характеристики. Но
благодаря наследованию объекту нужно доопределить только те качества, которые
делают его уникальным внуч>и его класса, поскольку он (объект) наследует общие
атрибуты своего родителя. Следовательно, именно механизм наследования позво.1Я­
ет одному объекту представлять конкретный экземпляр более общего класса.

~ПРОСЫ ДЛЯ текущего КОНТРОЛЯ - _ _ _ _ _ __


1. Назовите принципы ООП.

2. Что является основной единицей инкапсуляции в С++?

з. Какой термин в С++ используется для обозначения подпрограммы?·

и выполнение C++-прОграмм
Пора приступить к программированию. Для этого рассмотрим первую про­
стую С++-программу. Начнем с ввода текста, а затем перейдем к ее компиляции
и выполнению.

1. Принщmами ООП являются инкапсуляция, полиморфизм И наследование.


2. Базовой единицей инкапсуля:ции в С++ является класс.
3. Для обозначен!fЯ подпрограммы в С++ используется теРМИН "функция".
С++: руководство для начинающих 33

Спросим у опытного программиста


Вопрос. Ilы gm8ерЖdаете, "сто olJъeкmнo-opиeнтиpo8aннoe пpotpaJllJtlrlpOeaHue
+
(ООН) 1Iредcmа8ЛЯUII собоа эффекти8НЫЙ cnoc06 ynpаuенш 60ЛЬ­
lIШ.Ми 110 объе",,!! npotpaAl.AlQ.МU. Но не ознаwuuml ли это, ....0 для от­
u+
]5
ID
носительно не60лыllш npolpaJtlJtl иcnоль:юеtUШe 000 AIOжem 8Нести О
:J:
неоnpавданкые затраты cuсте.мных ресурсов? И cnраеедлuео ли это
для С++?
8
Ответ. Нет. Ключевым моментом для понимания применения ООП в С++ явля­
ется то, что оно позволяет писать объектно-ориентированные програм'
МЫ, но не явл.яется 06язателыlI.м требованием. в э'гом и заключаетur
одно из важных отличий С++ от Я3blКОВ Java и С#, которые предnолara­
ют использование строгой объектной модели в каждой программе. С++
просто предоставляет программисту возможности ООП. Более того, по
большей части объектно-ориентированные свойства С++ при выполне­
нии программы совершекно неэаметны, поэтому вряд ли стоит говорить

о каких-то ощутимых ззтратах системных ресурсов.

1*
Это простая С++-программа.

Назовите этот файл Sample.cpp.


*1

#include <iostrearn>
using namespace std;

11 С++-программа начинается с функции main().


int main ()

cout « "С++-программирование - это сила!";

return О;
}
Итак, вы ДОЛЖНЫ выполнить следующие действия.

1. Ввести текст программы.

2. Скомпилировать ее.

3. Выполнить.
34 Глава 1. Основы С++

Прежде чем ПрИC1)'lIать к выполнению этих действий, необходимо определить


два термина: исходный код и объектный код. Исходный код - это версия программ ы,
которую может читать человек. Она сохраняется в текстовом файле. Приведенный
выше листинг - это пример исходного кода. Вьmолняемая версия программы (она
создается компилятором) называется 06ьeютmым или выnолн.яе.мым "одо.м.

ВВОД текста программы


Программы, представленные в этой книге, можно загрузить с Web-сзйта ком­
пании Osborne с адресом: www.osborne.com. При желании вы можете ввести
текст программ вручную (это иногда даже полезно: при вводе кода вручную мы
запоминаете ключевые моменты). В этом случае необходимо использовать ка­
кой-нибудь текстовый редактор (например WordPad, если вы работаете в ОС
Windows), а не текстовой процессор (word processor). Дело в том, что при 8воде
текста программ должны быть созданы исключительно текстовые файлы, а не
файлы, в которых вместе с текстом (при использовании текстового процессо­
ра) сохраняется информация о его форматировании. Помните, что информация
о орматировании помешает работе С++-компилятора.
Имя файла, который будет содержать исходный код программы, формально
может быть любым. Но С++-программы обычно хранятся в файлах с расшиrе­
нием . срр. Поэтому называйте свои С++-программы любыми именами, но в ка­
честве расширения используйте . срр. Например, назовите нашу первую про­
грамму Sample . срр (это имя будет употребляться в дальнейших инструкциях),
а для других программ (если не будет специаЛJ,НЫХ указаний) выбирайте имена
по своему усмотрению.

Компилирование программы
Способ компиляции программы Sample. срр зависит от используемого ком­
пилятора и выбранных ОIЩИЙ. Более того, многие компиляторы, например ViStlal
С++ (Мiсrоsoft) и С++ Builder (Borland), предоставляют два различных способа
компиляции программ: с помощью компилятора командной строки и интегриро­
ванной среды разработки (lntegrated Development Environment - IDE). Поэтому
для компилирования С++-программ невозможно дать универсальные инструк­
ции, которые подойдут для всех компиляторов. Это значит, что вы должны сле­
довать инструкциям, приведенным в СОПРОВОДIfТельной документации, прилага­
емой к вашему компилятору.
Но, если вы используете такие популярные компиляторы, как Visual С++
и С++ Builder, то проще всего в обоих случаях компилировать и выполнять про­
граммы, приведенные в этой книге, с использованием компиляторов командной
С++: PYI<OBOACTBO для начинающих 35

строки. Например, чтобы скомпилировать программу Sample. срр, используя


Visua1 С++, введите следующую командную строку:
+
С:\ ... >сl -GX Sample.cpp u+
]1
Опция -GX предназначена для повышения качества компиляции. Чтобы исполь­
!3:I:
зовать компилятор командной строки Visual С++, необходимо выполнить пакет­ U
ный файл VСVАRSЗ2. bat, который входит в состав Visual С++. (В среде Visual О

Studio .NET можно перейти в режим работы по приглашению на ввод команды,


который активизируется выбором команды Мiсrоsоft Visual Studio .NET<=>Visual
Studio .NETTools<=>Visual Studio .NET Command Prompt из меню Пуск<=>Программы).
Чтобы скомпилировать программу Sample. срр, используя С++ Bui1der, введи­
те такую командную строку:

С:\ ... >ЬссЗ2 Sample.cpp


В результате работы С++-компилятора получается выполняемый объектный
код. Для Wiпdоws-среды выполняемый файл будет иметь то же имя, что и ис­
ходный, но другое расширение, а именно расширение. ехе. Итак, выполняемая
версия программы Sample. срр будет храниться в файле Sample. ехе.

Выполнение программы
Скомпилированная программа готова к выполнению. Поскольку результатом
работы С++-компилятора является выполняемый объектный код, то для запу­
ска программы в качестве команды достаточно ввести ее имя в режиме работы
по приглашению. Например, чтобы выполнить программу Sample. ехе, исполь­
зуйте эту командную строку:

C:\ ... >Sample.cpp


Результаты выполнения этой программы таковы:

С++-лрограммирование - это сила!

Если вы используете интегрированную среду разработки, то выплнитъ про­


грамму можно путем выбора из меню команды Run (Выполнитъ). Безусловно, более
точные инструкции приведены в сопроводительной документации, прилагаемой к
вашему компилятору. Но, как упоминалось выше, проще всего компилироватъ и вы­
полнять приведенные в этой книге программы с помощью командной строки.
Необходимо отметить, что все эти програмМbI представляют собой консоль­
ные приложения, а не приложения, основанные на применении окон, т.е. они вы­

полняются в сеансе приглашения на ввод команды (Command Prornpt). При этом


вам, должно быть, извecmо, что язык С++ не просто подходит для WIпdоws-про­
граммирования, С++ - основной язык, применяемый в разработке WIпdоws-прило­
жений. Однако ни одна из программ, представленных в этой книге, не использует
36 Глава 1. Основы С++

графический И1lТерфейс пользователя (graphics user interface - GUI). Дело в 1'ОМ,


что Windows - довольно сложная среда для написания программ, включающая
множество второстепенных тем, не связанных напрямую с языком С++. ДЛЯ соз­
дания Wiпdоws-программ, которые демонстрируют возможности С++, потребо­
валось бы написать сотни строк кода. В то же время консольные приложения го­
раздо короче графических и лучше подходят для обучения программированию.
Освоив С++, вы сможете без ilроблем примешlТЬ свои знания в сфере создания
Wiпdоws-приложеНиЙ.

Построчный ··разбор полетов·· nepBoro примера


nporpaMMbI
Несмотря на то что программа Sarnple. срр довольно мала по размеру, она,
тем не менее, содержит ключевые средства, хара ктерные для всех С ++- програм м.
Поэтому мы подробно рассмотрим каждую ее строку. Итак, наша программа на­
чинается с таких строк.

/*
Это простая С++-программа.

Назовите этот файл Sarnple.cpp.


*/
Это - Kaм.мeнmapUЙ. Подобно большинству других языков программирования,
С++ позволяет вводить в исходный код программы комментарии, содержание ко­
торых компилятор игнорирует. С помощью комментариев описываются или разъ­
ясняются действия, выполняемые в программе, и эти разъяснения предназначают·
ся для тех, кто будет читать исходный код. В данном случае комментарий просто
идентифицирует программу. Конечно, в реальных приложениях комментарии ис­
пользуются для разъяснения особенностей работы отдельных частей программы
или конкретных действий программных средств. Другими словами, вы можете ис­
пользовать комментарии для детального описания всех (или некоторых) ее строк
В С++ поддерживается два типа комментариев. Первый, показанный в нача­
ле рассматриваемой программы, называется .м.НОlострочuым. Комментарий этого
типа должен начинаться символами /* (косая черта и "звездочка") и заканчи­
ваться ими же, но переставленными в обратном порядке (* /). Все, что находит­
ся между этими парами символов, компилятор игнорирует. Комментарий этого
типа, как следует из его названия, может занимать несколько строк. Второй тнп
комментариев (однострочный) мы рассмотрим чуть ниже.
Приведем здесь следующую строку программы.

#include <iostream>
С++: PYI<OBOACTBO Mt;\ начинающих 37

в языке С++ определеtI ряд зшоловков (header), которые обычно содержат ин­
формацию, необходимую для программы. В нашу программу включен зaroловок
<iostream> (он используется ДЛЯ поддержки С++-системы ввода-вывода), ко­
торый представляет собой внешний исходный файл, помещаемый компилятором
в начало программы с помощью директивы # incl ude. Ниже в этой книге мы

: +
: +
:U
::0
'111
:0
::1:
ближе познакомимся с заголовками и узнаем, почему они так важны.

:0
Рассмотрим. следующую строку программы:

using namespace stdi


Эта строка означает, что компилятор должен использовать пространство имен s td
Пространства имен - относительно недавнее дополнение к языку С++. Подробнее о
них мы поговорим позже, а пока ограничимся их кратким определеНием. ПрocmраН­
ство имен (namespace) создает декларативную область, в которой могут размещать­
ся различные элементы программы. Пространство имен позволяет хранить одно
множество имен отдельно от дрyroго. С помощью этого средства можно упростить
организацию больших программ. Ключевое слово using информирует компилятор
об использовании заяв~енного пространства имен (в данном случае std). Именно
в пространстве имен s td объявлена вся библиотека стандарта С++. Таким образом,
используя пространство имен s td, вы упрощаете доступ к стандартной библиотеке
языка. (Поскольку пространства имен - относительно новое средство, старые ком­
пиляторы могут его не ПОДll.ерживать. Если вы используете старый компилятор, об­
ратитесь к приложению Б, чтобы узнать, как быть в этом случае.)
Очередная строка в нашей программе представляет собой одuоcmрочный ком­
ментарий.

// С++-программа начинается с функции main().


Так выглядит комментарий второго типа, поддерживаемый в С++. Одностроч­
ный комментарий начинается с пары символов // и заканчивается в конце стро­
ки. Как правило, программисты используют МliоrocтРОЧJiые комментарии ДЛЯ
подробных и потому более пространНblХ разъяснений, а ОДНОСТРОЧНblе - для
кратких (построчных) описаний инструкций или назначения переменных. Во­
обще-то, характер использования комментариев - ЛИЧJiое дело программиста.
Перейдем к следующей строке.

int main ()
Как сообщается в только что рассмотренном комментарии, именно с этой строки
и начинается выполнение программы.

Все С++-программы состоят из одной или нескольких функций. (Как упоми­


н3Jюсь выше, под функцией мы понимаем подпрограмму.) Каждая С++-функция
имеет имя, И только одна из них (ее должна включать каждая С++-программа)
называется main (). Выполнение С++-программы начинается и заканчивается
38 Глава 1. Основы С++

(в большинстве случаев) выполнением функции main (). (Точнее, С++-про­


грамма начинается с вызова функции main () и обычно заканчивается возвра­
том из функции main ().) Открытая фигурная скобка на следующей (после int
main ( » строке указывает на начало кода функции main ( ). Ключевое слово
int (сокращеНJiе от слова integer), стоящее перед именем main (), означает тип
данных для значенJiЯ, возвращаемого функцией main (). Как вы скоро узнаете,
С++ поддерживает несколько встроенных типов данных, и int - один из них.
Рассмотрим очередную строку программы:

cout « "С++-программирование - это сила!";

это инtтp)'КЦl1Я вывода данных на консоль. При ее выполнении на экране компыо­


тера отобразlПСЯ сообщение С++-программирозание - это сила!. В этой ин­
струкции используется оператор вывода "«". Он обеспеЧJШaет вывод выражения,
стоящего с правой стороны, на устройство, указанное с левой. Слово сои t представ­
ляет собой встроеtшый JiДентификатор (составлеtmый из частей слов C01JSo/e output),
который в большинстве случаев означает экран компьютера. Итак, рассматриваемая
инструкция обеспечивает вывод заданноro сообщения на экран. Обратите внимание
на то, что эта инструкция завершается точкой с запятой. В действительности все вы­
полняеМhlе С++-инструкции завершаются точкой с запятой.
Сообщение "С++-программирование - это сила!" представляет собой
строку. В С++ под строкой понимается последовательность символов, заключен­
ная в двойные кавычки. как вы увидите, строка в С++ - это один из часто ис­
пользуемых элементов языка.

А этой строкой завершается функция main ():


return О;

При ее выполнении функцJiЯ main О возвращает вызывающему пРощ.оссу


(в роли которого обычно выступает операционная система) значение О. ДЛЯ боль­
шинства операционных систем нулевое значение, которое возвращает эта функ­
ЦИЯ, свидетельствует о нормальном завершеНIIИ програмМЫ. Другие значения
MOtyT означать завершение программы в связи с какой-нибудь ошибкой. Слово
return относится к числу ключевых и используется для возврата значения из

функции. При нормальном завершении (т.е. без ошибок) все ваши программы
должны возвращать значение О.
Закрывающая фиrypная скобка в конце програММbJ формально завершает ее.

Обработка синтаксических ошибок


Введите текст только что рассмотренной программы (если вы еще не сделали это),
скомпилируйте ее и выполните. Каждому програ.\tМИСТУ известно, насколько легко
С++: PYI<OBOACTBO ДI\~ начинающих 39

при вводе текста проrJ>аммы в компьютер вносятся случайные ошибки (опечатки). К


счастью, при попытке скомпилировать такую программу компилятор "просиmaлит"
+
сообщением о наличии cuнmaкt:UЧeCКUX ошибок. Большинство С++-компи.ляторов
u+
поDыаются "увИдеть" смысл в исходном коде пJюгрзммы' неэависимо от того, что
iR
вы ввели. Поэтому сообщение об ошибке не всегда отражает истинную причину про­ о
:I:
U
блемы. Например, если в предыдущей ПРОrJ>змме случайно опустить открывающую О
фигурную скобку после имени фymщии та in ( ) , компилятор укажет в качестве ис­
точника ошибки инструкцию сои t. Поэтому при получении сообщения об ошибке
просмотрите две-три строки кода. непосредственно предшествующие строке с "об­
наруженной" ошибкой. Ведь иногда компилятор начинает "чуять недоброе" только
через несколько строк после реального местоположения ошибки.

Спросим у опытноrо проrраммиста

Вопрос. ПОJICWlCО сообщений 06 Оlllибках JlCOU C++-кО.JtmWUUrJОР 8ьЮаem fJ Кalfе­


cmfJe резульmатОfJ CfJoeu работы и nреiJррежiJенUR. Уем же npeiJy-
npежiJенu.я оmлwшютс. от оllltlбок и ка слеiJyem petullpOfJa",. на них?
Ответ. действительно, мноrnе C++-КОМlIИЛЯТоры выдают В качестве результатов
своей работы не только сообщения о неисправиМhIX синтаксических ошиб­
ках, но и предупреждения (waming) различных типов. Если компилятор
"уверен" D некорректности программного кода (например, инструкция не
завершается точкой с запятой), он сиmа.лизирует об ошибке, а если у него
есть лишь "подозрение" на некорректностъ при видимой правильности с
точки зрения синтаксиса, то он выдает предупреждение. Тогда программист
сам должен оценить, насколько справедливы подозрения компилятора.

Предупреждения также можно использовать (по желанию программиста)


для информирования о применении в коде неэффекmвных конструкций
или устаревших средств. Компиляторы позволяют выбирать различные
опции, которые могут информировать об интересующих вас вещах. Про­
граммы, приведенные в этой книге, написаны в соответствии со стандар­
том С++ и при корректном вводе не должны генерировать никаких пред­
упреждающих сообщений.
Для примеров этой книги достаточно использовать обычную настрой­
ку компилятора. Но вам все же имеет смысл эаглянугь в прилагаемую к
компилятору документацию и поинтересоваться, какие возможности по

управлению процессом компиляции есть в вашем распоряжении. Многие


компиляторы довольно "интеллектуальны" и могут помочь в обнаруже­
нии неочевидных ошибок еще до того, как они перераС1)'Т в большие про­
блемы. Знание принципов, используемых компилятором при составлении
отчета об ошибках, .стоит затрат времени и усилий, которые потребуются
от программиста на их освоение.
40 Глава 1. Основы С++

~npocы МЯ текущего контроля - - - - - - - -


1. С чего начинается выполнение С++-программы?

2. Что такое cout?


З. Какое действие выполняет инструкция ~ include <iostream>?·
=

Возможно, самой важной конструкцией в любом языке программировання


является переменнcut. Пере.менная - это именованная область памяти, в которой
MOryт храниться различные значения. При этом значение переменной во время
выполнения программы можно изменить. Другими словами, содержимое пере­
менной изменяемо, а не фиксированно.
В следующей программе создается перемеиная с именем length, которой
присваивается значение 7, а затем на экране отображается сообщение Значение
переменной length равно 7.
// Использование переменной.

#include <iostream>
using namespace std;

int main ()
{
int length; // ~ Здесь об~.етCR переиеина•.

length = 7; / / Переиениой lenqth присваиааетс. чиcnо 7.

cout « "Значение переменной length равно ";


cout « length; // ОТображаетCR значение переиеиной
// lenqth, Т.е. чиcnо 7.

1. Любая С++-программа начинает выполнение с функции тШпО.


2. Слово cout представляет собой встроенный идентификатор, который имеет отно­
шение к выводу данных на консоль.

З. Она включает в код программы заголовок <iostream>, который lIоддерживает


функционирование системы ввода-вывода.
С++: руководство ДI\.~ начинающих 41

return О;

+
Как упоминалось выше, для С++-программ можно выбирать любые имена. +
u
Тогда при вводе текста этой программы дадим ей, скажем, имя VarDemo. срр. 2i
ID
О
Что же нового в этой программе? Во-первых, инструкция I:
(J
int length; // Здесь объявляется переменная. О

объявляет переменную с именем length целочисленного типа. В С++ все перемен­


ные ДОЛЖНЫ быть объявлены до их использования. В объявлении переменной по­
мимо ее имени необходимо указать, значения какого типа она может храниТЬ. Тем
самым объявляется тип переменной. В данном случае переменная length может
хранить цслочисленные значения, т.е. целые числа, лежащие в диапазоне -32 768-
32767. В С++ для объявления перемеllliОЙ целочисленного типа достаточно поста­
вить перед ее именем ключевое слово int. Ниже вы узнаете, что С++ поддерживает
широкий диапазон встроенных типов переменных. (Более того, С++ позволяет про­
граммисту определять co6cTBeHtrwe типы данных.)
Во-вторых. при выполнении следующей инструкции переменной присваива­
ется KOHKpeTHQe значение:

length = 7; // Переменной length присваивается число 7.


Как отмечено в комментарии, здесь переменной length присваивается число 7.
В С++ оператор nрисваuванuя представляется одиночным знаком равенства (=).
Его действие заключается в копировании значения, расположенного справа от
оператора, в переменную, указанную слева от него. После выполнения этой ин­
струкции присваивания переменная length будет содержать число 7.
Обратите внимание на использование следующей инструкции для вывода
значения переменной length:
cout « length; // Отображается число 7.
В общем случае для отображения значения переменной достаточно в инструк­
ции cout поместить ее имя спраоа от оператора "«". Поскольку в данном кон­
кретном случае переменная length содержит ЧИCJЮ 7, то оно и будет отображено
на экране. Прежде чем переходить к следующему разделу, попробуйте присвоить
пере мен ной length другие значения (в исходном коде) и посмотрите на резуль­
таты выполнения этой программы после внесения изменений.

Подобно большинству других языков программирования, С++ поддерживает


полный диапазон арифметических операторов, которые позволяют выполнять
42 Глава 1. Основы С++

действия над числовыми значениями, используемыми в программе. Приведем


самые элементарные.

+ Сложение
Вычитание
* Умножение
/ Деление

Действие этих операторов совпадает с действием аналогичных операторов в


алгебре.
В следующей программе оператор "*" исполъэуется для вычисления площади
прямоугольника, заданного его длиной и шириной.

// Использование оператора.

#include <iostream>
using narnespace std;

int rnain ()
{
int length; // Здесь объявляется п~ременная.
int width; / / Здесь объявляется В'l'орая переменная.
int area; // Здесь объявляется третья переменная.

length = 7; // Число 7 присваивается переменной length.


width = 5; // Число 5 присваивается переменной width.

area length * width; // ~ Здесь зычиcn.е~СR nnощад&


/ / DpJDIОУГОJIЪниха, а реЗУJIЪ~а~ Dpоизведевия:
// звачений aepeкeRRНX lenqth и vidth
// прксваиаае~~ аерекенной area.

cout « "ПЛощадь прямоугольника равна ";


cout « area; // Здесь отображается число 35.

return О;

в этой npoграмме сначала объявляются три перс~менные


length, width и area.
Затем переменной length присваивается число
7, а переменной width - число 5.
После этого вычисляется произведение значений переменных length и width
(т.е. вычисляется площадь прямоугольника), а результат умножения присваи­
вается переменной area. При выполнении программа отображает следующее.
С++: PYI<OBOACтaO для начинающих 43

ПЛощадь прямоугольника равна 35.


В этой программе в действительности нет никакой необходимости в исполь­
+
зовании переменной Поэтому предыдущую программу можно переписать
area.
u+
следующим образом. J5
11 Упрощенная версия программы вычисления площади
!3:I:
U
11 прямоугольника. О

#include <iostream>
using namespace std;

int main ()
{
int length; 11 Здесь объявляется переменная.
int width; /1 Здесь объявляется вторая переменная.

length = 7; /1 Число 7 присваивается переменной length.


width = 5; /1 Число 5 присваивается переменной width.

cout « "Площадь прямоугольника равна ";


cout « length * width; 1/ Здесь о~обраааетс. чиcnо 35
11 (реsуnьта~ 8wпоnвеИКR
11 операции lenqth * vidth
11 8JoI80,QИ'Ж'CJI на эхраи В&ПрJDlP) •
return О;

в этой версии площадь прямоугольника вычисляется в инструкции сои t пу­


тем умножения значений переменных length и width с последующим выводом
результата на экран.

Хочу 06ратИ1:Ь ваше внимание на то, что с помощью одной и той же инструк­
ции можно объявить не одну, а сразу несколько перемеНIiЫХ. Для этого достаточ­
но разделить их имена запятыми. Например, переменные length, width и area
можно было бы объявить таким образом.
int length, width, area; 11 Все переменные объявлены в
// одной инструкции.

В профессиональных С++-npограммах объявление нескольких переменных в


одной инструкции - обычная практика.
44 Глава 1. Основы С++

~просы мя текущего контроля --------


1. Необходимо ли переменную объявлять до ее использования?
2. Покажите, как переменной min ПРИСВОИ1Ъ значение о.

з. Можно ли в одной инструкции объявить сразу несколько переменных?-

в предыдущих при мерах действия ВЫПОЛНЯЛIIСЬ над данными, которые явным


образом были заданы в программе. Например, в программе вычисления площади
выполнялось умножение значений сторон прямоугольника, причем эти МIЮЖII­
тели (7 и 5) являлись частью самой программы. Безусловно, процесс вычисле­
ния площади прямоуголъника не зависит от размера ero сторон, поэтому наша

программа была бы гораздо полезнее, если бы при ее выполнении пользователю


предлагалось ввести размеры прямоугольника с клавиатуры.

Чтобы пользователь мог ввести данные в программу с клавиатуры, можно


применить оператор "»". Это С++-оператор ввода. Для считывания данных с
клавиатуры используется такой формат этого оператора.

cin » vpr;
Здесь cin - еще ОДИН встроенный идентификаl0Р. Он составлен из частей слов
console input и автоматически померживается средстоами С++. По умолчанию
идентификатор cin связывается с клавиатурой, хотя ero можно перенаправИ1Ь
и на другие устроЙства. Элемент var означает переменную (указанную с правой
стороны от оператора "»"), которая принимает вводимые данные.
Рассмотрим новую версию программы вычисления площади, которая позво­
ляет пользователю вводить размеры сторон прямоугольника.

/*
Интерактивная программа, которая вычисляет

площадь прямоугольника.

*/

iinclude <iostream>

1. Да. в С ++ переменные необходимо объявлять до их использования.


2. min ~O;
3. Да, в одной инструкции можно объявить сразу несколько переменных.
С++: pyr<OBOACтeO ДЛЯ начинающих 45

using namespace stdi

int main () +
{
u+
:JS
11:1
int length: // Здесь объявляется переыеииая. О
:I:
Здесь объявляется вторая переме~ная.
int width: // 8
cout « "Введите длину прямоугольника: ":
cin » length: // ВВОД sначеВИR дnивu прсиоyr~RИXа
// (~.e. значеИИR аерекеввой lenqth)
/ / с 1UIaвKa~yp...

cout « "Введите ширину прямоугольника: ":


cin »widthi / / ВвОД значеlUDl IIIКpИIВI пря:коyrom.виха
// (~.e. звачеНИR аеРек."оЙ vidth)
/ / с 1UIaвKa~...

cout « "Площадь прямоугольника равна ":


cout « length * width: // Отображение эначения площади.

return О:

Вот один из возможных результатов выполнения этой програмМЫ.

Введите длину прямоугольника: 8


Введите ширину прямоугольника: 3
Площадь прямоугольника равна 24
Обратите особое внимание на эти строки программы.

cout « "Введите длину прямоугольника: ";


cin » length: // Ввод значения длины прямоугольника

Инструкция cout приглашает пользователя ввести данные. Инструкция cin


считывает ответ пользователя, запоминая его в пере мен ной length. Таким обра­
зом, значение, введенное пользователем (которое в данном случае представляет
собой целое число), помещается в переменную, расположенную с правой сторо­
ны от оператора "»" (В данном случае переменную leFlgth). После выполнения
инструкции cin переменная length будет содержать значение длины прямоу­
roльника. (Если же пользователь введет нечисловое значение, переменная length
получит нулевое значение.) Инструкции, обеспечивающие ввод и считывание
значения ширины прямоугольника, работают аналогично.
46 Глава 1. Основы С++

Вариации на тему вывода данных


До сих пор мы использовали самые простые типы инструкций сои t. Однако в
С++ предусмотрены.и другие варианты вывода ;l:aнHblx. Рассмотрим два из них.
Во-первых, с помощью одной инструкции сои t можно выводить сразу несколь­
ко порций информации. Например, в программе вычисления площади для ото­
бражения результата использовались следующш: две строки кода.

cout « "ПЛощадь прямоугольника равна ";


cout « length * width;
Эти две инструкции можно заменить одной.

cout « "Площадь прямоугольника равна " « length * width;


Здесь в одной инструкции cout используется два оператора "«", которые по­
зволяют сначала вывести строку "Площадь лрямоугольника равна ", затем
значение площади прямоугольника. В общем случае в одной инструкции cout
можно соединять любое количество операторов зывода, предварив каждый эле­
мент вывода "своим" оператором "«".
Во-вторых, до сих пор у нас не было необходимости в переносе выводимых
данных на следующую строку, Т.е. в выплненIIии последовательности команд

"возврат каретки/перевод строки". Но такая необходимость может появиться до­


вольно скоро. В С++ упомянутая выше последовательность команд генерируется
с помощью CUМВOJllJ навой строки. Чтобы поместить этот символ в строку, исполь·
зуйте код \п (обратная косая черта и строчная буква "п"). Теперь нам остается на
практике убедиться, как работает последовательность \п.

/*
в этой программе демонстрируется и,::пользование кода \п,
который генерирует переход на новую строку.

*/
finclude <iostream>
using namespace std;

int main ()
{
cout « "один\п";
cout « "два\п";
cout « "три";
cout « "четыре";

return О;
С++: руководство ДЛЯ начинающих 47

При выполнении эта программа генерирует такие результаты.

один
+
два
u+
тричетыре :i5
~
Символ новой строки можно размещать в любом месте строки, а не только в :r
конце. Вам стоит на практике опробовать различные варианты применения кода 8
\n, чтобы убедиться в том, что вам до конца понятно его назначение.

~ПРОСЫ A/IЯ теl<ущего l<онтрОл'i1 _ _ _ _ _ _ __


1. Какой оператор используется в С++ дЛЯ вводаДaJШЫХ?
2. С каким устройством по умолчанию связан идентификатор cin?
3. Что означает код \n?*

Познакомимся еще с ОДНИМ


ТИПОМ данных
В предыдущих программах использавались переменные типа int. Однако
перемеlfные типа in t могут содержать только целые числа. И поэтому их нельзя
использовать для представления чисел с дробной частью. Например, персмеЮJая
типа int может хранить число 18, но не значение 18,3. К счастью, в С++, кроме
in t, определены и другие типы данных. Для работы с числами, имеющими дроб­
ную часть, в С++ предусмотрено два типа данных с плавающей точкой: float и
double. Они служат для представления значений с одинарной и двойной точ­
tlОСТЬЮ соответственно. Чаще в С++-программах используется тип double.
Для объявления переменной типа double достаточно написать инструкцию,
подобную следующей.

double result;
Здесь resul t представляет собой имя переменной, которая имеет тип
double.
Поэтому перемеииая resul t может содержать такие значеиия, как 88,56, 0,034
или -107,03.

1. Для ввода данных в С++ используется оператор "»".


2. По умолчанию идентификатор cin связан с клавиатурой.
З. Код \п означает символ ноnой строки.
48 Глава 1. Основы С++

Чтобы лучше понять разницу между типами дaJmыx iлt и double, рассмотрим
следующую npoграмму.

/*
Эта лрограмма иллюстрирует различия между типами

данных iлt и double.


*/

liлсludе <iostream>
using namespace std;

int mаiл () {
int ivar; // Здесь объявляется переменная типа int.
double dvar; // Здесь объявляется переменная типа double.

ivar 100; // Переменная ivar получает значение 100.

dvar = 100.0; // Переменная dvar получает значение 100.0.

cout « "Исходное значение переменной ivar: " « ivar


« "\п";
cout « "Исходное значение перемеНЕОЙ dvar: " « dvar
« "\п";

cout « "\п"; // ВМвОДИJI ПУС~ С!1'роху.

// А теперь делим оба значения на З.


ivar ivar / 3;
dvar = dvar / 3.0;

cout « "Значение ivar nOC.:tIe деления: " « ivar « "\п";


cout « "Значение dvar после деления: " « dvar « "\п";

return О;

Вот как ВЫГЛЯДЯТ результаты выполнения этоii программы.

Исходное значение переменной ivar: 10~


Исходное значеНие переменной dvar: 10)
С++: руководство ДЛ)! начинающих 49

Значение ivar после деления: 33


Значение dvar после деления: 33.3ЗЗЗ

Как видите, при делении значения переменной i var на 3 выполняется цело­ :t


u
численное деление, в результате которого (33) теряется дробная часть. Но при 2i
са
О
делении на 3 значения переменной dvar дробная часть сохраняется. :r
u
В этой ПРО'1>амме есть еще новая деталь. Обратите внимание на эту строку. О

cout « "\n"; // Выводим пустую строку.

При выполнении этой инструкции IlРОИСХОДИТ переход на новую строку. Ис­


пользуйте эту инструкцию в случае, когда нужно разделить выводиМые данн'ые
пустой строкой.

Спросим V опытного программиста


Вопрос. Почему в С++ существgют различные типы аанных дм npeдcmавле­
НIIR целых IfUсел и ЗNQlfeHUU с плавающей точкой? ПочеJfCУ бы все чис­
ловые зна.,енllR "е представлять с nОJfCощью оОного типа данных?

Ответ. В С++ предусмотрены различные типы даиных, чтобы программиеты


могли создавать эффективные про граммы. Например, вычисления с не­
ПОЛЬ."JО8aJ-lием Цt'ЛОЧИCJIенной арифметики выполняются гораздо быстрее,
чем вычислею1Я, производимые над значениями е плавающей точкой. Та­
ким образом, если оам не нужны значения с дробной частью, то вам и не
стоит зря расходовать системные ресурсы, соязанныс с обработкой таких
типов данных, как Ноа t или double. Кроме того, для хранения значе­
ний различных пmов требуются разные по размеру области пaмsrrи. Под­
держивая различные типы данных, С++ позволяет программисту выбрать
:;1
наилучший вариант использования системных ресурсов. Наконец, для не­
которых алгоритмов требуется использование данных конкретного nmа. i•
И потом, широкий диапазон встроенных С++-типов данных предоставля­
ет программисту проявнтъ максимальную гибкость при реализации реше­
ний разнообразиых задач программирования.
!

Проект 1.1. ',l r4l: ~~, rl~ФJ. : \' ~- 'I'J,.V,


1
, FtoM. срр Несмотря на то что в предыдущих примерах программ были
продемонстрированы важные средства языка С++, они полезны
больше с точки зрения теории. Поэтому важно закрепить даже те немногие све­
ден ия, которые вы уже почерпну ли о С + + , при создании практических программ.
В этом проекте мы напишем про грамму перевода футов в метры. Программа
50 Глава 1, Основы С++

должна предложить пользователю ввести значение в футах, а затем отобразить


значение, преобразованнос в метры.
Один метр равен приблизительно 3,28 футам. Следовательно, в программе мы
должны использовать представление данных с плавающей точкой. для выпол­
нения преобразования в программе необходимо объявить две переменные типа
double: одну для хранения значения в футах, а другую для хранения значения,
преобразованного в метры.

Последовательность действий
1. Создайте новый С++-фзйл с именем Ftc.M. срр. (Конечно, вы можете вы­
брать для этого файла любое другое имя.)

2. Начните программу следующими строками, которые разъясняют назначе­


ние программы, включите заголовок iозtrеаm и укажите пространство
имен std.
/*
Проект 1.1.

Эта про грамма преобразует фУ'ГЫ в метры.

Назовите программу FtoM.cpp.


*/

#include <iostream>
using namespace std;
3. Начните определение функции main () с объявления переменных f и!'.1.
int main () {
double f; / / содержит длину в футах
double т; // содержит результат преобразоваНИR в метрах

4. добавьте код, предназначенный для ввода значения в футах.

cout « "Введите длину в фута>!: ";


cin » f; 1/ считывание значения, выраженного в футах

5. добавьте код, которые выполняет преобраэование в метры и отображает


результат.

m = f 1 3.28; /1 преобразование в метры


cout « f « " футов равно n « m « " метрам.";
С++: PYI<OBOACTBO МЯ начинающих 51

6.

7.
Завершите программу следующим образом.
return О;

Ваша законченная программа должна иметь такой ВИД.


-
~
:U
:~
t
'1:11
:0
::1:
/* :U
Прое1(Т 1.1.
:0

Эта программа преобразует футы в метры.

Назовите про грамму FtoM.cpp.


*/

#include <iostrearn>
using narnespace std;

int rnain () {
double f; // содержит длину в футах
double т; // содержит результат преобразования в ме­
трах

cout « "Введите длину в футах: ";


cin » f; // считывание значения, выраженного в футах

rn = f / 3.28; // преобразование в метры


cout « f « " футов равно" « rn « " метрам.";
t-
return О;
!

I
8. СJ,(омпилируйте и выполните программу. Вот как выглядит один из воз­
можных результатов ее выполнения.

Введите длину в футах: 5


5 футов равно 1.52439 метрам.

9. Попробуйте ввести другие значения. Л теперь поnытайтесь изменить про­


грамму. чтобы она преобразовывала метры в футы.
52 Глава 1. Основы С++

~npocы для текущего контроля --------


1. Какое С++-ключевое слово служит ДЛЯ объявления данных целочислен­
ноготипа ?
2. Чтоозначаетсловоdоublе?

з. как вывести пустую строку (или обеспечить переход на новую строку)?·


-
управления if и for
Внутри функции выполнение инструкций происходит последовательно.
сверху вниз. Однако, используя различные инструкции управления, поддержи­
ваемые в С++, такой порядок можно измеНИ1Ь. Позже мы рассмотрим эти ин­
струкции подробно, а пока кратко представим их, чтобы можно было восполь:ю­
ваться ими для написания следующих примеров программ.

ИНСТРУКЦИЯ if
Можно избирательно выполнить часть программы, используя инструкцию
управления условием i f. Инструкция i f в С -\ + действует подобно инструкции
"IF", определенной в любом другом языке программирования (например C.Java
и С#). Ее простейший формат таков:

if(условие) инструкция;

Здесь элемент условие - это выражение, которое при вычислении может ока­
заться равным значению ИСТИНА ИЛИ ЛОЖЬ. В С++ ИСТИНА представля­
ется ненулевым значением, а ЛОЖЬ - нулем. Если условие, или условное вы­
ражение, истинно, элемент инструкция выполнится, в противном случае - нет.

НапрИМеР, при выполнении следующего фрагмента кода на экране отобразится


фраза 1 О меньше 11, потому что число 10 действительно ~еньше 11.
if(10 < 11) cout <~ "10 меньше 11";

1. Для объявления данных целочисленного ПIПa служит ключевое слово int.


2. Слово double является ключевым и используется для объявления данных с плавающей
ТОЧКОй двойной точности.

3. Для вывода пустой строки используется код \п.


С++: PYI(OBOACTBO для начинающих 53

Теперь рассмотрим такую строку кода.

if(10 > 11) cout « "Это соое5щение никогда не отое5раЭИТСЯ"i

В этом случае число 10 не больше 11, поэтому инструкция cout не выполнит­


t
u

ся. Конечно же, операнды в инструкции i f не должны всегда быть константами. 111
о
Они могут быть переменными. :J:
U
В С++ определен полныА набор операторов отношений, которые используют­ О

ся в условном выражении. Перечислим ИХ.

Равно
!= Не равно
> Больше
< Меньше
>= Больше или равно
<= Меньше или равно

Обратите внимание на то, что для проверки на равенство используется двой­


ной знак "равно".
Теперь рассмотрим программу, в которой демонстрируется использование ин­
струкции Н.

// Демонстрация использования инструкции if.

#include <iostream>
using namespace stdi

int main ()
int а, Ь, С;

а = 2;
Ь З;

if (а < Ь) cout « "а меньше Ь\п"; / / +-(--

// Эта инструкция ничего не отобразит.


if(a Ь) cout « "Этого вы не увидите.\п";

cout « "\п";

с = а - Ь; // Переменная с содержит -1.

cout « "Переменная с содержит -1.\п";


54 Глава 1. OCl10BbI С++

if(c >= О) cout « "Значение с неотрицательно.\п";


if(c < О) cout « "Значение с отрицательно.\п";

cout « "\п";

с = ь - а; // Теперь переменная с содержит 1.


cout « "Переменная с содержит 1.\п";
if(c >= О) cout « "Значение с неотрицательно.\п";
if(c < О) cout « "Значение с отрицательно.\п";

return О;

При выполнении эта программа генерирует такие результаты.

а меньше Ь

Переменная с содержит -1.


Значение с отрицательно.

Переменная с содержит 1.
Значение снеотрицательно.

ЦИКЛfоr
Мы можем организовать повторяющееся выполнение одной и той же после­
дователыюсти инструкций с помощью специальной конструкции, именуемой
ЦUКЛОМ. В С++ предусмотрены различные ВИДЫ циклов, и одним из них являетея
цикл for. Для тех, кто уже не новичок в программировании, отмечу, что в С+ +
цикл for работает так же, как в языках С# или Java. Рассмотрим простейший
формат использования цикла for.
fоr(инициализация; условие; инкременr) инструкция;

Элемент инициализация обычно представляет собой инструкцию присваи­


вания, которая устанавливает управляющую nере.менную цuкла равной неко­
торому Ifачальному значению. Эта переменная действует в качестве счетчи­
ка, который управляет работой цикла. Элемент условие представляет собой
условное выражение, в котором тестируется значение управляющей пере­
мен ной цикла. По результату этого тестирования определяется, выполнится
цикл for еще раз или нет. Элемент инкремент - это вцражение, которое
определяет, как изменяется значение управляющей переменной цикла после
каждой итерации (т.е. каждого повторения элемента инструкция). Обратите
С++: РУКОВОДСТВО для начинающих 55

внимание на то, что все эти элементы цикла for должны отделяться точкой с
запятой. Цикл for б~/:tет выполняться до тех пор, пока вычисление элемента
+
условие дает истинный результат. Как только это условное выражение ста­
нет ложным, цикл завершится, а выполнение программы продолжится с ин­
u+
25.
m
струкции, следующей за циклом for. О
1:
()
Использование цикла for демонстрируется в следующей программе. Она вы­ О
водит на экран числа от 1 до 100.

11 Программа, иллюстрирующая ЦИКЛ for.

iinclude <iostream>
using hamespace std;

int main ()
{
int count:

for(count=l: count <= 100: count=count+1) // циxn ~Qr


cout « count « " ":

return О;

в этом цикле переменная count инициализируется значением 1. При каждом


повторении тела цикла проверяется условие цикла.

count <= 100;


Если результат проверки истинен, на экран будет выведено значение переменной
count, после чего управляющая переменная цикла увеличивается на единицу.

Когда значение переменной count превысит число 100, проверяемое в цикле


условие станет ложным, и цикл остановится.

В ПРофСССИОllальных С++-программах вы не встретите инструкции

count=count+1,
или подобной ей, поскольку в С++ существует специальный оператор инкре­
мента, который выполняет операцию увеличения значения на единицу более эф­
фективно. Оператор инкремента обозначается в виде двух знаков "плюс" (+ +).
Например, инструкцию for из приведенной выше программы с использованием
оператора "++" можно переписать так.

for(count=l; count <= 100; count++) // ЦИКЛ for


cout « count « " ";
56 Глава 1. Основы С++

в остальной части книги для увеличения значения переменной на едиmщу


омы будем использовать оператор инкремента.
В С++ также реализован оператор декремента, который обозначается двумя
знаками "минус" (--). Он применяется для уменьшения значения переменной
на единицу.

~ПРОСЫ ДI\<;1 текущего коН!Рол<;1----------


1. Каково назначение инструкции i f?
2. Для чего предназначена инструкция for?
З. Какие операторы отношений реализованы в С++?*

Одним из ключевых элементов С++ является бло" "ода. Блок - это логически
связанная группа программных инструкций (т.е. одна или несколько инс-rрук­
ций), которые обрабатываются как единое целое. В С++ программный блок соз­
дается путем размещения последоватеЛЬНОСТIf инструкций между фигурными
(открывающей и закрывающей) скобками, После создания блок кода становится
логической единицей, которую разрешено использовать везде, где можно приме­
нять одну инструкцию. Например, блок кода может составлять тело инструкций
if или for. Рассмотрим такую инструкцию if'.
i f (w < h) {
v w * h;
w = О;

Здесь, если значение переменной w меньше значения переменной h, будут вы­


полнены обе инструкции, заключенные в фИl'урные скобки. Эти две инструк­
ции (вместе с фигурными скобками) представляют блок кода. Они составля­
ют логически неделимую группу: ни одна из этих инструкций не может вы­
полниться без другой. Здесь важно понимап., что если вам нужно логически

1. Инструкция if - это инструкция условного выполнения части кода програмМЫ.


2. Инструкция {or - одна из инструкций цикла в С++, которая предназначена для
организации повторяющеroся выполнения некоторой последовательности ин­
струкций.
3. В С++ реализованы такие операторы отношеннй: =~, 1-, <, >, <- И >-.
С++: PYI<OBOACTBO для начинающих 57

связать несколько инструкций, это легко достигается путем создания блока.


Кроме того, с использованием блоков кода многие алгоритмы реализуются
более четко и эффективно.
+
u+
Рассмотрим программу, в которой блок кода позволяет предотвратить деле­ 21
111
ние на нуль. О
1:
U
// Демонстрация использования блока кода. О

#include <iostream>
using namespace stdi

int main ()
double result, n, di

cout « "Введите делимое: ";


cin » ni

cout « "Введите делитель: ";


cin » di

// Здесь инструкция if управляет целым блоком.


if (d ! = О) {
cout « "Звачение d не р_но О, дenеlDlе осущеС'1'llJDIО."

« "\n".i
result = n I di
cout « n « " I " « d « " Р".О " « resulti
}

return О;

Вот как Bblrлядят результаты выполнения этой программы.

Введите делимое: 10
Введите делитель: 2
Значение d не равно О, деление осуществимо.
10 / 2 равно 5
В этом случае инструкция i f управляет целым блоком кода, а не просто одной
ИliструкциеЙ. Если управляющее условие инструкции if истинно (как в нашем
примере), будут выполнены все три инструкции, составляющие блок. Поnробуй-
58 rлава 1. Основы С++

те ввести нулевое значение для делителя и узнайте, как выполнится наша про­
грамма в этом случае. Убедитесь,.что IIpИ вводе нуля if-блок будет опущен.
как будет показано ниже, блоки кода имеют дополнительные свойства и спо­
собы IIpименения. Но основная цель их существования - создавать логически
связанные единицы кода.

Спросим у опытного программиста

Вопрос. Не cmраОаem ли эффeIOtШВНоcmь выI'IлнeнIuI пpoгpa;tIМЫ от 1fl1IU'eнeNШI


блоКО8 "oiJa? Дpyzu.мu СЛО8QJff11, не тJJe6уemся ли дonoлнuтeльнoe врUIЯ
КОAmUЛRmору для 06рабoтIOl кода, заКЛНJlleюIOtо 8 фraypныe CfCобки?
Ответ. Нет. Обработка блоков кода не требует дополнительных затрат системных
ресурсов. Более того, использование блоков кода (благодаря возможнОС1"И
улросrnть кодирование некоторых aJlГОРИТМОВ) позволяет увеличить ско­
рость и эффективность выполнения n рограмм.

Точки с запятой и расположение


инструкций
в С++ точка с запятой означает конец инструкции. Другими словами, каж­
дая отдельная инструкция должна завершаться точкой с запятой. Как вы знаете,
блок - это набор логически связанных инструкций, которые заключены между
открывающей и закрывающей фигурными скобками. Бло}( не завершается точ­
кой с запятой. Поскольку блок состоит из инструкций, каждая из которых за­
вершается точкой с запятой, то в дополнителыюй точке с запятой нет никакого
смысла. Признаком же конца блока служит закрывающая фигурная скобка
Язык С++ не воспринимает конец строки в качестве признака конца инструк­
ции. Таким признаком конца служит только точка с запятой. Поэтому ДЛЯ компи­
лятора не имеет значения, в каком месте строки располагается инструкция. На­
IIpимер, с точки зрения С++-компилятора следующий фрагмент кода
• х = у:

у = y+l:
cout « х « " " « у;

аналогичен такой строке:

х = у; у = y+l; cout« х « " " « у;

Более того. отдельные элементы любой инструкции можно располагать на от­


дельных строках. Например, следующий вариант записи инструкции абсолютно
приемлем.
С++: РУКОВОДСТВО ДЛЯ начинающих 59

cout « "Это длинная строка. Сумма равна : "


« а + Ь + с + d + е + f;
+
Подобное разбиение на строки часто используется, чтобы сделать программу +
u
более читабельной. ..,
::о
о
:I:
U
Практика отступов О

Рассматривая предыдущие примеры, вы, вероятно, заметили, что некоторые


инструкции сдвинуты относительно левого края. С++ - язык свободной формы,
т.е. его синтаксис не связан позиционными или форматными ограничениями. Это
означает, что для С++-компилятора не важно, как будут расположены инструк­
ции по отношению друг к другу. Но у программистов с годами выработался стиль
применеНI1Я отступов, который значительно повышает чита6ельность программ.
В этой книге мы придерживаемся этого стиля и вам советуем поступать так же.
Согласно этому стилю после каждой открывающей скобки делается очередной
отступ вправо, а после каждой закрывающей скобки начало отступа возвращает­
ся к прежнему уровню. Существуют также некоторые определенные инструкции,
для которых предусматриваются дополнительные отступы (о них речь впереди).

~просы ДЛЯ текущего l<оНтролЯ ________


1. Как обозначается блок кода?
2. Что является признаком завершения инструкции в С++?

3. Все С++-инструкции должны начинаться и завершаться на одной строке .

Верно ли это? •

Проект 1.2.

' FtoMTable. срр : В этом проекте демонстрируется применение цикла for,


(
! инструкции i f и блоков кода на примере создания про-

1. Блок кода начинается с открывающей фигурной скобки ({), а оканчивается закры­


вающей фигурной скобкой (}).
2. Признаком завершения инструкции в С++ является точка с запятой.
3. Не верно. Отдельные элементы любой инструкции можно располагать на отдельных
строках.
60 Глава 1. Основы С++

граммы вывода таблицы результатов преобраювания футов в метры. Эта табли­


ца начинается с одного фута и заканчивается 100 футами. После каждых 1О фу­
тов выводится пустая строка. Это реализуется с помощью·переменноЙ counter,
в которой хранится количество выведенных с·грок. Обратите особое внимание на
использование этой переменной.

Последовательность действий
1. Создайте новый файл с именем Fto~Table. срр.
2. Введите 8 этот файл CJlед)'ющую программу.

/*
Проект 1.2.

При выполнении этой программы выводится таблица


результатов преобразования футов в метры.

Назовите эту программу FtoMTable.cpp.


*/

iinclude <iostrearn>
using narnespace std;

int rnain () {
double f; // содержит длину, выраженную в футах
double т; // содержит результат преобразования в метры
int counter; // счетчик строк

counter = О; // Вачanък" установка сче~чика C~K.

for(f = 1.0; f <= 100.0; f++) {


т = f / 3.28; // преобразуем в метры
cout « f « " футов равно" « m« " MeTpa.\n";

counter++; // Посае Х&8Дой итерации циxnа


/ / ивкрекев'1'Ир"Уем сче~UDC С'1'рок.

// После каждой 10-й CTPOK~ выводим пустую строку.


if(counter == 10) { // Еcnи сче~чик С'1'рок досчитал
// до 10, 8W80ДИК пус~ С'1'року.
cout « "\n"; // выводим пустую строку
С++: руководство ДЛЯ начинающих 61

counter О; // обнуляем счетчик строк

+
u+
1i
ID
return О; О
1:
U
О
3. Обратите внимание на то, как используется переменная counter для вы­
вода пустой строки после каждых десяти строк. Сначала (до входа в цикл
for) она устанавливается равной нулю. После каждого пре06разования
переменная counter инкРементируется. Когда ее значение становится
равным t О, выводится пустая строка, после чего счетчик ~ТPOK снова обну­
ляется и процесс повторяется.

4. Скомпилируйте и запустите программу. Ниже приведена часть таблицы,


которую вы должны получить при выполнении программы.

1 футов равно 0.304878 метра.


2 футов равно 0.609756 метра.
3 футов равно 0.914634 метра.
4 футов равно 1.21951 метра.
5 футов равно 1.52439 метра.
6 футов равно 1.82927 метра.
7 футов равно 2.13415 метра.
8 футов равно 2.43902 метра.
9 футов равно 2.7439 метра.
10 футов равно 3.04878 метра.

11 футов равно 3.35366 метра.


12 футов равно 3.65854 метра.
13 футов равно 3.96341 метра.
14 футов равно 4.26829 метра.
15 футов равно 4.57317 метра.
16 футов равно 4.87805 метра.
17 футов равно 5.18293 метра.
18 футов равно 5.4878 метра.
19 футов равно 5.79268 метра.
20 футов равно 6.09756 метра.

21 футов равно 6.40244 метра.


22 футов равно 6.70732 метра.
23 футов равно 7.0122 метра.
62 Глава 1. O~HOBЫ С++

24 футов равно 7.31707 метра.

25 футов равно 7.62195 метра.

26 футов равно 7.92683 метра.

27 футов равно 8.23171 метра.

28 футов равно 8.53659 метра.

29 футов равно 8.84146 метра.

30 футов равно 9.14634 метра.

31 футов равно 9.45122 метра.


32 футов равно 9.7561 метра.
33 футов равно 10.061 метра.
34 футов равно 10.3659 метра.
35 футов равно 10.6,707 метра.
36 футов равно 10.9756 метра.
37 футов'равно 11.2805 метра.
38 футов равно 11.5854 метра.
39 футов равно 11.8902 метра.
40 футов равно 12.1951 метра.
5. Самостоятельно измените программу так, чтобы она выводила пустую
строку через каждые 25 строк результатов.

'ШОI
:1111 []ablSlIId" а ф~ЫКI ~ldSl;l
Любая С++-программа составляется из "строительных блоков", именуемых
функциями. И хотя более детально мы будем рассматривать функции в MOДY:le 5,
сделаем здесь краткий обзор понятий и терминов, связанных с этой темой. Функ­
ция - это подпрограмма, которая содержит одну или несколько С++-инструк­
ций и выполняет одну или несколько задач.
Каждая функция имеет имя, которое используется для ее вызова. Чтобы вы­
звать функцию, достаточно в исходном коде l1porpaмMbl указать ее имя с парой
круглых скобок. Своим функциям программист может давать любые имена, за
исключением имени mаiл (), зарезервированного для функции, с которой начи­
нается выполнение программы. Например, мы назвали функцию именем МуРи­
лс. Тогда для вызова функции MyFunc достаточно записать следующее.
МуFuлс();

При вызове функции ей передается управление программой, в результате чего


начинает выполняться код, составляющий тело функции. По завершении функ­
ции управление передается инициатору ее вы:юва.
С++: РУI<ОВОДСТВО ДЛЯ начинающих 63

Функции можно передать одно или несколько значений. Значение, переда­


ваемое функции, называется аргументом. Таким образом, функции в С++ могут
принимать один или несколько аргументов. Аргументы указываются при вызове
функции между открывающей и закрывающей круглыми скобками. Например,
если функция MyFunc () принимает один целочисленный аргумент, то, исполь­
-
:+
:+
:U

CD
о
1:
'J
зуя следующую запись, можно вызвать функцию MyFunc () со значением 2. )
MyFunc(2);
Если функция принимает несколько аргументов, они разделяются запятыми.
В этой книге под термином список аргументов понимаются аргументы, разделен­
ные запятыми. Помните, что не все функции ПРИIIИМают аргументы. Если аргу­
менты не нужны, то круглые скобки после имеии функции остаются пустыми.
Функция может возвращать в вызывающий код значение. HelcoтopbIe фуик­
ции не возвращают никакого значения. Значение, возвращаемое функцией. мож­
но присвоить переменной в вызывающем коде, поместив обращение к функции
с праUОl1 стороны от оператора присваивaJШЯ. Например, если бы функция
MyFunc () возвращала значение, мы могли бы вызвать се таким образом.
х = MyFunc(2);
Эта инструкция работает так. Сначала вызывается ФУIIКЦИЯ MyFunc (). По
ее завершении возвращаемое ею значение ПРИСВa.IfВается персменной х. Вызов
функции можно также использовать в выражении. Рас~мо/'рим пример.
х = MyFunc(2) + 10;
В этом случае значение, возвращаемое функцией, суммируется с числом 1О,
а результат сложения присваивается переменной х. И вообще, если в какой-либо
инструкции встречается имя функции, эта функция автоматически вызывается,
чтобы можно было получить (а затем и использовать) возвращаемое ею значеЮiе.
Итак, вспомним: аргумент - это значение, передаваемое функции. Возвраща­
емое функцией значение - это данные, передаваемые назад в вызывающий код.
Рассмотрим короткую программу, которая демонстрирует использование функ­
ции. Здесь для отображения абсолютного значения числа используется стандарт­
ная библиотечная (т.е. встроенная) функция abs (). Эта функция принимает один
аргумент, преобразует его D абсолютное значение и возвращает результат.
// Использование функции abs().

#include <iostream>
#include <cstdlib>
using namespace std;

int main ()
64 Глава 1. Основы С++

int result;

result = abs(-lO)j // Вызыаае~ск фунхциа аЬа(), а


// воsвращаекое 8JD sначевие
// ПРИС8аивае~ск перемевной result.

cout « result;

return О;

Здесь функции abs () в качестве аргумента передается число -10. Фушщия


abs () , приняв при вызове аргумент, возвращает ero абсолютное значение. По­
лученное значение присваивается переменной resul t. Поэтому на экране ото­
бражается число 10.
Обратите также ВtIИмание на то, что рассматриваемая программа включает за­
ГОЛОВОК <cstdlib>. ЭТОТ заголовок необходим для обеспечения ВОЗМОЖНОСТИ
вызова функции аЬз ( ) . Каждый раз, когда вы используете библиотечную функ­
цию, в проrpамму необходимо включать соответствующий заголовок.
В общем случае в своих программах вы будеl е использовать функции двух ти пов.
К первому типу отнесем фушщии, нarшсанные программистом (т.е. вами), и в каче­
стве примера такой функции можно на.1вать функцию та i n ( ) . как вы узнаете ниже,
реальные С ++-программы содержат множество пользовательских функций.
Функции второго типа предоставляются компилятором. К этой категории Функ­
ций принадлежит функция аЬs ( ) . ОбbIЧНо программы состоят как из функций, на­
писанных программистами, так и из функций, предоставленных компилятором.
При обозначении функций в тексте этоii КНИЛi используется соглашение
(обычно соблюдаемое в литературе, посвященной языку программирования
С++), согласно которому имя функции завершается парой круглых скобок. На­
пример, если функция имеет имя getval, то ее упоминание в тексте обозначит­
ся как getval (). Соблюдение этого соглашения позволит легко отличать имена
переменных от имен функций.

Библиотеки С++
как упоминалось выше, функция аЬs () не является частью языка С++. но ее
"знает" каждый С++-компилятор. Эта функция, как и множестводругих, входит
в состав стандартной 6u6лuотeICU. В примерах этой книги мы подробно рассмо­
трим использование многих библиотечных функций С++.
С++: руководство для начинающих 65

в С++ определен довольно большой набор функций, которые содержатся в


стандартной библиотеке. 3ти функции предназначены для выполнения часто

u+
встречающихся задач, включая операции ввода-вывода, математические вы­

числения и обработку строк. При использовании программистом библиотечной


функции компилятор автоматически связывает объектный код этой функции с ~:J:
U
объектным кодом программы. О
Поскольку стандартная библиотека С++ довольно велика, в ней можно найти
много полезных ФУНКЦIIЙ, которыми действительно часто пользуются програм­
мисты. Библиотечные функции можно при менять подобно строительным бло­
кам, из которых возводится здание. Чтобы не "изобретать велосипед", ознакомь­
тесь с документацией на библиотеку используемого вами компилятора. Если вы
сами напишете функцию, которая будет "переходить" с вами из программы в про­
грамму, ее также можно поместить в библиотеку.
Помимо библиотеки функций, каждый С++-компилятор также содержит би­
блиотеку классов, которая является объеКТllо-ориеt}ТИРОВанной библиотекой.
Но, прежде чем мы сможем использовать библиотеку классов, нам нужно позна­
комиться с классами и объектами.

~просы для теl<ущего I<ОНТрОЛЯ


1. Что такое функция?
--------

2. Функция вызывается с помощью ее имени. Верно ли это?


3. Что понимается под стандартной библиотекой функций С++?·

ВАЖНОI
"'1 КАючевь'е САОва С++
В стандарте С++ определено 63 ключевых слова. Они показаны в табл. 1.1.
Эти ключевые слова (в сочетании с синтаксисом операторов и разделителей)
образуют определение языка С++. В ранних версиях С++ определено ключевое
слово overload, но теперь оно устарело. Следует иметь в виду, что в С++ раз­
личается строчное и прописное написание букв. Ключевые слова не являются ис­
ключением, Т.е. все они должны быть написаны строчными буквами.

1. Функция - это подпрограмма, которая содержит одну или несколько С++­


инcrpукциЙ.
2. Верно. Чтобы вызвать функцию, дocrnточно В исходном коде программы указать ее имя.
З. Стандартная библиотека фyнюntЙ С++ - это коллекция функций, поддерживаемая
всеми С + +-компиляторами.
66 Глава 1. Основы С++

Таблица 1.1. Ключевые слова С++


азm auto Ьооl break
case catch char class
const const class contint:e default
delete do double dinamic cast.
else enum explici t export
extern false float for
friend goto if inline
int long mutable, namespace
new operator private protected
public register reinterpret_cast return
short signed sizeof static
st'atic cast struct switch template
this, throw true try
typedef typeid typenanle union
unsigned using virtuaJ. void
volatile wchar t while

• Идентификаторы
в С++ идентификатор представляет собой имя, которое присваивается функ­
ции, переменной или иному элементу, 'определенному пользователем. 'Иденти­
фикаторы могут состоять из одного или нескольких символов. Имена перемен­
ных должны начинаться с буквы или символа подчеркивания. Последующим
символом может быть буква, цифра и символ подчеркивания. Символ подчер­
кивания можно использовать для улучшения читабельноети имени перемеююй,
IJ;lIlример line_count. В С++ прописные и строчные буквы воспринимаются
t-.:ш, различные символы, Т.е. myvar И MyVar - это разные имена. В С++ нельзя
использовать в качестве идентификаторов ключевые слова, а также имена стан­
дартных функций (например, abs). Запрещено также использовать в качестве
пользовательских имен встроенные идентификаторы (например, cout).
Вот несколько примеров допустимых идентификаторов.

Test х у2 Maxlncr
ир _top my_var simplelnterest23
Помните, что идентификатор не должен начинаться с цифры. Так, 980К­
недопустимый идентификатор. Конечно, вы вольны называть переменные и
другие программные элементы по своему усмотрению, но обычно идентифика­
тор отражает назначение или смысловую характеристику элемента, которому

он принадлежит.
С++: PYI<OBOACTBO ДЛЯ начинающих 67

~ПРОСЫ мя теl<ущего контром --------


+
u+
J!
1. Какой из следующих вариантов представляет собой ключевое слово: f о r, ~
:I:
For или FOR?
8
2. Символы какого типа может содержать С++-идентификатор?

3. Слова
катор?
..
index21 и Index21 представляют собой один и тот же идентифи­

• ТеСТ,ДАЯ СQМОКQНТрООЯ по МОАJlt'Ю 1


{. Выше отмечалось, что С++ занимает центральное место в области совре­
менного программирования. Объясните это утверждение.

2. C++-КОМПИJlЯтор генерирует объектный код, который непосредственно ис­


пользуется компилятором. Верно ли это?

З. Каковы три основных принципа объектно-ориентированного программи-


рования?

4. С чего начинается выполнение С++-программы?

5. Что такое заголовок?

6. Что такое <iostream>? Для чего служит следующий код?


#include <iostream>
7. Что такое пространство имен?

8. Что такое переменная?

9. какое (какие) из следующих имен переменных недопустимо (недопустимы)?

А. count
В. count
С. count27
D_ 67count
Е. if

1. Ключевым словом эдесь является вариант (от. В С++ все ключевые слова ПШlIутся
С ИСПОЛЪЗ0ванием СТРОЧНЫХ букв.
2. С++-идентификатор может содержать буквы, цифры И символ подчеркивания.
З. Нет, в С++ прописные и строчные буквы воспринимаются как раэличные симвоJIы.
68 Глава 1. Основы С++

10. как создать однострочный комментарий? Как создать мноrocтpoчный ком­


ментарий?

11. Представьте общий формат инструкции if. Представьте общий формат


инструкции for.
12. Как создать блок кода?

13. Гравитация Луны составляет около 17% от гравитации Земли. Напишите


программу, которая бы генерировала таблицу земных фунтов и эквива­
лентных ЗI-Iачений, выраженных в лунном весе. Таблица должна содержать
значения от 1 до 100 фунтов и включать пустые строки после каждых 25
строк результатов.

14. Год Юпитера (т.е. время, за которое Юпитер делает один полный оборот
вокруг СОЛf!.ца) составляет приблизительно 12 земных лет. Напишит(' [IPO-
грамму, которая бы выполняла преобразовани.я значений, выраженных в
годах Юпитера, в значения, выраженные в годах Земли. Конечно же, здесь
допустимо использование нецелых ЗliачениЙ.

15. Что происходит с управлением программой при вызове функции?


16. Напишите программу, которая усредняет абсолютные значения пяти значе­
ний, введенных пользователем. Програм\tа должна отображать результат.

~ Ответы на эти вопросы можно найти на Web-странице данной


На заметку " "' книги по адресу: http://www.osborne.com.
Модуль2
Типы данных и операторы

2.1. Типы данных С++


2.2. Литермы
2.3. Создание инициализированных переменных
2.4. Арифметические операторы
2.5. Операторы отношений и логические операторы
2.6. Оператор присваивания
2.7. Составные операТОрЫ присваивания
2.8. ПреобразОБание типов в операторах присваивания
2.9. Преобразование типов в выражениях
2.10. Приведеllие ТИПОlJ
2.11. Использование пробелов и круглых скобок
70 Модуль 2. Типы данных и операторы

Центральное место в описании языка ПРОГРJ.ммирования занимают типы дан­


ных и операторы. Эти элементы определяют ограничсния языка и виды задач, к
которым его можно примснить. Нетрудно предположить, что язык С++ поддер­
живает богатый ассортимент как типов данных, так и опсраторов, что позволяет
его использовать ДЛЯ решения широкого круга задач программирования.

Типы данных и операторы - это большая тема, которую мы начнем pacc:vla-


тривать с основных типов данных и наиболее часто используемых операторов. В
этом модуле мы также обсудим подробнее такие элементы языка, как перемен­
ные и выражения.

Почему ТИПbl данных столь ваЖНbI


Тип переменных определяет операции, которые разрешены для выполнения
над ними, и диапазон значений, которые могут быть сохранены с их помощью.
В С++ определеио несколько типов данных, 11 осе они обладают уникальными
характеристиками. Поэтому все переменные ДОЛЖНЫ быть определены до их ис­
пользования, а объявление переменной должно включать спецификатор типа.
Без этой информации компилятор не сможет сгеuерировать корректный код.
В С++ не существует понятия "переменной ОС-\ типа".
Типы данных важНЫ для С++-программирования еще и потому, что несколько
базовых типов тесно связанЫ со "строительными блоками", которыми оперирует
компьютер: байтами и словами. Другими словами, С++ позволяет программисту
задействовать те же самые ТИПЫ данных, которые использует сам централl>НЫЙ
процессор. Именно поэтому с помощью С++ можно писать очень эффективные
\
программы системного уровня.

Язык С++ поддерживает встроенные типы данных, которые позволяют ис­


пользовать в программах целые числа, СИМВОJlЫ, значения с плавающей точкой
и булевы (логические) значения. Именно использование КОНКРетных типов дан­
ных позволяет сохранять и обрабатывать в программах различные виды инфор­
мации. как будет показано ниже D этой книге, С++ предоставляет программисту
возможность самому создавать типы данных, а не только использовать встроен­

ные. Вы научитесь создавать такие типы данных, как классы, структуры и перс­
числения, 110 при этом помните, что все (даже очень сложные) новые типы дан­
ных состоят из встроенных.
С++: РУI<ОВОДСТВО ДNI начинающих 71

В С++ определено семь основных типов данных. Их названия и ключевые


слова, которые используются для объявления переменных этих типов, приведе­
ны в следующей таблице.

Тип Название
char Символьный
wchar t Символьный двубайтовый
int целочисленный
float С плавающей ТОЧКОЙ
double С плавающей точкой двойной точности
bool Лоrnческий (или булев)
void Без значения

В С++ перед такими типами данных, как char, int и double, разрешается
использовать .модифU1Шmоры. Модификатор служит для изменения значения ба­
зовоro типа, чтобы он более точно соответствовал конкретной ситуации. Пере­
чиелим возможные модификаторы типов.

signed
unsigned
long
short
Модификаторы signed, unsigned, long и short можно примеitять к це­
лочисленным базовым типам. Кроме того, модификаторы signed и unsigned
можно использовать с типом
char, а модификатор long - с типом double. Все
допустимые комбинации базовых типов и модификаторов приведены в табл. 2.1.
В этой таблице также указаны гарантированные минимальные диапазоны пред­
ставления для каждоro типа, соответствующие С++-стандарту ANSI/ISO.
Минимальные диапазоны, представленные в табл. 2.1, важно понимать именно
как .мUНUМШlЫtыe дuanаЭ()7fЫ и никак иначе. Дело в том, что С++-компилятор может
расширить один или несколько из этих минимумов (что и делается в большинстве
случаев). Это означает, что диапазоны представления С++-типов данных зависят от
конкретной реализации. Например, ДЛЯ компьютеров, которые используют арифме­
тику дополнительных кодов (т.е. почти все COBpeMeННhle компьютеры), целочислен­
НЫЙ тип будет иметь диапазоli представлеlШЯ чисел от -32 768 до 32 767. Однако во
всех случаях диапазон представления типа short int является подмножеством
диапазона типа in t, диапазон представления KOТOPOro в свою очередь является под­
множеством диапазона типа long int. Аналогичными отношениями связаны и
типы float, double и long double. В этом контексте термин noдмножеC11l8O озна­
чает более УЗЮiЙ или такой же диапазон. Таким образом, типы int и long int
MOryт иметь одинаковые диапазоны, но диапазон типа int не может быть шире диа­
пазона типа long int.
72 Модуль 2. Типы данных и операторы

Таблица 2.1. Все допустимые комбинации числовых типов и их


гарантированные минимальные диапазоны представления.

соответствующие С++-стандарту ANSI/ISO

~Ти~п~____________________~~~и~н~и~м~ал~ЬН~Ыf1~АИ~а_п
__о_эо_н
________________
char -128-127
unsigned char 0-255
signed char -128-127
int -32768-32767
unsigned int 0-65 535
signed int АналоrиЧентипу int
short int -32768-32767
unsigned short int 0-65 535
signed short int Аналоrnчентилу short int
10ng int -2147483648-2147483647
·signed 10ng int Аналоrnчен типу 10ng int
unsigned 10ng int 0-4294967295
floa t 1Е-37 -1 Е +37. с шестью значащими цифрами
double 1Е-37-1Е+З7. (" дссятьюзначащими цифрами
_1_0_п-=g__d_о_u_Ь_1_е______________1_Е_-_3_7_-_1_Е_+_37--'-,с десятью значащими циФрами

Поскольку стандарт С++ указывает только минимальный диапазон, который


обязан соответствовать тому или иному типу данных, реальные диапазоны, под­
держиваемые вашим компилятором, следует уroчнить в соответствующей доку­
ментации. Например, в табл. 2.2 указаны типи чные размеры значений в битах и
диапазоны представления для каждого С++-типа данных в 32-разрядной среде
(например, в Windows ХР).

Целочисленный тип
как вы узнали в модуле 1, переменные типа iI\ t предназначены для хранения lJ,e-
лочисленных значений, которые не содержат др06ной части. Переменные этого nma
часто используются для управления циклами и условными инструкциями. Опера­
ЦИИ с iпt-значениями (поскольку они не имеют дробной части) выполняются на­
много быстрее, чем со значениями с плавающей точкой (вещественного типа).
А теперь подробно рассмотрим каждый тип в отдельности.
Поскольку целочисленный тип столь важен для программирования, в С++
определено несколько его разJfовидностеЙ. Как показано в табл. 2.1, существуют
короткие (short int), обычные (int) и длинные (long int) целочисленные
значения. Кроме того, существуют их версии со знаком и без. Переменные uело­
численного типа со знаком MOryт содержать как положительные, так и отрица-
С++: PYI(OBOACTBO для начинающих 73

тельные значения. По умолчанию предполагается использование целочисленно­


го типа со знаком. Таким образом, указание модификатора s i gned избыточно (но
допустимо), поскольку объявление по умолчанию и так предполагает значение
со знаком. Переменные целочисленного типа без знака могут содержать только
положительные значения. Для объявления целочислеНIiОЙ переменной без знака
достаточно использовать модификатор unsigned.

Таблица 2.2. Типичные размеры значений в битах и диапазоны


представлениS1 С++-типов данных в 32-разрS1ДНОЙ среде

Тип Размер в битах Диапазон


char 8 -128-127
unsigned char 8 0-255
signed char 8 -128-127
int 32 -2 147483648-2 147483647
unsigned int 32 0-4 294 967 295
signed int 32 Аналогичен типу int
short int 16 -32 768-32 767
unsigned short int 16 0-65535
signed short int 16 -32 768-32 767
long int 32 Аналогичен типу int
signed long int 32 Аналогичен типу signed int
unsigned long int 32 АналОПfчен типу unsigned int
float З2 1,8Е-З8-ЗАЕ +З8
double 64 2,2Е-308-1,8Е+308
long double 64 2,2Е-308-1,8Е+308
Ьооl ИСТИНА или ЛОЖЬ
w char t 16 0-65535

Разли~ие между целочисленными значениями со знаком и без него заключа­


ется в иЙтерпретации старшего разряда. Если задано целочисленное значение
со знаком, С++-компилятор сгенерирует КОД с учетом того, что старший разряд
значения используется в качестве флazа знака. Если флаг знака равен О, число
считается положительным, а если он равен 1, - отрицательным. Отрицатель­
ные числа почти всегда представляются в дополнительном коде. Для получения
дополнительного кода все разряды числа берутся 8 обратном коде, а затем по­
лученный результат увеличивается на единицу. Наконец, флаг знака устанав­
ливается равным 1.
Целочисленные значения со знаком используются во многих алгоритмах, но
максимальное число, которое можно представить со знаком, составляет только
74 Модуль 2. Типы данных и операторы
................................................................................................................................

половину от максимального числа, которое можно представить без знака. Рас­


смотрим, например, максимально возможное 16-разрядное целое число (32 767):
0111111111111111
Если бы старший разряд этого значения со знаком был установлен равным 1. то
оно бы интерпретировалось как -1 (в дополнительном коде). Но если объявить
его как unsigned iпt-значение, то после установки его старшего разряда в 1 мы
получили бы число 65 535.
Чтобы понять различие в С++-интерпрет.щии целочисленныx значений со
знаком и без него, выполним следующую короткую программу.
#include <iostream>

/* Эта про грамма демонстрирует различие между


signed- и uпsigпеd-значениями целочисленного типа.

*/

using namespace std;

int main ()
{
short int i; // короткое iпt-значение со знаком
short unsigned int j; // короткое iпt-значение без знака

j = 60000; // Число 60000 попадает в диапазон


// представления типа short unsigned int, но
// не попадает в диапазон представления типа
// short signed int.
i j; // Поэтому после присваивания числа 60000
// переменной i оно будет интерпретироваться
// как отрицательное.
cout « i « " " « j;

return О;

При выполнении программа выведет два числа:

-5536 60000
Дело в том, что битовая комбинация, которая представляет число 60000 как короткое
(short) целочисленное значение без знака, интерпретируется в качестве короткого
iпt-значения со знаком как число -5536 (при 16-разрядном представлении).
С++: РУКОВОДСТВО ДЛЯ начинающих 75

в С++ предусмотрен сокращенный способ объявления unsigned-, short- и


lопg-значений целочисленноro типа. Это значит, что при объявлении iпt-зна­
чений достаточно использовать слова unsigned, short и long, не указывая ~ип
int, Т.е. тип int подразумевается. Например, следующие две инструкции объ­
являют целочисленные переменные без знака.
unsigned Х;
unsigned int У:

Символы
Переменные типа char предназначены для хранения ASCIl-СИМDОЛОВ (напри­
мер А, z или G) либо иных В-разрядных величин. Чтобы задать символ, необхо­
димо заключить ero в одинарные кавычки. Например, после выполнения следу-
I

ющих двух инструкций

char ch;
ch = 'х' i

переменной ch будет присвоена буква Х.


Содержимое сhаr-значения можно вывести на экран с помощью соut-ин­
струкции. Вот пример.

cout « "Это содержится в переменной ch: " « Chi


При выполнении этой инструкции на экран будет выведено следующее.
Это содержится в переменной ch: Х

Тип char может быть модифIщирован с помощью модификаторов signed и ип­


signed. Строго говоря, только конкретная реализация определяет по умолчанию,
каким будет сhаr-06ъявление: со знаком или без него., Но для большинства компи­
ляторов объявление типа char подразумевает значение со знаком. Следовательно,
в таких средах использование модификатора signed для char-обьяWlения также
избыточно. В этой книге предполагается, что char-значенИя имеют знак
Переменные типа char можно использовать не TOJIЫ(O для хранения ASсп­
символов, но и для хранения числовых значений. Переменные типа char могут со­
держать "небольшие" целые числа в диапазоне -128-127 и поэтому их можно ис­
пользовать вместо i nt -переменtlых, если вас устраивает такой диапазон представ­
ления чисел. Например, в следующей программе сhаr-переменная используется
для управления циклом, который выводит на экран алфавит английского языка.

,// Эта про грамма выводит алфавит.

tinclude <iostream>
76 МОДУЛЬ 2. Типы данных и операторы

using паmезрасе std;

int main ()
{
char letter; // Перекеква_ letter ~a char
// иcnоnьзуетса дn_ упрaanекия цихпок for.
J.
for(letter = 'А'; letter <= 'Z'; letter++)
cout « letter;

return О;

Если ЦИКЛ for вам покажется несколько cTpaнным. то учтите. что символ' А'
представляется в компьютере как число 65. а значения от 'А' до 'Z' являются
последовательными и расположены в возрастающем порядке. При каждом про­
ходе через ЦИКЛ значение переменной let ter инкрементируется. Таким обра­
зом. после первой итерации переменная lette:r будет содержать значение I Е'.
ТИП wchar_ t предназначен для хранения символов. входящих в состав t:юль­
ших символьных наборов. Вероятно. вам известно, что в некоторых естественных
языках (например китайском) определено очень большое количество символов,
для которых В-разрядное представление (обеспечиваемое типом char) вес[.ма
недостаточно. Для решения проблем такого рода в язык С++ и был добавлен тип
wchar _ t. который вам пригодится. если вы планируете выходить со своими про­
граммами на международный рынок.

~npocы дIIя текущего контроля - - -_____


1. Назовите семь основных типов данных в С++.

2. Чем различаются целочисленные значения со знаком и без?


З. Можно ли использовать переменные типа char для представления не­
больших целых чисел?·

1. Семьосновиыхтипов: char.wchar_t. in1:. float, double.bool иvоid.

2. Целочисленный тип со знаком позволяет хр;uпггь как положительные, так и отри­


цательные значения, а с помощью целочислеlПfОro типа без знака можно хранить
только положительные значения.

3. Да, переменные типа char можно ИСПОЛЬЗОЕ·атъ для представления небольmиx це­
лыхчисел.
С++: РУКОВОДСТВО ДЛЯ начинающих 77
..................................................................................................................................

Спросим у опытного программиста

Вопрос. Почему сltUlндарт С++ определяет только .минuмальн.,е диапазоны


дм tlcmpoeHIIых типов, не ycmaHa&llutllVl их более 1IUJIIнo?

Ответ. Не задавая точных размеров, язык С++ позволяет каждому компилятору


оптимизировать типы данных для конкретной среды выполнения. В этом
частично и состоит причина того, что С ++ предоставляет возможности для
создания высокопроизводительных I1рограмм. Стандарт ANSIIISO про­
сто заявляет, что встроенные тип bJ должны отвечать определенным требо­
ваниям. Например, в нем сказано, что тип in t "должен иметь естествен­
ный размер, предлагаемый архитектурой среды выполнения". это значит,
что R 16-раэрядных средах ДЛЯ хранения значений типа i nt должно выде­
ляться 16 бит, а в 32-разрядиых - 32. При этом наименьший допустимый
размер для целочисленных значений в любой среде должен составлять 16
бит. Позтому, есЛи вы будете Ш1Сать программы, не "заступая" за пределы
минимальных диапазонов, то они (программы) будут переносимы в дру­
гие среды. Одно замечание: каждый С++-компнлятор указывает диапазон
базовых типов в заголовке <cl imi t S>.

Типы данных с плавающей точкой


к переменным типа flоа t JI double обращаются либо для обработки чисел с
дробной частью, либо при необходимости выполнения операций над очень боль­
шими или очень малыми числами. ТИIIЫ float и double различаются значением
наибольшего ( и наименьшего) числа, которые можно хранить с помощью пере­
менных этих типов. Обычно тип double в С++ позволяет хранить число, при­
близительно в десять раз превышающее значение типа float.
Чаще всего в профессиона.льных программах используется тип double. Дело
IJ том, что большинство математических функций из С++-библиотеки исполь­
зуют dоublе-значения. Например, функция sqrt () возвращает dоublе-зна­
чение, которое равно квадратному корню из ее double-аргумента. Для примера
рассмотрим программу, в которой функция sqrt () используется для вычисле­
ния длины гипотенузы по заданным длинам двух других сторон треугольника.

/*
Здесь используется теорема Пифагора для вычисления
длины гипотенузы по заданным длинам двух других

сторон треугольника.

*/
78 МОДУЛЬ 2. Типы данных и операторы
.................................................................................................................................

finclude <iostream>
#include <cmath> // Это~ saroловох аеобходим дn_
/ / 8101S08. ФУRJC.ЦИИ 8qrt () .
using namespace std;

int main () (
double х, у, z;

х = 5;
У 4;

z = sqrt(x*x + у*у); // ФУВXЦИR 8qrt() RВnRe~c_ час~


// ма~ека~есхой С++-бибnио~ехи.

cout « "Гипотенуза