Можно ли использовать break

Мысли вслух

В общении с коллегами — учителями информатики — я много раз сталкивался с твёрдым убеждением, что использование оператора

break

для досрочного выхода из цикла — это «неграмотно», «грязный хак», «не соответствует принципам структурного программирования» и вообще «я своим ученикам такое не зачту». В то же время общение с профессиональными программистами показывает, что такой прием на практике применяется очень часто, потому что это удобно и в большинстве случаев делает программу более понятной.

Такой «разброд» имеет совершенно объяснимые причины. Большинство преподавателей, с одной стороны, когда-то заучили, что структурное программирование — это хорошо, а любое отступление от него — это плохо. С другой стороны, сами они уже фактически отошли от промышленного программирования: я могу на пальцах одной руки пересчитать знакомых (в том числе и по Интернету) учителей информатики, которые сами написали что-то стóящее. Таким образом, наблюдаем закон Дж.Б. Шоу в действии.

Попробуем разобраться в сути вещей. Оператор

break

— это фактически оператор перехода, знаменитый

GOTO

, который в 1970-е годы был морально уничтожен, прежде всего, стараниями «отца структурного программирования» Эдсгера Дейкстры [1]. Однако сами «отцы» хорошо понимали, что программа без

GOTO

ещё не становится автоматически структурной программой. Поэтому появилось на свет эссе Дональда Кнута «Структурное программирование с операторами GOTO» [2]. Кнут писал (перевод мой):

«Другими словами, мы не должны просто удалять операторы GOTO из-за того, что сейчас модно это делать; присутствие или отсутствие операторов GOTO — это не главный вопрос. Истинная цель состоит в том, чтобы формулировать наши программы таким образом, чтобы их было легко понимать.»

Посмотрим, как обстоит дело с пониманием программ, содержащих циклы с операторами

break

и сравним их с программами, где операторов

break

умышленно избегают.

Пример 1. С клавиатуры вводятся числа, ввод заканчивается числом 999. Вычислить сумму введенных чисел.

Вот решение с использованием

break

:

s := 0; while True do begin Readln(x); if x = 999 then break; s := s + x; end;

На взгляд автора, этот алгоритм очень хорошо соответствует словесному описанию: «строим цикл, выход из которого происходит при получении числа 999».

Теперь посмотрим на «кошерные» альтернативы. Нужно как-то выполнить те же действия (то есть, выйти из цикла при получении числа 999), не используя оператор выхода из цикла.

Во-первых, можно поставить условие цикла

x 999

, но при этом нужно будет инициализировать переменную

x

до цикла каким-то «магическим числом», отличным от 999, например, 1 (или 998 :-). Программист, который будет разбираться в таком коде через некоторое время, спасибо вам не скажет. Кроме того, вторую часть тела цикла придется взять в условный оператор, а эта вторая часть может быть достаточно большой. Читабельность явно не повышается. Зато программа «структурная», можно «взять с полки пирожок». 🙂

s:=0; x := 1; while x 999 do begin Readln(x); if x 999 then s := s + x; end;

Заметим, что число 999 появляется в программе дважды: в заголовке цикла и в условии в теле цикла, что само по себе уже нехорошо.

Можно вынести оператор

Readln

за цикл, продублировав его в теле цикла:

s := 0; Readln(x); while x 999 do begin s := s + x; Readln(x); end;

На взгляд автора, при этом два оператора ввода, выполняющие одну и ту же функцию, «размывают» логику программы и не добавляют ей «прозрачности». Кроме того, вместо

Readln

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

Кроме того, можно ввести логическую переменную (флаг), которой присваивается истинное значение при получении числа 999:

stop := False; while not stop do begin Readln(x); if x = 999 then stop := True else s := s + x; end;

Но тут нужно вспомнить о «бритве Оккама» — не плоди лишних сущностей. И ещё — любое усложнение системы, как правило, снижает её надежность.

Еще один вариант — перейти на цикл с постусловием:

s := 0; repeat Readln(x); if x 999 then s := s + x; until x = 999;

