Циклы в языке программирования с++

При выполнении программы нередко возникает необходимость неоднократного повторения однотипных вычислений над различными данными. Для этих целей используются циклы. Операторы цикла используются для организации многократно повторяющихся вычислений.Любой цикл состоит из тела цикла, то есть тех операторов, которые выполняются несколько раз, начальных установок, блока модификации параметра цикла и проверки условия выхода из цикла, которая может размещаться либо до тела цикла (тогда говорят о цикле с предусловием), либо после тела цикла (цикл с постусловием).В теории программирования различают два вида циклов:

  • арифметические;
  • итерационные;

Арифметические или счетные циклы – циклы с управляющей переменной (счетчиком или параметром цикла). Выполняется известное число раз.

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

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

Для их организации в С++ используются три вида операторов: while (цикл с предусловием), for (цикл со счетчиком), do-while (цикл с постусловием).

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

Цикл с предусловием реализует структурную схему и имеет вид:

while (выражение) оператор;

Выражение определяет условие повторения тела цикла, представленного простым или составным оператором. Если выражение не равно 0 (истинно), выполняется оператор цикла, после чего опять вычисляется выражение. Если при первой проверке выражение равно 0, цикл не выполнится ни разу. Тип выражения должен быть арифметическим или приводимым к нему.

Пример реализации цикла с предусловием – программа печатает таблицу значений функции y=x2+1 во введенном диапазоне:

#include <iostream>

#include <windows.h>

using namespace std;

int main()

{

setlocale(LC_ALL,»Rus»);

float Xn, Xk, Dx;

cout << » Введите диапазон и шаг изменения аргумента: «;

cin >> Xn >> Xk >> Dx;

cout << «| X | Y |\n»;

float X = Xn;

while (X <= Xk)

{

cout << » | «<< X <<» | «<< X*X + 1 << » | \n»;

X += Dx;

}

return 0;

}

Цикл с постусловием реализует структурную схему и имеет вид:

do оператор while (выражение);

Сначала выполняется простой или составной оператор, составляющий тело цикла, а затем вычисляется выражение. Если оно не равно 0 (истинно), тело цикла выполняется еще раз, и так далее, пока выражение не станет равным нулю или в теле цикла не будет выполнен какой-либо оператор передачи управления. Тип выражения должен быть арифметическим или приводимым к нему.

Пример реализации цикла с постусловием:

Игра «Купи слона»

#include <iostream>

#include <windows.h>

using namespace std;

int main()

{

setlocale(LC_ALL,»Rus»);

SetConsoleCP(1251);

SetConsoleOutputCP(1251);

char answer[20];

cout << «\n Купи слона! «;

cin >> answer;

do

{

cout << «\n Все говорят » << answer << » а ты купи слона! «;

cin >> answer;

}

while (answer != «ok»);

}

Цикл с параметром имеет следующий формат:

for (инициализация; выражение; модификации) оператор;

Инициализация используется для объявления и присвоения начальных значений величинам, используемым в цикле. В этой части можно записать несколько операторов, разделенных запятой. Выражение определяет условие выполнения цикла: если оно не равно 0 (истинно), цикл выполняется.

Модификации выполняются после каждой итерации цикла и служат обычно для изменения параметров цикла. В части модификаций можно записать несколько операторов через запятую. Простой или составной оператор представляет собой тело цикла. Любая из частей оператора for может быть опущена (но точки с запятой необходимо оставить на своих местах).

Пример реализации цикла с параметром:

Оператор, вычисляющий сумму чисел от 1 до 100.

for (int i = 1, s = 0; i<=100; i++) s += i;

В предыдущем примере есть одна особенность – вводимая в качестве счетчика переменная i. Данная переменная является локальной и память под нее выделяется только в момент использования цикла.

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

Сначала необходимо решить, нужен ли цикл с предусловием или с постусловием. Чаще всего всего возникает необходимость в цикле с предусловием. По оценкам специалистов, в среднем циклы с постусловием составляют 5% от общего числа используемых циклов. Во многом использование циклов с предусловием объясняется следующим принципом: цикл с предусловием используется в том случае, когда до его непосредственного использования требуется проверка переменной, цикл с постусловием используется, когда необходимо провести хотя бы один его шаг до непосредственной проверки.

Вложенными циклами называют конструкции, в которых один цикл выполняется внутри другого. Внутренний цикл выполняется полностью во время каждой итерации внешнего цикла. В программе можно использовать любые комбинации вложенных циклов всех типов: while, for, do-while, если этого требует логика построения кода.

Например, требуется заполнить экран символами «#». Возможный вариант решения имеет вид:

for (i=1; i<=25; i++)

for (k=1; k<=80; k++) cout << ‘#’;

