Введение
В этом практическом занятии вы изучите инструкции управления потоком в C++. Вы научитесь использовать инструкции if-else, switch, while, do-while и for.
В этом практическом занятии вы изучите инструкции управления потоком в C++. Вы научитесь использовать инструкции if-else, switch, while, do-while и for.
Есть три основных конструкции управления потоком - последовательная, условная (или решение) и циклическая (или итеративная). Последовательная структура: процесс выполнения идет сверху вниз по строкам. Условная структура использует инструкцию if-else для проверки, удовлетворяет ли утверждение определенным конкретным условиям, и затем делает выбор. Циклическая структура используется для повторного выполнения некоторых логических операций.

Программа представляет собой последовательность инструкций. Последовательный поток является наиболее распространенным и простым, при котором инструкции программы выполняются в том порядке, в котором они написаны - сверху вниз последовательно.
Существует несколько типов условных операторов: if-then, if-then-else, вложенный if (if-elseif-elseif-...-else), switch-case и условное выражение.
#include <iostream>
using namespace std;
int main(){
int mark;
cout<<"Введите число [0-100]: ";
cin>>mark;
// if
if (mark >= 50) {
cout << "Поздравляем!" << endl;
cout << "Продолжайте в том же духе!" << endl;
}
cout<<"Введите число [0-100]: ";
cin>>mark;
// if-else
if (mark >= 50) {
cout << "Поздравляем!" << endl;
cout << "Продолжайте в том же духе!" << endl;
} else {
cout << "Постарайтесь лучше!" << endl;
}
cout<<"Введите число [0-100]: ";
cin>>mark;
// вложенный if
if (mark >= 80) {
cout << "A" << endl;
} else if (mark >= 70) {
cout << "B" << endl;
} else if (mark >= 60) {
cout << "C" << endl;
} else if (mark >= 50) {
cout << "D" << endl;
} else {
cout << "F" << endl;
}
// switch-case
char oper;
int num1 = 1, num2 = 2, result = 0;
cout<<"Введите символ [+ - / *]: ";
cin>> oper;
switch (oper) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
default:
cout << "Неизвестный оператор" << endl;
}
cout<<num1<<oper<<num2<<"="<<result;
return 0;
}
Вывод:
Введите число [0-100]: 50
Поздравляем!
Продолжайте в том же духе!
Введите число [0-100]: 40
Постарайтесь лучше!
Введите число [0-100]: 85
A
Введите символ [+ - / *]: +
1+2=3

Условный оператор: Условный оператор - это тернарный (с тремя операндами) оператор, в форме booleanExpr? trueExpr : falseExpr. В зависимости от booleanExpr он вычисляет и возвращает значение trueExpr или falseExpr.
// возвращает либо "ПРОЙДЕН" либо "НЕ ПРОЙДЕН", и выводит в cout
cout << (mark >= 50)? "ПРОЙДЕН" : "НЕ ПРОЙДЕН" << endl;
max = (a > b)? a : b; // правая часть возвращает a или b
abs = (a > 0)? a : -a; // правая часть возвращает a или -a
Скобки: Вы можете опустить фигурные скобки { }, если в блоке есть только одна инструкция. Например,
if (mark >= 50)
cout << "ПРОЙДЕН" << endl; // Только одна инструкция, можно опустить { }, но не рекомендуется
else { // несколько инструкций, нужны { }
cout << "НЕ ПРОЙДЕН" << endl;
cout << "Постарайтесь лучше!" << endl;
}
Однако мы рекомендуем оставлять фигурные скобки, даже если в блоке есть только одна инструкция, чтобы повысить читаемость вашей программы.
Опять-таки, существуют несколько типов циклов: for-цикл, while-do, и do-while.
// for-цикл
int sum = 0;
for (int number = 1; number <= 100; ++number) {
sum += number;
}
// while-do
int sum = 0, number = 1;
while (number <= 100) {
sum += number;
++number;
}
// do-while
int sum = 0, number = 1;
do {
sum += number;
++number;
} while (number <= 100);
Запросить у пользователя верхнюю границу. Посчитать сумму целых чисел от 1 до заданной верхней границы и вычислить их среднее значение.
/*
* Сумма от 1 до заданной верхней границы и вычисление их среднего значения.
*/
#include <iostream>
using namespace std;
int main() {
int sum = 0; // Сохраняет накопленную сумму
int upperbound;
cout << "Введите верхнюю границу: ";
cin >> upperbound;
// Сумма от 1 до верхней границы
for (int number = 1; number <= upperbound; ++number) {
sum += number;
}
cout << "Сумма равна " << sum << endl;
cout << "Среднее значение равно " << (double)sum / upperbound << endl;
// Сумма только нечетных чисел
int count = 0; // Количество нечетных чисел
sum = 0; // Сброс суммы
for (int number=1; number <= upperbound; number=number+2) {
++count;
sum += number;
}
cout << "Сумма нечетных чисел равна " << sum << endl;
cout << "Среднее значение равно " << (double)sum / count << endl;
}
Вывод:
Введите верхнюю границу: 15
Сумма равна 120
Среднее значение равно 8
Сумма нечетных чисел равна 64
Среднее значение равно 8