Во-первых, как и в одном из предыдущих вариантов, здесь два раза всплывает число 999. Во-вторых, вторую часть тела цикла снова нужно помещать в условный оператор. В-третьих, читать программы с циклами

repeat

— это сущее наказание: встретив слово

repeat

, судорожно пытаемся найти соответствующий

until

с условием, без этого всё вообще непонятно. Потом опять нужно смотреть наверх: что же там в теле цикла…

Можно, конечно, и так :-):

s := 0; try while True do begin Readln(x); if x = 999 then raise Exception.Create(»); s := s + x; end; except end;

Но по сути это то же самое, что и

break

. Использовать здесь исключения — всё равно, что гвозди микроскопом забивать.

Рассмотрим еще один пример.

Пример 2. Найти в массиве

A[1..N]

элемент, равный

X

, или сообщить, что такого элемента нет.

Решение с помощью

break

:

nX := 0; for i:=1 to N do if A[i] = X then begin nX := i; break; end; if nX = 0 then writeln(‘Не нашли!’) else writeln(‘nX = ‘, nX);

Как и для первого примера, программа с

break

почти дословно повторяет словесное описание идеи решения: «просматриваем все элементы массива с первого до последнего; как только нашли нужный элемент, запоминаем его номер и выходим из цикла».

Вот альтернатива без

break

:

nX := 1; while (nX X) do Inc(nX); if nX > N then writeln(‘Не нашли!’) else writeln(‘nX = ‘, nX);

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

X

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

Вот еще вариант, с логической переменной:

nX := 1; found := False; repeat if A[nX] = X then found:= True else Inc(nX); until found or (nX > N); if not found then writeln(‘Не нашли!’) else writeln(‘nX = ‘, nX);

Какая программа понятнее, каждый решает сам. 🙂

Итак, подытожим.

  1. Оператор break есть практически во всех современных языках программирования. «Значит, это кому-нибудь нужно!»
  2. Это инструмент, который нужно использовать в соответствии с его назначением.
  3. Само по себе наличие или отсутствие оператора break ничего не говорит о том, грамотно ли написана программа; задача состоит в том, чтобы сделать ее наиболее понятной и «прозрачной».
  4. Использование оператора break относится к так называемым «структурным» переходам [3], то есть к переходам вперёд в пределах того же модуля, что не нарушает принципы структурного программирования.

Разобравшись с

break

, можно перейти к его непосредственному «родственнику» — оператору

continue

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

Пример 3. В цикле обрабатываются все элементы массива

A[1:N]

. Для каждого из них сначала выполняются операторы

Читайте также:  Можно ли использовать гофру от вытяжки

S1

,

S2

, …,

SN

, в результате вычисляется некоторое значение

x

. Если получено значение

x = 1

, нужно выполнить еще операторы

T1

,

T2

, …,

TM

, а в противном случае перейти к следующему элементу.

«Классическое» решение выглядит так:

for i:=1 to N do begin S1; S2; … x := SN; if x = 1 then begin T1; T2; … TM; end end;

Вроде бы всё хорошо. Но мы потеряли «локальность»: при достаточно длинном теле условного оператора нужно еще «сканировать» цикл до конца, проверяя, не выполняются ли какие-то действия в том случае, когда

x 1

. А эту проблему может элегантно решить

continue

:

for i:=1 to N do begin S1; S2; … x := SN; if x 1 then continue; T1; T2; … TM end;

Здесь уже точно ясно, что при

x 1

никаких дополнительных операций не происходит. По мнению автора, такой вариант более «прозрачен» и, по крайней мере, не хуже предыдущего.

Остается еще один «смежный» вопрос: можно ли писать подпрограммы с несколькими выходами? Давайте посмотрим пример рекурсивной процедуры.

Пример 4. Разработать процедуру, которая выводит на экран решение задачи «Ханойская башня» [4].

Рекурсивное решение этой задачи хорошо известно, одна из реализаций выглядит так:

procedure Hanoi(n, k, m: integer); var p: integer; begin if n = 0 then exit; p := 6 — k — m; Hanoi(n-1, k, p); writeln(k, ‘ -> ‘, m); Hanoi(n-1, p, m) end;

Здесь

n

