1.6. Инструкции. Условные операторы. Циклы
Как вы уже видели в предыдущих частях выполнение программы на C++ состоит из последовательных инстркций. Инструкции выполняются одна за другой. Тем не менее, несмотря на это, при определенных оптимизациях компилятор может попытаться съоптимизировать выполнение инстуркций и приведенный ниже пример не рекомендуется использовать на практике:
Вложенная видимость
Можно объявлять блоки (с помощью фигурных скобок) и в них объявлять переменные с уже сипользованным именем. В этом случае все манимпуляции с “новой” переменной никак не повлияют на переменную вне блока:
Условные операторы ветвления if/else
Самыми простыми условными ветвлениями в языке С++ являются стейтменты if/else. Они выглядят следующим образом:
При определенных сценаряих можно написать и проверку в else, но злоупотребять этим не стоит, так как код превразается не сильно читаемым (спагетти):
С++ предоставляет специальных тернарный оператор (? :), который может упростить выражение сверху (оставив функционал прежним):
Циклы for, while
Основным циклом в “классическом” C++ является цикл for. Общая его сигнатура следующая:
Например следующая инструкция считает сумму квадратов от 0 до 10 (не включительно)
В случае, когда нам необходимо задать только условия остановки данных код можно переписать с помощью цикла while:
Цикл do-while
Цикл do-while отличается от цикла while тем, что он гарантирует выполнение одного прогона, если даже условие в while уже не выполняется. В качестве примера рассмотрите следующие выражения:
Что такое цикл в с
Циклы позволяют выполняет некоторый набор инструкций множество раз, пока соблюдается определенное условие. В языке C++ имеются следующие виды циклов:
Цикл while
Цикл while выполняет некоторый код, пока его условие истинно, то есть возвращает true. Он имеет следующее формальное определение:
После ключевого слова while в скобках идет условное выражение, которое возвращает true или false. Затем в фигурных скобках идет набор инструкций, которые составляют тело цикла. И пока условие возвращает true, будут выполняться инструкции в теле цикла.
Например, выведем квадраты чисел от 1 до 9:
Каждый отдельный проход цикла называется итерацией. То есть в примере выше было 9 итераций.
Если цикл содержит одну инструкцию, то фигурные скобки можно опустить:
инициализатор выполняется один раз при начале выполнения цикла и представляет установку начальных условий, как правило, это инициализация счетчиков — специальных переменных, которые используются для контроля за циклом.
условие представляет условие, при соблюдении которого выполняется цикл. Как правило, в качестве условия используется операция сравнения, и если она возвращает ненулевое значение (то есть условие истинно), то выполняется тело цикла, а затем выполняется итерация .
итерация выполняется после каждого завершения блока цикла и задает изменение параметров цикла. Обычно здесь происходит увеличение счетчиков цикла.
Например, перепишем программу по выводу квадратов чисел с помощью цикла for:
Необязательно указывать все три выражения в определении цикла, мы можем одно или даже все из них опустить:
Здесь для хранения суммы чисел определена переменная sum , которая по умолчанию равна 0. В цикле определяем переменную-счетчик i и выполняем цикл, пока i не станет равна 6.
Обратите внимание на третью часть определения цикла — sum += i++ . Здесь мы прибавляем к переменной sum значение переменной i и потом увеличиваем значение i. Таким образом, мы нашли сумму чисел, но при этом обошлись без тела цикла.
Выражение инициализации может определять больше одной переменной. Например, определим две переменных и выведем на консоль их произведение:
Перебор значений в стиле for-each
Существует также особая форма цикла for , которая предназначена специально для работы с последовательностями значений. Эта форма имеет следующее формальное определение:
Здесь выражение <2, 3, 4, 5>как раз представляет последовательность значений — чисел int. Цикл перебирает всю эту последовательность и помещает каждое значение в переменную n , значение которой выводится на консоль.
Другой пример. Строка фактически представляет собой последовательность символов, которую также можно перебрать с помощью данной вида циклов:
Здесь каждый символ строки помещается в переменную c, значение которой затем выводится на консоль.
В дальнейшем мы рассмотрим различные виды последовательности, которые можно перебирать с помощью данного вида циклов.
Цикл do
В цикле do сначала выполняется код цикла, а потом происходит проверка условия в инструкции while. И пока это условие истинно, то есть не равно 0, то цикл повторяется. Формальное определение цикла:
Здесь код цикла сработает 6 раз, пока i не станет равным нулю.
Но важно отметить, что цикл do гарантирует хотя бы однократное выполнение действий, даже если условие в инструкции while не будет истинно. То есть мы можем написать:
Хотя у нас переменная i меньше 0, цикл все равно один раз выполнится.
Рассмотрим еще пример. В ряде консольных программ также реализован подобный цикл, который срабатывает, пока пользователь не введет какой-либо символ. Допустим, пользователь вводит числа, и программа должна вычислить среднее арифметическое чисел. И пусть пользователь может ввести неопределенное количество чисел, а если он захочет завершить ввод чисел, пусть введет символ «y» или «Y»:
В данном случае считываем каждое число в переменную number, а затем прибавляем ее к переменной total, попутно увеличиваем счетчик чисел — count. После каждого ввода также ожидаем еще один ввод — если пользователь введет «y» или «Y», завершаем цикл и выводим среднее арифметическое чисел. Пример работы программы:
Вложенные циклы for
Можно определять вложенные циклы. Например, выведем таблицу умножения с помощью вложенного цикла for :
Операторы continue и break
Иногда возникает необходимость выйти из цикла до его завершения. В этом случае можно воспользоваться оператором break . Например, нам надо подсчитать сумму чисел от 1 до 9, пока она не станет больше 20:
Здесь когда значение переменной result станет больше 20 (то есть когда i будет равно 6), осуществляется выход из цикла с помощью оператора break :
В отличие от оператора break , оператор continue производит переход к следующей итерации. Например, нам надо посчитать сумму только нечетных чисел из некоторого диапазона:
Однако в этих случаях в зависимости от ситуации все равно может быть какое-то условие, при котором цикл может завершить работу. В этом случае для выхода из цикла может применяться оператор break . Например, пусть пользователь бесконечно может вводить числа, а программа выводит ему квадрат числа. Но если пользователь ввел 0, то выполним выход из цикла:
Операторы цикла в языке Си
Рассмотрим третью алгоритмическую структуру — цикл.
Циклом называется блок кода, который для решения задачи требуется повторить несколько раз.
Каждый цикл состоит из
- блока проверки условия повторения цикла
- тела цикла
Цикл выполняется до тех пор, пока блок проверки условия возвращает истинное значение.
Тело цикла содержит последовательность операций, которая выполняется в случае истинного условия повторения цикла. После выполнения последней операции тела цикла снова выполняется операция проверки условия повторения цикла. Если это условие не выполняется, то будет выполнена операция, стоящая непосредственно после цикла в коде программы.
В языке Си следующие виды циклов:
- while — цикл с предусловием;
- do…while — цикл с постусловием;
- for — параметрический цикл (цикл с заданным числом повторений).
Цикл с предусловием while
Общая форма записи
Если Условие выполняется (выражение, проверяющее Условие , не равно нулю), то выполняется БлокОпераций , заключенный в фигурные скобки, затем Условие проверяется снова.
Последовательность действий, состоящая из проверки Условия и выполнения БлокаОпераций , повторяется до тех пор, пока выражение, проверяющее Условие , не станет ложным (равным нулю). При этом происходит выход из цикла, и производится выполнение операции, стоящей после оператора цикла.
Пример на Си : Посчитать сумму чисел от 1 до введенного k
Результат выполнения
При построении цикла while , в него необходимо включить конструкции, изменяющие величину проверяемого выражения так, чтобы в конце концов оно стало ложным (равным нулю). Иначе выполнение цикла будет осуществляться бесконечно (бесконечный цикл).
Пример бесконечного цикла
while — цикл с предусловием, поэтому вполне возможно, что тело цикла не будет выполнено ни разу если в момент первой проверки проверяемое условие окажется ложным.
Например, если в приведенном выше коде программы ввести k=-1, то получим результат 
Цикл с постусловием do. while
Общая форма записи
Цикл do. while — это цикл с постусловием, где истинность выражения, проверяющего Условие проверяется после выполнения Блока Операций , заключенного в фигурные скобки. Тело цикла выполняется до тех пор, пока выражение, проверяющее Условие , не станет ложным, то есть тело цикла с постусловием выполнится хотя бы один раз.
Использовать цикл do. while лучше в тех случаях, когда должна быть выполнена хотя бы одна итерация, либо когда инициализация объектов, участвующих в проверке условия, происходит внутри тела цикла.
Пример на Си . Проверка, что пользователь ввел число от 0 до 10
Результат выполнения: 
Параметрический цикл for
Общая форма записи
for — параметрический цикл (цикл с фиксированным числом повторений). Для организации такого цикла необходимо осуществить три операции:
- Инициализация — присваивание параметру цикла начального значения;
- Условие — проверка условия повторения цикла, чаще всего — сравнение величины параметра с некоторым граничным значением;
- Модификация — изменение значения параметра для следующего прохождения тела цикла.
Эти три операции записываются в скобках и разделяются точкой с запятой ; ;. Как правило, параметром цикла является целочисленная переменная.
Инициализация параметра осуществляется только один раз — когда цикл for начинает выполняться.
Проверка Условия повторения цикла осуществляется перед каждым возможным выполнением тела цикла. Когда выражение, проверяющее Условие становится ложным (равным нулю), цикл завершается. Модификация параметра осуществляется в конце каждого выполнения тела цикла. Параметр может как увеличиваться, так и уменьшаться.
Пример на Си : Посчитать сумму чисел от 1 до введенного k
Результат выполнения
В записи цикла for можно опустить одно или несколько выражений, но нельзя опускать точку с запятой, разделяющие три составляющие цикла.
Код предыдущего примера можно представить в виде
Параметры, находящиеся в выражениях в заголовке цикла можно изменить при выполнении операции в теле цикла, например
#define _CRT_SECURE_NO_WARNINGS // для возможности использования scanf
#include <stdio.h>
int main() <
int k; // объявляем целую переменную key
int sum = 0; // начальное значение суммы равно 0
printf( "k = " );
scanf( "%d" , &k); // вводим значение переменной k
for ( int i=1; i<=k; ) // цикл для переменной i от 1 до k с шагом 1
<
sum = sum + i; // добавляем значение i к сумме
i++; // добавляем 1 к значению i
>
printf( "sum = %d\n" , sum); // вывод значения суммы
getchar(); getchar();
return 0;
>
В цикле for может использоваться операция запятая — , — для разделения нескольких выражений. Это позволяет включить в спецификацию цикла несколько инициализирующих или корректирующих выражений. Выражения, к которым применяется операция запятая, будут вычисляться слева направо.
Результат выполнения
Вложенные циклы
В Си допускаются вложенные циклы, то есть когда один цикл находится внутри другого:
Пример : Вывести числа от 0 до 99, по 10 в каждой строке
Результат выполнения
Рекомендации по выбору цикла
При выборе цикла необходимо оценить необходимость проверки условия при входе в цикл или по завершении прохождения цикла.
Цикл с постусловием удобно применять в случаях, когда для проверки условия требуется вычислить значение выражения, которое затем будет размещено в теле цикла (см. выше пример ввода числа от 0 до 10).
Цикл c предусловием используется в случае если все переменные, участвующие в выражении, проверяющем условие, проинициализированы заранее, но точное число повторений цикла неизвестно или предполагается сложная модификация переменных, участвующих в формировании условия повторения цикла.
Если цикл ориентирован на работу с параметром, для которого заранее известно число повторений и шаг изменения, то более предпочтительным является параметрический цикл. Очень удобно использовать параметрический цикл при работе с массивами для перебора элементов.
Операторы прерывания и продолжения цикла break и continue
В теле любого цикла можно использовать операторы прерывания цикла — break и продолжения цикла — continue .
Оператор break позволяет выйти из цикла, не завершая его.
Оператор continue позволяет пропустить часть операторов тела цикла и начать новую итерацию.
Пример на Си : Вывести числа от 0 до 99 ниже главной диагонали
Результат выполнения 
Пример на Си : Вывести числа от 0 до 99 исключая числа, оканчивающиеся на 5 или 8
Результат выполнения 
При вложенных циклах действия операторов break и continue распространяется только на самую внутреннюю структуру, в которой они содержатся.
Оператор безусловного перехода goto
Общая форма записи
Выполнение оператора goto вызывает передачу управления в программе операции, помеченной Меткой . По сути Метка является идентификатором адреса операции, которой должно быть передано управление. Для отделения Метки от Операции используется двоеточие — : .
Метка может располагаться в программе как до оператора goto , так и после него. Имена Меток образуются по тем же правилам, что и имена переменных.
Пример на Си : Вывести все целые числа от 5 до 0.
Результат выполнения 
Использование оператора goto в программах на Си без крайней необходимости не рекомендуется, поскольку это может повлечь за собой ряд ошибок, связанных с плохой читаемостью кода программы. Использование операторов цикла позволяет практически полностью исключить необходимость использования оператора goto .
Что такое цикл в с
В Си существуют все три типа операторов цикла: цикл с предусловием, цикл с постусловием и цикл с параметром.
Цикл с предусловием . Формат оператора цикла с предусловием:
while (выражение) оператор;
Цикл повторяет свое выполнение, пока значение выражения отлично от нуля, т. е. заключенное в нем условие цикла истинно.
В качестве примера использования оператора цикла рассмотрим программу вычисления факториала целого положительного числа N!. Сопоставим программу решения этой задачи, написанную на Си.
// Программа вычисления факториала
Обратите внимание на операторы в теле цикла. Конечно, и в Си-программе можно было написать два оператора присваивания, объединив их фигурными скобками. Однако использованный способ записи более лаконичен и более характерен для Си. Этот же самый оператор можно было записать еще короче: F*=i++
При практическом использовании этой программы не следует забывать, что факториал — очень быстро растущая функция, и поэтому при определенных значениях N выйдет из диапазона, соответствующего типу long int. Задав для переменной F тип unsigned long, можно сдвинуть эту границу, но этого может оказаться недостаточно. Предлагаем в качестве самостоятельного задания исследовать предельные значения N для двух указанных типов переменной F.
Интересно свойство следующего оператора:
Это бесконечный пустой цикл. Использование в качестве выражения константы 1 приводит к тому, что условие повторения цикла все время остается истинным и работа цикла никогда не заканчивается. Тело в этом цикле представляет собой пустой оператор. При исполнении такого оператора программа будет «топтаться на месте».
Рассмотрим еще один пример использования оператора цикла while. Вернемся к задаче итерационного вычисления суммы гармонического ряда: 1 + 1/2 + 1/3 + . с заданной точностью ε. Снова сопоставим программу на С++.