Глава 11
Если вы читаете книгу по порядку, вы уже получили представление об основных аспектах написания программ. Но до сих пор все рассматриваемые программы выполнялись только последовательно. Другими словами, выполнение программы всегда начиналось с первой строки функции main, а затем последовательно осуществлялся переход от одного выражения к другому, и порядок этот никогда не нарушался.
Однако, как вы уже могли убедиться на собственном опыте, течение жизни не всегда прямолинейно и порой случаются отклонения от общего курса. Хорошие программы обладают подобной гибкостью. Существуют, конечно, задачи, которые могут быть решены с помощью последовательно выполняющихся программ. Но в большинстве случаев программы должны уметь реагировать на некие внешние воздействия или команды и, в зависимости от этого, както изменять свое поведение. Для моделирования таких ситуаций C++ предлагает целый набор операторов, позволяющих управлять последовательностью выполняемых действий. Эти операторы разрешают выполнение определенной операции только в случае выполнения указанного условия. Кроме того, они способны выполнять один и тот же набор инструкций до тех
пор, пока заданное условие не перестанет выполняться.
Существует множество ситуаций, которые невозможно смоделировать без использования таких операторов. Ниже приведено несколько примеров типичных задач, требующих для своего решения многократного повторения одних и тех же действий.
В других ситуациях вам необходима возможность выбора. Обычно эта возможность фор мулируется так: если условие выполняется, сделайте это. Приведем примеры нескольких подобных ситуаций.
Как видите, существует очень широкий спектр самых типичных задач, требующих для своего выполнения либо многократного повторения одних и тех же действий, либо осуществления выбора. Справиться с такими задачами призваны операторы, управляющие последовательностью выполняемых инструкций. И эта глава посвящена именно им.
Вверх
Три оператора управления используются почти во всех программах: if, for и while.
Вверх
Синтаксис условного оператора if очень прост:
(Обратите внимание, что здесь и далее в книге словом ехрг будет обозначаться любое выражение,
Вместо expr1 можно подставить любое выражение, которому может быть сопоставлено
А этот код моделирует ситуацию, в которой покупателю предоставляется скидка, если он сделал покупки на сумму, превышающую $3 000:
Можно придать оператору if большую гибкость, если использовать вместе с ним ключевое слово else :
В этом случае, если проверяемое выражение (expr1) ложно, выполняется инструкция stmt 2.
Приведенный ниже код моделирует эпизод карточной игры, когда проверяются набранные игроком очки, и, если их сумма превышает число 21, фиксируется перебор (fBusted), в противном случае предлагается взять еше одну карту:
//Игроку предлагается взять еще одну карту
Введение в форматирование кодов программ
А вот тот же код, набранный без отступов:
if (nHandValue > 21)(
Первый код проще, поскольку из него ясно видно, какие инструкции будут выполнены в случае выполнения условия, а какие в случае невыполнения.
При использовании вложенных операторов выделяйте коды каждого из них дополнительными отступами.
Например:
Другим приемом, облегчающим чтение кодов программы (который также использовался во всех приведенных выше примерах), является размещение закрывающей фигурной скобки } на одном уровне с соответствующей ей открывающей { скобкой:
Благодаря этому легко увидеть, где начатый блок кодов заканчивается. Кроме того, хотя для оператора if использовать фигурные скобки обязательно только в том случае, если он содержит более одной инструкции для выполнения, постоянное их применение может предотвратить возникновение некоторых тривиальных ошибок. Например, в следующем коде фигурные скобки не используются:
Приведенный ниже код выполняет точно те же действия, но читается намного проще и позволяет в случае необходимости без особых усилий добавить к оператору i f дополнительные инструкции для выполнения:
Visuaf C++ .NET форматирует коды вашей программы автоматически. Например, если вы выделите с помощью отступа какую-то строку, набираемые после нее строки будут автоматически выравниваться по : ней. Если вы наберете скобку }, она автоматически будет выровнена по соответствующей ей скобке
{
.
Следующий код определяет размер предоставляемой скидки в зависимости от суммы со
вершенных покупок:
В некоторых случаях, как в приведенном выше примере, один оператор if используется внутри другого оператора if. Это называется вложением операторов. Чтобы коды вложенных операторов были проще для чтения и понимания, добавляйте отступы, выделяющие границы каждого из них.
Вверх
Ключевое слово for используется в тех случаях, когда какие-то инструкции должны выполняться подряд определенное количество раз. Синтаксис оператора for выглядит следующим образом:
Такой код еше называют циклом for.
При выполнении цикла for в первую очередь обрабатывается выражение expr1, которым определяется начальное значение переменной, используемой для контроля за количеством итераций.
(Итерация — это одноразовое выполнение инструкций цикла.) Затем оценивается выражение ехрг2. (Оно оценивается перед каждой итерацией, для того чтобы определить, следует ли продолжать выполнение цикла.) Если выражение ехрг2 истинно, выполняется инструкция strati, после чего обрабатывается выражение ехргЗ. Выражение ехргЗ используется обычно для изменения значения переменной, контролирующей количество итераций. Если выражение ехрг2 ложно, выполнение цикла прекращается и программа переходит к обработке следующих за этим циклом кодов.
Пример использования цикла for
Приведенное выше объяснение может показаться вам не очень понятным, поэтому про-
демонстрируем работу цикла for на практическом примере.
Опишем, как этот код выполняется.
Ее выполнение приводит к отображению на экране значения переменной i.
Изменяя и усложняя выражение ехрг2, можно задавать самые разные условия, определяющие количество выполняемых итераций и момент прекращения выполнения цикла. Далее в примерах этой книги вы еще неоднократно встретитесь с ним.
Повторение ради повторения Если вы хотите, чтобы инструкция была выполнена несколько раз подряд, наберите такой код:
for (i = 0; i < n; i++)
Значение n определяет количество выполняемых итераций. Например, если вам нужно,
Чтобы не показаться навязчивым, можете позволить пользователю самому определить,
Вычисление факториала
Наверное, каждый программист когда-нибудь сталкивался с такой проблемой: как написать код, вычисляющий n-факториал?
if (n == 1)
Этот способ, несмотря на свою простоту, крайне неэффективен, поскольку, даже если вы будете продолжать аналогичным образом набирать коды для чисел 4, 5, ... 35 и т.д., все равно вы не сможете перебрать даже малую часть всех возможных вариантов. Реальным решением этой проблемы может быть использование цикла for .
#include "stdafx.h"
// This is the entry point for this application
//Get the value
//Now loop through. Each time through the loop
//Print the result
//Hang out until the user is finished
return 0;
Вверх
Как и цикл for, цикл while используется в тех случаях, когда некоторая инструкция (или набор инструкций) должна быть выполнена несколько раз подряд. Его синтаксис даже проще, чем синтаксис оператора for, и выглядит следующим образом:
Вначале оценивается выражение exprl. Если оно истинно, выполняется инструкция
Среди инструкций stmt (те, которые выполняются на каждой итерации) обязательно должна быть та, которая как-то изменяет значение переменной, входящей
Бесконечный цикл
Ниже приведен пример небольшой программы, выполнение шторой неминуемо приведет к зависанию компьютера.
Вверх
Visual C++ имеет в своем запасе еще пару операторов, управляющих последовательно
Оператор switch
Оператор switch подобен оператору if, но позволяет учесть сразу множество вари-
Вначале оценивается выражение ехрг и его значение сравнивается со значением vall.(Значение vall должно быть каким-нибудь числом, например 1 или 23,5.) Если значение выражения ехрг совпадает со значением vall , выполняется инструкция stmtl и все последующие за ней инструкции цикла switch. Если значение выражения ехрг не совпадает со значением vall , оно сравнивается со значением val2 и т.д.
Если вы хотите быть уверены, что по крайней мере какая-то инструкция будет обязательно выполнена (в том случае, если ни одно из заданных значений не совпадет со значением выражения ехрг), добавьте ключевое слово default (как показано выше) и укажите после него нужную инструкцию. Если после выполнения какой-то инструкции вы не хотите, чтобы все последующие инструкции также выполнялись, наберите после нее слово break, которое сразу же остановит выполнение оператора switch.
Если вы знакомы с языком Visual Basic, вы, наверное, ожидаете, что, как и в
Продемонстрируем работу оператора switch на примере, отображающем названия некоторых чисел:
Обратите внимание на наличие ключевых слов break после каждой инструкции, следующей за словом case. Если бы их там не было, возвращаемый программой результат выглядел бы так:
Результат
Оператор do
Выполнение цикла do во многом подобно выполнению цикла while. Отличие состоит в
Вот пример использование цикла do, который выполняется до тех пор, пока значение переменной i не сравняется со значением переменной n:
int i = 0;
Если даже переменная n имеет значение 0, это число все равно будет отображено на экране, поскольку проверяемое выражение (в данном случае i
Выражение i = i + 1 эквивалентно выражению i++.
Назад |
Начало урока |
Вверх |
Вперед
Великолепная тройка: ключевые слова if, for и while
Оператор if (называемый также условным оператором) выполняет определенный набор инструкций в том и только том случае, если заданное условие выполняется. Операторы for и while (называемые иногда цикл for и цикл while) повторяют нужное количество раз один и тот же заданный набор инструкций.
Условный оператор
if (expr1)
stmt;
например такое, как i < 1, а словом stmt— инструкция, например
cost = cost + 1.)
логическое значение. Если выражение истинно, выполняется инструкция stmt. Можно использовать фигурные скобки, для того чтобы заключить в них набор инструкций, которые должны будут выполняться в случае, если проверяемое выражение истинно. Например, следующим кодом проверяется значение логической переменной fDcDo, и, если оно совпадает со значением true , выполняется набор из трех инструкций:
if (fDcDo)
{
nDidle = 1;
nDum = 0;
if (nCount > 3000)
{
if (expr1)
if (nHandValue > 21)
{
nUserScore -= nBet;
fBusted = true;
else
{
cout << "Еще?\n";
cin >> fHitMe;
Коды программ можно форматировать множеством способов. И хотя для внешнего оформления кодов не
существует никаких стандартов и ограничений, вы можете применить пару приемов, позволяющих значительно упростить их чтение и понимание.
Хорошей практикой является выделение с помощью отступов всех строк, заключенных в пару фигурных скобок. Таким образом вы сразу можете видеть набор инструкций, выполняемых вместе. Например, следующий код легко читается, поскольку к нужным строкам добавлены отступы:
if (nHandValue > 21)
{
nUserScore -= nBet;
fBusted = true;
else
{
cout « "Еще?\п";
cin » fHitMe;
//В картах перебор
nUserScore -= nBet; fBusted = true;} else
{
cout « "Еще?\п"; cin >> fHitMe;
Если вы читаете главы книги по порядку, то уже видели использование этого приема на примере функции main, все строки которой выделяются отступами. А также видели нечто подобное при создании структур.
if (too)
{
if (bar > 3)
{
if (goober < 7)
{
if (fFoo)
{
if (fFoo)
nVal++;
nCheck++;
if (fFoo)
{
nCheck++;
//Если сумма превышает $5000, скидка равна 30%
if (nSumrr, > 5000)
{
else
{
if (nSumm > 3000)
{
//В противном случае скидка не предоставляется
else
{
Оператор for
for(exp1; expr2; ехргЗ)
stmt1;
int i;
for (i = 0; i < 2; i++)
{
Console::WriteLine(i.ToString()) ;
единицу и становиться равным числу 2.
{
чтобы строка "Терпение и еще раз терпение" была выведена на экран 50 раз подряд, наберите такой код;
for (i = 0; i < 50; i++)
{
сколько раз строка должна отобразиться на экране. Делается это так:
int nCount;
Console::WriteLine(S"Сколько строк отобразить?");
nCount = Console::ReadLine()->ToInt32();
for (i = 0; i < nCount; i++)
{
Это выражение (n-факториал) вычисляется по такой формуле: nх (n - 1) х (n - 2) х ... х1.
Так, 2-факториал (пишется как 2! в математических книгах, но не в компьютерных кодах) вычисляется как 2 х 1, а 3! - как 3 х 2 х 1.
Одним из вариантов решения такой проблемы может быть приведенный ниже код.
//Вычисление n!
n = Int32 :: Parse (Console : : ReadLine () ) ;
{
else if (n == 2)
{
else if (n == 3)
{
// Factorial
// Computes n!
#using <mscorlib.dll>
using namespace System;
#ifdef _UNICODE
int wmain(void)
#else
int main(void)
#endif
{
int nResult = 1;
int i; //Loop variable
Console::WriteLine("What is the number?");
nNumber = Int32::Parse(Console::ReadLine());
//multiply the result by i. This will give
//1*2*3...n because i starts at 1 and increases
//until it is n
for (i=1; i<=nNumber; i++)
{
Console::WriteLine(S"n! is
{0}", nResult.ToString());
Console::WriteLine(L"Hit the enter key to stop the program");
Console::ReadLine();
Оператор while
while [exprl]
stmt;
stmt. Затем опять проверяется выражение exprl. До тех пор пока выражение exprl будет оставаться истинным, инструкция stmt будет выполняться снова и снова. Как только выражение exprl становится ложным, выполнение цикла прекращается.
Например, если нужно создать цикл, выполняющий десять итераций, наберите такой код:
int i = 0;
while (i < 10]
в состав выражения exprl. В противном случае выполнение цикла никогда не
прекратится.
//Компьютер завис
int main(void)
{
Произойдет это по следующей причине. Выполнение цикла while продолжается до тех пор, пока выражение exprl не станет ложным. В данном случае выражению exprl постоянно соответствует число 1, которое всегда воспринимается как истинное. Поэтому выполнение цикла while без внешнего вмешательства никогда не прекратится. Подобные циклы обычно называют бесконечными.
Ключевые слова switch u do
стью выполняемых инструкций. Познакомимся с ними поближе.
антов и выбрать только один из них. (Описание каждого варианта начинается с ключевого слова case.) Таким образом, если необходимо создать код, решающий задачу наподобие; "если это Вася, тогда ..., если это Маша, тогда ..., если это Дима, тогда ...", используйте оператор switch, который может заменить собой сразу несколько операторов if. Синтаксис оператора switch выглядит так:
switch (ехрr)
{
case val2:
default:
Visual Basic, в качестве проверяемых значений val могут быть использованы
строки. К сожалению, это не так. Сравниваться могут только числовые значения,
но не текстовые.
//Названия чисел 1, 2, 3 и 4
switch (n)
{
break;
case 2 :
break;
case 3:
break;
case 4:
brеак;
default:
1 одиндватричетыренеизвестное число
2 дватричетыренеизвестное число
и т.д.
ключевое слово break. Если этого не делать, выполняться будут все инструкции
оператора switch, набранные после слова case со значением, которое совпало
с проверяемым.
том, что цикл while проверяет истинность выражения до того, как будет выполнена какая-либо инструкция. Поэтому возможен вариант (если выражение сразу окажется ложным), при котором ни одна из инструкций не будет выполнена. Цикл do, наоборот, вначале выполняет первую итерацию и только затем проверяет истинность выражения. Если выражение истинно, выполняется следующая итерация и т.д. Когда выражение становится ложным, выполнение цикла прекращается.
do
stint;
while (expr);
do
Console::WriteLine(i.ToString());
while (i < n);
Содержание