В результате выполнения данной программы 25 раз осуществляется вывод по 80 символов.

В С++ есть несколько операторов, изменяющих естественный порядок выполнения вычислений:

  • оператор безусловного перехода goto;
  • оператор выхода из цикла break;
  • оператор перехода к следующей итерации цикла continue;
  • оператор возврата из функции return.

Оператор goto

Оператор безусловного перехода goto имеет формат:

goto метка;

В теле той же функции должна присутствовать ровно одна конструкция вида:

метка: оператор;

Оператор goto передает управление на помеченный оператор. Метка – это обычный идентификатор, областью видимости которого является функция, в теле которой он встречается. Использование оператора безусловного перехода оправдано в двух случаях:

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

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

  • не входить внутрь блока извне;
  • не входить внутрь условного оператора;
  • не входить извне внутрь переключателя;
  • не передавать управление внутрь цикла.

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

#include <iostream>

#include <cmath>

#include <windows.h>

using namespace std;

int main(){

setlocale(LC_ALL,»Rus»);

int a=0,b;

st:

cout<<«Число на данный момент равно «<<a<<endl;

cout<<«Список команд:\n1 — Прибавить один\n2 — Отнять один\n3 — Умножить на два\n4 — Взять квадрат числа\n5 — Выход\n\n»;

cout<<«Введите команду\n»;

cin>>b;

switch(b){

case 1: a++; cout << «Число увеличено на единицу\n»; goto st; break;

case 2: a—; cout << «Число уменьшено на единицу\n»; goto st; break;

case 3: a*=2; cout << «Число уменьшено вдвое\n»; goto st; break;

case 4: a*=a; cout << «Число возведено в квадрат\n»; goto st; break;

case 5: cout << «Вы вышли из системы\n»; goto nd;;

default: cout << «Введена неверная команда\n»; goto st;

}

nd:

cout<<«Результат равен «<<a<<endl;

return 0;

}

Оператор выхода из цикла break обеспечивает переход на оператор, непосредственно следующий за оператором if, switch или цикла, внутри которых находится оператор break.

Примером использования оператора break может быть программа вычисления значения гиперболического синуса вещественного аргумента х с заданной точностью eps с помощью разложения в бесконечный ряд: sh x = 1 + x3/3! + x5/5! + x7/7! + …

#include <iostream>

#include <cmath>

#include <windows.h>

using namespace std;

int main()

{

setlocale(LC_ALL,»Rus»);

const int MaxIter = 500;

double x, eps;

cout << «\n Введите аргумент и точность: «;

cin >> x >> eps;

bool flag = true;

double y = x, ch = x;

for (int n = 0; fabs(ch) > eps; n++)

{

ch *= x * x /(2 * n + 2)/(2 * n + 3);

y += ch;

if (n > MaxIter)

{

cout << «\n Ряд расходится!»;

flag = false; break;

}

}

if (flag) cout << «\n Значение функции: » << y;

}

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

Оператор перехода к следующей итерации цикла continue пропускает все операторы, оставшиеся до конца тела цикла, и передает управление на начало следующей итерации. Например, необходимо найти количество символов ‘a’ в тексте. При использовании языка С++ данная задача решается следующим образом:

#include <iostream>

#include <stdlib.h>

#include <string.h>

#include <windows.h>

#include <unistd.h>

using namespace std;

int main()

{

setlocale(LC_ALL,»Rus»);

SetConsoleCP(1251);

SetConsoleOutputCP(1251);

int i,n=0;

char string[100];

system(«cls»);

cout<<«Введите строку: «;

gets(string);

printf(«Была введена строка: %s длиной %d»,string, strlen(string));

for(i=0;i<=strlen(string)-1;i++)

{

if (string[i]==’а’)

{

n++; continue;

}

}

cout<<«\nВ вашей строке «<<n<<» символa(ов) ‘a'»;

sleep(2000);

return 0;

}

Оператор return

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

float cube(float z) {return z*z*z;}

Выражение в операторе return не может присутствовать в том случае, если возвращаемое функцией значение имеет тип void. Например следующая функция выводит на экран дисплея, связанный с потоком cout, значение третьей степени своего аргумента и не возвращает в точку вызова никакого значения:

void cude_print(float z)

{

cout<<«\t cube = «<<z*z*z; // В данном примере оператор возврата из функции не содержит выражения.

return;

}

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

while (true) {…}

или в случае цикла for:

for ( ; ; ) {…}

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

for ( ; a <=10; )

не будет отличаться от цикла

while (a<=10)

ни его поведением,, ни типовыми особенностями.

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

bool flag = true;

while (flag)

{

a++;

if (a >=20) flag = false;

}