- •Р. Лафоре
- •Глава 1. Общие сведения 32
- •Глава 3. Циклы и ветвления 92
- •Глава 4. Структуры 142
- •Глава 5. Функции 168
- •Глава 6. Объекты и классы 217
- •Глава 7. Массивы и строки 261
- •Глава 8. Перегрузка операций 312
- •Глава 9. Наследование 361
- •Глава 10. Указатели 411
- •Глава 11. Виртуальные функции 476
- •Глава 12. Потоки и файлы 536
- •Глава 13. Многофайловые программы 596
- •Глава 14. Шаблоны и исключения 640
- •Глава 15. Стандартная библиотека шаблонов (stl) 681
- •Глава 16. Разработка объектно-ориентированного по 752
- •Глава 1 «Общие сведения» включает список тем, касающихся uml, с указа- нием их расположения в книге.
- •Глава 1
- •Глава 2
- •Глава 3
- •If внутри циклов
- •If и else во вложенных ветвлениях
- •Глава 4
- •Глава 5 Функции
- •Глава 6
- •Глава 7
- •123456. Россия
- •123456. Россия
- •Глава 8
- •Глава 9
- •Глава 10 Указатели
- •Main() передает адрес переменной var в ptrd в centimize()
- •Centimize() использует этот адрес для доступа к var
- •Глава 11
- •Глава 12
- •Тип:менеджер Фамилия: Александров Номер:1111
- •Тип:Ученый Фамилия: Лебедев Номер:2222
- •Тип:рабочий Фамилия:Шевелев Номер:3333
- •Глава 13
- •Глава 14
- •Много объектов разных классов в памяти Рис. 14.2. Шаблон класса
- •Алгоритмы используют итераторы для работы с объектами контейнеров. Рис. 15.1. Контейнеры, алгоритмы и итераторы
- •Глава 16
- •Глава 1
- •Глава 2
- •Глава 3
- •Глава 4
- •Глава 5
- •Глава 6
- •Глава 7
- •Глава 8
- •Глава 9
- •Глава 10 Ответы на вопросы
- •Глава 11
- •Глава 12 Ответы на вопросы
- •Глава 13 Ответы на вопросы
- •Глава 14 Ответы на вопросы
- •Глава 15 Ответы на вопросы
- •Глава 16
Рис.
3.8. Исполнение оператора if
Несколько
операторов в теле if
Как и для циклов,
тело ветвления if
может состоять
как из одного оператора, что
было
продемонстрировано в программе IFDEMO,
так и из
нескольких операторов,
заключенных
в фигурные скобки. Пример, иллюстрирующий
использование
блока операторов в
теле if,
называется IF2
и приводится
ниже.
//
if2.cpp
//
использование нескольких операторов
в теле цикла if
#include
<iostream>
using
namespace
std;
int
main()
{
int
x;
cout
<<
"Введите
число:
";
cin
>>
x;
if(x
>
100)
{
cout
<<
"Число
"
<< x;
cout
<<
"
больше, чем 100\n";
}
return
0;
}
Вот возможный
результат работы программы IF2:
Введите
число: 12345
Число 12345 больше, чем 100
Циклы и ветвления
можно использовать совместно. Вы можете
помещать ветв-
ления внутрь цикла и
наоборот, использовать вложенные
ветвления и вложен-
ные циклы. В
следующем примере под названием PRIME
ветвление if
находится
внутри
цикла for.
Программа
определяет, является ли вводимое число
простым
If внутри циклов
или нет (простым
называется число, которое делится
только на единицу и на само
себя.
Примерами простых чисел являются 2, 3,
5, 7, 11, 13 и 17).
//
prime.cpp
//
применение цикла if
для
определения простых чисел
#include
<iostream>
using
namespace
std;
#include
<process.h>
//
для
exit()
int
main()
{
unsigned
long
n, j;
cout
<< "Введите
число: ";
cin
>>
n;
//
ввод проверяемого числа
for(j
=
2; j
<= n
/
2;
j++)
//
деление на целые числа,
if(n
%
j
==
0)
//
начиная с 2; если остаток
{
//
нулевой, то число не простое
cout
<<
"Число
не простое:
делится на "
<< j
<<
endl;
exit(0);
//
выход из программы
}
cout
<<
"Число
является простым\n";
return
0;
}
В этом примере
пользователь вводит значение, которое
присваивается пере-
менной n. Затем
программа при помощи цикла for
делит число n
на все числа от 2
до n/2.
Делителем является переменная j,
служащая
счетчиком цикла. Если чис-
ло n
разделится без остатка на какое-либо
из значений j,
то оно не будет
прос-
тым. Условием того, что одно
число делится на другое без остатка,
является
равенство остатка от деления
нулю. Поэтому в условии для if
участвует
опера-
ция остатка от деления %. Если
число оказывается не простым, то мы
выводим
соответствующее сообщение
и выходим из программы.
Ниже приведен результат работы программы
для трех последовательно вве-
денных
чисел:
Введите
число: 13
Число
является простым
Введите
число: 22229
Число
является простым
Введите
число: 22231
Число
не простое: делится на 11
Обратите внимание
— тело цикла не заключено в фигурные
скобки. Это объ-
ясняется тем, что
оператор if
и операторы
тела ветвления на самом деле явля-
ются
одним оператором. Для того чтобы улучшить
читаемость кода, вы можете
добавить
фигурные скобки, но это не является
обязательным для правильной
работы
компилятора.
Функция
exit()
Когда программа
PRIME
получает число,
не являющееся простым, она завершает-
ся,
поскольку нет необходимости несколько
раз проверять, является число прос-
тым
или нет. Библиотечная функция exit()
производит
немедленный выход из
программы независимо
от того, в каком месте она находится.
Эта функция не
возвращает значения.
Ее единственный аргумент (в
нашем случае 0)
возвращается
вызывающему окружению
после того, как программа завершается
(эта
величина
часто используется в
пакетных
файлах, которые запрашивают значение,
возвра-
щаемое функцией exit().
Как правило,
возвращаемое значение 0 говорит об
успеш-
ном завершении программы;
ненулевые значения сигнализируют об
ошибках).
Оператор
if...else
Оператор if
позволяет
совершать действие в том случае, если
выполняется неко-
торое условие.
Если же условие не выполняется, никакого
действия не выполня-
ется. Однако
можно представить такую ситуацию, когда
нам необходимо совер-
шить одно
действие в случае выполнения условия
и другое действие в случае
невыполнения
этого условия. Здесь оказывается
полезным ветвление if...else.
Оно
состоит из оператора if,
за которым
следует блок операторов, и ключевого
слова
else,
за которым
следует еще один блок операторов.
Синтаксис ветвления
показан на рис.
3.9.
Рис.
3.9.
Синтаксис if...else
Изменим программу
if,
добавив к
ветвлению else-часть:
//
ifelse.cpp
//
применение
конструкции
if...else
#include
<iostream>
using
namespace std;
int
main()
{
int
x;
cout
<<
"\nВведите
число:
";
cin
>>
x;
if(x
>
100)
Рис.
3.10. Исполнение оператора if...else
Функция
getche()
Следующий наш
пример CHCOUNT
демонстрирует
использование ветвления if...else
внутри
цикла while.
Кроме того, в
нем используется библиотечная
функция
getche().
Программа
подсчитывает количество слов и символов
в строке, вводи-
мой пользователем
с клавиатуры.
//
chcount.cpp
//
подсчет числа слов и символов в
строке
#include
<iostream>
using
namespace
std;
#include
<conio.h> //
для
getche()
int
main()
{
int
chcount
=
0; //
число непробельных символов
int
wdcount
=
1; //
число пробелов
char
ch
=
'a'; //
ch
должна
иметь определенное значение
cout
<<
"Введите
строку: ";
while(ch
!= '\r') //
цикл, пока не будет нажата клавиша Enter
{
cout
<< "Это
число больше, чем 100\n";
else
cout
<< "Это
число не больше, чем 100\n";
return
0;
}
В зависимости от
истинности или ложности условия
ветвления, программа
выводит на
экран соответствующее сообщение. Вот
результаты двух вызовов
программы:
Введите
число; 300
Это
число больше, чем 100
Введите
число: 3
Это
число не больше, чем 100
Функционирование
ветвления if...else
показано на
рис. 3.10.
ch
= getche();
//
считывание символа
if(ch
== '
')
//
если символ является пробелом,
wdcount++;
//
то инкрементируем число слов
else
//
в противном случае
chcount++;
//
инкрементируем число символов
}
//
вывод результатов на экран
cout
<< "\nCлов:
"
<< wdcount << endl;
cout
<< "Букв:
"
<< (chcount - 1) << endl;
return
0;
}
До
сих пор мы использовали для ввода только
объект cin
и
операцию >>.
Такой способ вводить значения
предполагает, что после ввода значения
пользователь нажмет клавишу Enter.
Это
верно и в отношении отдельных символов:
пользователь вводит символ, а затем
нажимает Enter.
В
данном случае программе необходимо
обрабатывать каждый введенный символ
сразу после его появления, не дожидаясь
нажатия клавиши Enter.
Такую
возможность обеспечивает библиотечная
функция getche().
Эта
функция не имеет аргументов, а ее
описание содержится в заголовочном
файле CONIO.H.
Значение,
возвращаемое функцией getche(),
присваивается
переменной ch
(функция
getche(),
кроме
возвращения значения, печатает это
значение на экране; такой ввод называется
ввод с эхом (echo),
что
отражено в названии функции буквой е
на конце. Другая функция под названием
getch()
похожа
на функцию getche(),
но,
в отличие от нее, не отображает
вводимый символ на экране.
Ветвление
if...else
увеличивает на единицу значение
переменной wdcount
в
том случае, если с клавиатуры вводится
пробел, и значение переменной chcount,
если
введен не пробел. Таким образом, программа
считает за букву любой символ, не
являющийся пробелом. Разумеется, этот
алгоритм примитивен и дает ошибочный
результат уже при введении нескольких
пробелов между словами. Взаимодействие
с программой может осуществляться
следующим образом:
Введите
строку: For
while
and
do
Слов:
4
Букв:
13
Условие цикла while
проверяет, не
является ли нажатая клавиша клавишей
Enter,
что соответствует
выдаче функцией getche()
символа,
соответствующего
управляющей
последовательности '\r'.
При нажатии клавиши Enter
цикл и про-
грамма
завершаются.
Условия с
присваиванием
Можно переписать
программу CHCOUNT,
сократив ее на
одну строку и продемон-
стрировав
важные аспекты, касающиеся присваивания
и старшинства операций.
Получившаяся
в результате конструкция может показаться
необычной, однако
на самом деле она
часто употребляется не только в C++,
но даже в С.
Приведем измененную
версию предыдущей программы, названную
CHCNT2:
//
chcnt2.cpp
//
подсчет числа слов и символов в строке
#include
<iostream>
using
namespace std;
#include
<conio.h>
//
для
getche()
int
main()
{
int
chcount = 0;
int
wdcount = 1; //
пробел
между
двумя
словами
char
ch;
while((ch
= getche())
!= '\r')
//
цикл, пока не нажата клавиша Enter
{
if(ch
== '
')
//
если введен пробел,
wdcount++;
//
инкрементировать счетчик слов
else
//
иначе
chcount++;
//
инкрементировать число символов
}
//
вывод результатов
cout
<< "\nСлов:
"
<< wdcount << endl;
cout
<< "Букв:
"
<< chcount << endl;
return
0;
}
Значение, возвращаемое
функцией getche(),
присваивается
переменной ch,
как
и раньше,
но сама операция присваивания находится
прямо внутри условия
цикла while.
Присвоенное
значение сравнивается с '\r'
для того, чтобы выяснить,
продолжать
выполнение цикла или нет. Эта конструкция
работает правильно,
потому что
операция присваивания значения сама
получает это значение. Если,
к примеру,
функция getche()
возвращает
символ 'a',
то при этом не только про-
исходит
присваивание значения 'a'
переменной ch,
но само выражение
(ch
=
getche())
получает значение,
равное 'a',
которое участвует в проверке.
Тот факт, что операции присваивания
имеют собственное значение, приме-
няется
при множественном присваивании, таком,
как
int
x,
y,
z; x
= у = z
=
0;
Подобные конструкции
являются абсолютно корректными в C++.
Сначала
переменной z
присваивается
значение 0, которое затем присваивается
перемен-
ной у. После этого выражение
y
=
z
=
0 получает
значение 0, которое присваивается
переменной
x.
Внешние круглые скобки в выражении
(ch
=
getche())
необходимы, поскольку
операция присваивания =
имеет более низкий приори-
тет, чем
операция отношения !=.
Если бы скобки отсутствовали, то
выражение
while((ch
=
getche())
!= '\r')
присваивало бы
истинное или ложное значение переменной
ch,
что было бы
не-
правильно для нашего алгоритма.
Таким образом,
оператор while
в программе
CHCNT2
выполняет много
полез-
ных действий. Он не только
проверяет, является ли значение
переменной ch
символом
'\r',
но еще получает символ с клавиатуры и
присваивает его перемен-
ной ch.
Непросто с
одного взгляда понять все действия
этого оператора.
Вложенные
ветвления if...else
Возможно, вам
приходилось видеть приключенческие
игры, предназначенные
для ранних
версий MS
DOS.
Их суть
заключалась в следующем: играющий
дви-
гал своего «героя» по воображаемому
ландшафту и замкам среди волшебников,
сокровищ
и т. д., нарисованных с помощью текстовых
символов. Следующая
программа,
ADIFELSE,
напоминает
небольшую часть такой приключенческой
игры.
//
adifelse.cpp
//
приключенческая игра с применением
ветвления if...else
#include
<iostream>
using
namespace std;
#include
<conio.h> //
для
getche()
int
main()
{
char
dir = 'a';
int
x
= 10, y
= 10;
cout
<< "Нажмите
Enter
для выхода...\n";
while(dir
!= '\r')
//
пока не будет нажата клавиша Enter
{
cout
<< "\nВаши
координаты: "
<< x
<< ",
"
<< y;
cout
<< "\nВыберите
направление (n,
s,
e,
w):
";
dir
= getche();
//
ввод символа
if(dir
== 'n')
//
движение на север
y--;
else
if(dir
== 's')
//
движение
на
юг
y++;
else
if(dir
== 'e')
//
движение на восток
x++;
else
if(dir
== 'w')
//
движение на запад
x--;
}
//
конец цикла while
return
0;
}
//
конец функции main()
Когда
игра начинается, вы оказываетесь на
бесплодном участке земли. Вы можете
передвигаться на север, юг, запад и
восток, а программа будет следить за
вашими передвижениями и сообщать ваши
текущие координаты. Начало движения
находится в точке с координатами (10,
10).
С вашим героем не будет происходить
ничего интересного, куда бы он ни пошел;
пустая земля простирается во всех
направлениях, как видно на рис. 3.11. Позже
мы внесем в эту игру немного разнообразия.
Вот
пример взаимодействия с нашей игрой:
Ваши
координаты: 10, 10
Выберите
направление (n,s,e,w):
n
Ваши
координаты: 10, 9
Выберите
направление (n,s,e,w):
e
Ваши
координаты: 11, 9
Выберите
направление (n,s,e,w):