— количество дисков, которые нужно перенести;

k

— номер начального стержня и

m

— номер конечного стержня.

И все было бы хорошо, но тут нарушен ещё один принцип, который стал «священной коровой» ортодоксального структурного программирования: процедура имеет (увы 🙂 два выхода, один естественный, и второй — по признаку окончания рекурсии.

Можно ли было обойтись без этого? Да, можно, «упаковав» все тело процедуры внутрь условного оператора:

procedure Hanoi(n, k, m: integer); var p: integer; begin if n > 0 then begin p := 6 — k — m; Hanoi(n-1, k, p); writeln(k, ‘ -> ‘, m); Hanoi(n-1, p, m) end end;

Но тут мы опять теряем локальность — при достаточно длинном тексте процедуры нужно еще посмотреть, не выполняются ли какие-то действия после условного оператора. Да и не совсем понятно, зачем добавлять лишний уровень вложенности. «Не плоди лишних сущностей». По мнению автора, первое приведенное решение более понятное и более красивое.

Пример 5. Разработать функцию, которая определяет, если ли в квадратной матрице элемент, равный заданному значению.

Будем предполагать, что введен тип данных

type Matrix = array[1..N,1..N] of integer;

Тогда функцию можно написать так:

Find(const A: Matrix; X: integer): boolean; var i, j: integer; begin Result := True; for i:=1 to N do for j:=1 to N do if A[i,j] = X then exit; Result := False end;

Здесь оператор

exit

фактически выполняет роль

break

для вложенного цикла. С формальной точки зрения у функции два выхода. В общем, «я своим ученикам никогда такое не зачту» — уже слышу я от учителей информатики.

А давайте подумаем, какие альтернативы? Можно вот так:

Find(const A: Matrix; X: integer): Boolean; var i, j: integer; label finish; begin Result := True; for i:=1 to N do for j:=1 to N do if A[i,j] = X then goto finish; Result := False; finish: end;

Но тут вообще «криминал» — метка и

goto

! Хотя по сути ничего не изменилось, тот же выход из вложенного цикла.

Конечно, здесь можно использовать исключение:

Find(const A: Matrix; X: integer): Boolean; var i, j: integer; begin Result := False; try for i:=1 to N do for j:=1 to N do if A[i,j] = X then raise Exception.Create(»); except Result := True end end;

Но ведь это далеко не «исключительная ситуация», поэтому по смыслу исключения здесь всё-таки не особо уместны. Кроме того, нужно учитывать, что при обработке исключений выполняется большое число машинных команд, что снижает эффективность программы.

Любителей «чистого» структурного программирования наверняка устроит такой вариант решения:

Find(A: Matrix; X: integer): Boolean; var i, j: integer; begin Result := False; for i:=1 to N do for j:=1 to N do if A[i,j] = X then Result := True end;

Но, к сожалению, по эффективности он не может составить конкуренцию предыдущим, так как в любом случае рассматриваются все N2 элементов массива, даже если элемент

A[1,1]

равен

X

.

Выводы

Эта статья, прежде всего, о том, что любые идеи и принципы нужно воспринимать в контексте конечной цели. Одна из основных целей концепции структурного программирования — повысить читаемость программ и за счёт этого облегчить их отладку, тестирование и сопровождение. Поэтому применение операторов

break

,

continue

и

exit

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

В то же время попытки избавиться от этих операторов (для того, чтобы формально соблюсти «классические правила») могут привести к ухудшению читаемости программы.

Литература

  1. Dijkstra E.W., Go To ement Considered Harmful // Communications of the ACM, Vol. 11, No. 3, March 1968, pp. 147-148. (PDF)
  2. Knuth D.E. Structured Programming with GO TO ements // ASM Computing Surveys. 1974. 6(4). P.261-301. (HTML, PDF)
  3. Непейвода H.H., Скопин И.Н. Основания программирования. — Москва-Ижевск: Институт компьютерных исследований, 2003. (PDF)
  4. Гарднер М., Математические головоломки и развлечения. — М.: Мир, 1999.

Ярлыки: Дейкстра, Кнут, Паскаль, программирование, break, continue, exit, goto

Источник

Урок №70. Операторы break и continue

Обновл. 15 Сен 2020 |

Хотя вы уже видели оператор break в связке с оператором switch, все же он заслуживает большего внимания, поскольку может использоваться и с циклами. Оператор break приводит к завершению выполнения циклов do, for или while.

break и switch

В контексте оператора switch оператор break обычно используется в конце каждого кейса для его завершения (предотвращая fall-through):

switch (op)

{

case ‘+’:

doAddition(a, b);

break;

case ‘-‘:

doSubtraction(a, b);

break;

case ‘*’:

doMultiplication(a, b);

break;

case ‘/’:

doDivision(a, b);

break;

}

break и циклы

В контексте циклов оператор break используется для завершения работы цикла раньше времени:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#include <iostream>

int main()

{

int sum = 0;

// Разрешаем пользователю ввести до 10 чисел

for (int count=0; count < 10; ++count)

{

std::cout << «Enter a number to add, or 0 to exit: «;

int val;

std::cin >> val;

// Выходим из цикла, если пользователь введет 0

if (val == 0)

break;

// В противном случае, добавляем число к общей сумме

sum += val;

}

std::cout << «The sum of all the numbers you entered is » << sum << «n»;

return 0;

}

Эта программа позволяет пользователю ввести до 10 чисел и в конце подсчитывает их сумму. Если пользователь введет 0, то выполнится break и цикл завершится (не важно, сколько чисел в этот момент успел ввести пользователь).

Обратите внимание, оператор break может использоваться и для выхода из бесконечного цикла:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#include <iostream>

int main()

{

while (true) // бесконечный цикл

{

std::cout << «Enter 0 to exit or anything else to continue: «;

int val;

std::cin >> val;

// Выходим из цикла, если пользователь ввел 0

if (val == 0)

break;

}

std::cout << «We’re out!n»;

return 0;

}

break и return

Новички часто путают или не понимают разницы между операторами break и return. Оператор break завершает работу switch или цикла, а выполнение кода продолжается с первого стейтмента, который находится сразу же после этого switch или цикла. Оператор return завершает выполнение всей функции, в которой находится цикл, а выполнение продолжается в точке после вызова функции:

Читайте также:  Мтс smart безлимитище можно ли использовать в модеме мтс

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

#include <iostream>

int breakOrReturn()

{

while (true) // бесконечный цикл

{

std::cout << «Enter ‘b’ to break or ‘r’ to return: «;

char sm;

std::cin >> sm;

if (sm == ‘b’)

break; // выполнение кода продолжится с первого стейтмента после цикла

if (sm == ‘r’)

return 1; // выполнение return приведет к тому, что управление сразу возвратится в caller (в этом случае, в функцию main())

}

// Использование оператора break приведет к тому, что выполнение цикла продолжится здесь

std::cout << «We broke out of the loopn»;

return 0;

}

int main()

{

int returnValue = breakOrReturn();

std::cout << » breakOrContinue returned » << returnValue << ‘n’;

return 0;

}

Оператор continue

Оператор continue позволяет сразу перейти в конец тела цикла, пропуская весь код, который находится под ним. Это полезно в тех случаях, когда мы хотим завершить текущую итерацию раньше времени. Например:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#include <iostream>

int main()

{

for (int count = 0; count < 20; ++count)

{

// Если число делится нацело на 4, то пропускаем весь код в этой итерации после continue

if ((count % 4) == 0)

continue; // пропускаем всё и переходим в конец тела цикла

// Если число не делится нацело на 4, то выполнение кода продолжается

std::cout << count << std::endl;

// Точка выполнения после оператора continue перемещается сюда

}

return 0;

}

Эта программа выведет все числа от 0 до 19, которые не делятся нацело на 4.

В случае с циклом for часть инкремента/декремента счетчика по-прежнему выполняется даже после выполнения continue (так как инкремент/декремент происходит вне тела цикла).

Будьте осторожны при использовании оператора continue с циклами while или do while. Поскольку в этих циклах инкремент счетчиков выполняется непосредственно в теле цикла, то использование continue может привести к тому, что цикл станет бесконечным! Например:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#include <iostream>

int main()

{

int count(0);

while (count < 10)

{

if (count == 5)

continue; // переходим в конец тела цикла

std::cout << count << » «;

++count;

// Точка выполнения после оператора continue перемещается сюда

}

return 0;

}

Предполагается, что программа выведет все числа от 0 до 9, за исключением 5. Но на самом деле:

0 1 2 3 4

А затем цикл станет бесконечным. Когда значением count становится 5, то условие оператора if станет true, затем выполнится continue и мы, минуя вывод числа и инкремент счетчика, перейдем к следующей итерации. Переменная count так и не увеличится. Как результат, в следующей итерации переменная count по-прежнему останется со значением 5, а оператор if по-прежнему останется true, и цикл станет бесконечным.

А вот правильное решение, но с использованием цикла do while:

#include <iostream>

int main()

{

int count(0);

do

{

if (count == 5)

continue; // переходим в конец тела цикла

std::cout << count << » «;

// Точка выполнения после оператора continue перемещается сюда

} while (++count < 10); // этот код выполняется, так как он находится вне тела цикла

return 0;

}

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

0 1 2 3 4 6 7 8 9

break и continue

Многие учебники рекомендуют не использовать операторы break и continue, поскольку они приводят к произвольному перемещению точки выполнения программы по всему коду, что усложняет понимание и следование логике выполнения такого кода.

Тем не менее, разумное использование операторов break и continue может улучшить читабельность циклов в программе, уменьшив при этом количество вложенных блоков и необходимость наличия сложной логики выполнения циклов. Например, рассмотрим следующую программу:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

#include <iostream>

int main()

{

int count(0); // считаем количество итераций цикла

bool exitLoop(false); // контролируем завершение выполнения цикла

while (!exitLoop)

{

std::cout << «Enter ‘e’ to exit this loop or any other key to continue: «;

char sm;

std::cin >> sm;

if (sm == ‘e’)

exitLoop = true;

else

{

++count;

std::cout << «We’ve iterated » << count << » sn»;

}

}

return 0;

}

Эта программа использует логическую переменную для выхода из цикла, а также вложенный блок, который запускается только в том случае, если пользователь не использует символ выхода.

А вот более читабельная версия, но с использованием оператора break:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#include <iostream>

int main()

{

int count(0); // считаем количество итераций цикла

while (true) // выполнение цикла продолжается, если его не завершит пользователь

{

std::cout << «Enter ‘e’ to exit this loop or any other key to continue: «;

char sm;

std::cin >> sm;

if (sm == ‘e’)

break;

++count;

std::cout << «We’ve iterated » << count << » sn»;

}

return 0;

}

Здесь (с одним оператором break) мы избежали использования как логической переменной (а также понимания того, зачем она и где используется), так и оператора else с вложенным блоком.

Уменьшение количества используемых переменных и вложенных блоков улучшают читабельность и понимание кода намного больше, чем операторы break или continue могут нанести вред. По этой причине считается приемлемым их разумное использование.

Оценить статью:

Загрузка…

Источник

BestProg

Содержание

  • 1. Особенности применения оператора break
  • 2. Особенности применения оператора continue
  • 3. Оператор break. Примеры решения задач с использованием циклов
    • 3.1. Вычисление суммы чисел, введенных с клавиатуры. Цикл for
    • 3.2. Вычисление значения числа π по формуле
  • 4. Оператор continue. Примеры решения задач
    • 4.1. Вычисление суммы элементов последовательности
    • 4.2. Вычисление суммы элементов массива в соответствии с условием
  • 5. Как работает оператор break в случае вложенных циклов? Пример
  • 6. Можно ли использовать операторы break и continue в операторе if?
  • Связанные темы

Поиск на других ресурсах:

1. Особенности применения оператора break

В языке C++ существуют операторы break и continue, которые используются для управления ходом выполнения циклического процесса. Эти операторы могут быть применены только в теле цикла.

Оператор break предназначен для искусственного прерывания выполнения:

  • последовательности итераций в операторах цикла for, while или do-while;
  • последовательности операторов в операторе выбора switch.

Чаще всего оператор break используется в сочетании с оператором условия if. В этом случае, происходит проверка некоторого условия, и в случае успеха вызывается оператор break.

Пример. В нижеследующем примере при достижении переменной i значения 3 происходит безусловный выход из цикла путем вызова оператора break. Продемонстрирован вызов break для всех видов операторов.

#include <iostream> using namespace std; void main() { int i, j; // Оператор break // 1. Цикл for cout << «Loop for:» << endl; for (i = 0; i < 5; i++) // цикл по i { if (i == 3) break; // выход из цикла for // этот оператор выполняется cout << «i = » << i << endl; } // 2. Цикл while cout << «Loop while:» << endl; i = 0; while (i < 5) { if (i == 3) break; // выход из цикла while cout << «i = » << i << endl; i++; } // 3. Цикл do-while cout << «Loop do-while:» << endl; i = 0; do { if (i == 3) break; // выход из цикла do-while cout << «i = » << i << endl; i++; } while (i < 5); }

Читайте также:  Можно ли использовать клей как затирку

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

Loop for: i = 0 i = 1 i = 2 Loop while: i = 0 i = 1 i = 2 Loop do-while: i = 0 i = 1 i = 2

2. Особенности применения оператора continue

Оператор continue предназначен для перехода к выполнению следующей итерации цикла. Если в теле цикла встречается оператор continue, то:

  • выполнение текущей итерации останавливается;
  • происходит переход к следующей итерации цикла.

Оператор continue может быть применен во всех видах циклов: for, while, do-while.

В большинстве случаев вызов оператора continue осуществляется при выполнении некоторого условия в операторе if.

Пример. В примере демонстрируется использование оператора continue для всех видов циклов C++. В задаче, при достижении переменной i значения 3 происходит переход к следующей итерации с помощью инструкции continue.

#include <iostream> using namespace std; void main() { int i, j; // Оператор continue // 1. Цикл for cout << «Loop for:» << endl; for (i = 0; i < 5; i++) // цикл по i { if (i == 3) continue; // переход к следующей итерации // этот оператор выполняется cout << «i = » << i << endl; } // 2. Цикл while cout << «Loop while:» << endl; i = 0; while (i < 5) { if (i == 3) { i++; // увеличить счетчик — обязательно continue; // переход к следующей итерации } cout << «i = » << i << endl; i++; } // 3. Цикл do-while cout << «Loop do-while:» << endl; i = 0; do { if (i == 3) { i++; // увеличить счетчик — обязательно continue; // переход к следующей итерации } cout << «i = » << i << endl; i++; } while (i < 5); }

Результат работы программы

Loop for: i = 0 i = 1 i = 2 i = 4 Loop while: i = 0 i = 1 i = 2 i = 4 Loop do-while: i = 0 i = 1 i = 2 i = 4

3. Оператор break. Примеры решения задач с использованием циклов
3.1. Вычисление суммы чисел, введенных с клавиатуры. Цикл for

Пользователь вводит числа с клавиатуры. Окончание ввода — число 0. Вычислить сумму чисел, которые введет пользователь. В программе использовать операторы for и break.

Решение задачи на языке C++ следующее

#include <iostream> using namespace std; void main() { // Вычисление суммы чисел, вводимых с клавиатури int number, summ = 0; cout << «Enter numbers (0-exit):» << ::endl; // вечный цикл for (;;) { // ввод числа cout << «number = «; cin >> number; // если ввести 0, то выход из цикла if (number == 0) break; // увеличить сумму на величину числа summ += number; } // отобразить сумму cout << «summ = » << summ << endl; }

3.2. Вычисление значения числа π по формуле

Вычислить значение числа π, используя формулу с заданной точностью.

#include <iostream> using namespace std; void main() { // Вычислить значение числа Пи с заданной точностью // 1. Объявить внутренние переменные int n; // количество знаков после запятой double eps; // точность int i, k; double pi; // искомое число Pi double t; // 2. Ввести количество знаков после запятой cout << «Enter the number of decimal places: n = «; cin >> n; // 3. Формирование точности вычислений eps = 1; i = 0; while (i < n) { eps /= 10; // разделить на 10 n раз i++; } // 4. Цикл вычисления числа Pi pi = 1; i = 1; k = 1; t = 0; while (1) // вечный цикл { t = pi; i = i + 2; k = -k; pi = pi + k * 1.0 / i; // проверка, достигнута ли желаемая точность if (fabs(pi — t) < eps) break; // если точность достигнута, выйти из цикла } // 5. Вывести результат pi = 4 * pi; cout << «pi = » << pi << endl; cout << «i = » << i << endl; }

В примере для выхода из цикла while используется оператор break.

4. Оператор continue. Примеры решения задач
4.1. Вычисление суммы элементов последовательности

Дана последовательность вещественных чисел, которая завершается числом 0. Вычислить сумму элементов последовательности, которые имеют значения в пределах [-5; 5].

Решение задачи на C++ следующее

#include <iostream> using namespace std; void main() { // Вычисление суммы чисел, находящихся в указанных пределах // конец ввода — значение 0 const double MIN = -5.0; // нижний предел const double MAX = 5.0; // верхний предел double number; // вводимое число double summ = 0; // указанная сумма cout << «Enter numbers (exit — 0):» << ::endl; // цикл do-while do { // ввод числа cout << «=> «; cin >> number; // если число за допустимыми пределами if ((number < MIN) || (number > MAX)) continue; // то перейти к следующей итерации цикла // вычислить сумму, если введено коректное число summ += number; } while (number != 0); // числа вводятся до числа 0 // отобразить сумму cout << «summ = » << summ << endl; }

4.2. Вычисление суммы элементов массива в соответствии с условием

Вычислить сумму элементов массива, лежащих на парных позициях. Поскольку в C++ элементы массива нумеруются с 0, то парными будем считать позиции 1, 3, 5, и т.д.

Решение задачи с использованием оператора continue следующее.

#include <iostream> using namespace std; void main() { // Вычислить сумму элементов массива, лежащих на парных позициях // 1. Объявить внутренние переменные const int MAX = 10; // максимально-возможное количество элементов в массиве double A[MAX]; // указанный массив int n; // количество элементов в массиве double summ; // искомая сумма // 2. Ввести количество элементов в массиве cout << «Enter number of items in the array (1..10): «; cin >> n; // 3. Проверка, корректно ли введены данные if ((n < 1) || (n > MAX)) return; // 4. Ввод массива cout << «Enter the array:» << endl; for (int i = 0; i < n; i++) { cout << «A[» << i << «] = «; cin >> A[i]; } // 5. Вычисление суммы summ = 0; for (int i = 0; i < n; i++) { // проверка, позиции на парность if (i % 2 == 0) continue; // если позиция парная, то перейти к следующей итерации summ = summ + A[i]; // елси позиция непарная, вычислить сумму } // 5. Вывести сумму cout << «summ = » << summ << endl; }

5. Как работает оператор break в случае вложенных циклов? Пример

В случае вложенных циклов происходит выход из цикла наиболее низшего уровня. В нижеследующем примере вложенный цикл по j никогда не выполнится до конца, так как в нем встречается оператор break.

#include <iostream> using namespace std; void main() { int i, j; // Если циклы вложенные for (i = 0; i < 5; i++) // цикл по i { for (j = 0; j < 5; j++) // цикл по j { if (j == 0) break; // виход из цикла по j cout << «j = » << j << endl; } // этот оператор выполняется cout << «i = » << i << endl; } }

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

i = 0 i = 1 i = 2 i = 3 i = 4

6. Можно ли использовать операторы break и continue в операторе if?

Нет, нельзя. Однако, оператор break может еще использоваться как составная оператора switch.

Если попробовать использовать оператор break в конструкции if, то компилятор сгенерирует ошибку со следующим сообщением

a break ement may only be used within a loop or switch

Если попробовать вызвать оператор continue в конструкции if, то компилятор сгенерирует ошибку со следующим сообщением

a continue ement may only be used within a loop

Связанные темы

  • Оператор выбора switch
  • Циклы. Операторы цикла for, while, do…while

Источник