Инструкция break прерывает и выходит из текущего (самого вложенного) цикла.
Инструкция continue прерывает текущую итерацию и продолжает следующую итерацию текущего (самого вложенного) цикла.
break и continue - это плохие структуры, так как они трудно читать и понять. Используйте их только в крайних случаях. Вы всегда можете написать ту же программу без использования break и continue.
Следующая программа выводит составные числа между 2 и верхней границей.
/*
* Выводит составные числа от 1 до верхней границы.
*/
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int upperbound;
cout << "Введите верхнюю границу: ";
cin >> upperbound;
for (int number = 2; number <= upperbound; ++number) {
// Не является простым, если есть делитель между 2 и sqrt(number)
int maxFactor = (int)sqrt(number);
for (int factor = 2; factor <= maxFactor; ++factor) {
if (number % factor == 0) { // Делитель?
cout << number << " ";
break; // Найден делитель, нет необходимости искать больше делителей
}
}
}
cout << endl;
return 0;
}
Вывод:
Введите верхнюю границу: 20
4 6 8 9 10 12 14 15 16 18 20

Перепишем вышеуказанную программу, чтобы вывести все простые числа. Для этого используется флаг boolean под названием isPrime, который указывает, является ли текущее number простым числом. Затем он используется для управления печатью.
/*
* Выводит простые числа от 1 до верхней границы.
*/
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int upperbound;
cout << "Введите верхнюю границу: ";
cin >> upperbound;
for (int number = 2; number <= upperbound; ++number) {
// Не является простым, если есть делитель между 2 и sqrt(number)
int maxFactor = (int)sqrt(number);
bool isPrime = true; // Флаг boolean, указывающий, является ли number простым числом
for (int factor = 2; factor <= maxFactor; ++factor) {
if (number % factor == 0) { // Делитель?
isPrime = false; // number не является простым числом
break; // Найден делитель, нет необходимости искать больше делителей
}
}
if (isPrime) cout << number << " ";
}
cout << endl;
return 0;
}
Вывод:
Введите верхнюю границу: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

Изучите следующую программу, использующую break и continue.
/* A mystery series */
#include <iostream>
using namespace std;
int main() {
int number = 1;
while (true) {
++number;
if ((number % 3) == 0) continue;
if (number == 53) break;
if ((number % 2) == 0) {
number += 3;
} else {
number -= 3;
}
cout << number << " ";
}
cout << endl;
return 0;
}
Вывод:
5 4 2 7 11 10 8 13 17 16 14 19 23 22 20 25 29 28 26 31 35 34 32 37 41 40 38 43 47 46 44 49 53 52

Существует несколько способов завершения программы до достижения конца программных инструкций.
exit(): Вы можете вызвать функцию exit(int exitCode) из <cstdlib> (портированной из C's "stdlib.h"), чтобы завершить программу и вернуть управление операционной системе. По соглашению, возвратный код 0 указывает на нормальное завершение; в то время как не нулевой exitCode (-1) указывает на аномальное завершение. Например,
abort(): Заголовочный файл <cstdlib> также предоставляет функцию abort(), которая может быть использована для аномального завершения программы.
if (errorCount > 10) {
cout << "слишком много ошибок" << endl;
exit(-1); // Завершить программу
// ИЛИ abort();
}
Следующая диаграмма иллюстрирует вложенный for-цикл, то есть внутренний for-цикл внутри внешнего for-цикла.

/*
* Выводит треугольную фигуру.
*/
#include <iostream>
using namespace std;
int main() {
int size = 8;
for (int row = 1; row <= size; ++row) { // Внешний цикл для вывода всех строк
for (int col = 1; col <= size-row+1; ++col) { // Внутренний цикл для вывода всех столбцов каждой строки
cout << "## ";
}
cout << endl; // Строка завершена, перемещаем курсор на следующую строку
}
return 0;
}
Вывод:
## ## ## ## ## ## ## #
## ## ## ## ## ## #
## ## ## ## ## #
## ## ## ## #
## ## ## #
## ## #
## #
#

Следующая конструкция часто используется:
while (true) { ...... }
Это, казалось бы, бесконечный цикл (или вечный цикл), но обычно он завершается с помощью инструкции break или return внутри тела цикла. Этот вид кода трудно читать - избегайте его, если возможно, переписав условие.
В этом разделе мы рассмотрели три управляющие конструкции. Они очень полезны. Вы можете комбинировать их между собой. Будьте осторожны с циклами, проверяйте условия завершения, чтобы избежать бесконечных циклов.