Вложенные операторы цикла




Лабораторная Работа

 

На тему: ОПЕРАТОР ЦИКЛА for


ОПЕРАТОР ЦИКЛА for

Назначение и синтаксис

 

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

Пример 1. Напишите программу, выводящую на экран все целые числа от 0 до 99, включительно.

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

 

Вариант 1 1. Объявляем целочисленную переменную k и инициализируем ее значением 0. 2. Выводим на экран k. 3. Увеличиваем k на единицу. 4. Если k меньше 100, возвращаемся к пункту 2. 5. Завершаем программу.   Вариант 2 1. Объявляем целочисленную переменную k и инициализируем ее значением 0. 2. Если k меньше 100, переходим к следующему пункту, иначе завершаем программу. 3. Выводим на экран k. 4. Увеличиваем k на единицу. 5. Возвращаемся к пункту 2.  

 

Блок-схемы этих алгоритмов изображены ниже.

Цикл с постусловием Цикл с предусловием

 

Несмотря на то, что результат работы обоих алгоритмов одинаков, существует различие в их организации. Различие связано с расположением условия продолжения цикла: в первом случае проверка происходит после того, как выполнен очередной шаг; во втором – перед очередным шагом. В соответствии с этим, предложенные алгоритмы называются циклом с пост-условием и циклом с пред-условием, соответственно. Переменную k будем называть счетчиком цикла, а повторяющиеся в цикле операторы – телом цикла.

В С++ существует несколько языковых конструкций для организации циклов. В настоящей работе мы рассматриваем цикл for, который иногда также называют итерационным циклом.

Общий формат его записи

for( <инициализация>; <условие_продолжения>;<изменение_счетчика> )

{

<блок операторов>;

}

Цикл for начинается с выполнения блока <инициализации>, где, как правило, определяется начальное значение счетчика цикла. Далее следует проверка <условия_продолжения>, и в случае, если это условие истинно, целиком выполняется <блок_операторов> в теле цикла.

 

 

На этом завершается первый шаг цикла, и управление вновь передается заголовку for, который производит <изменение_счетчика>. Следующий шаг также будет включать в себя проверку <условия_продолжения> и, в случае его истинности, последовательное выполнение операторов тела цикла. Циклическое повторение будет продолжено до тех пор, пока <условие_продолжения> не станет ложным. На этом выполнение цикла прекращается, и управление передается следующему оператору за пределами тела цикла for.

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

В качестве примера использования этой конструкции, рассмотрим листинг программы, решающей сформулированную выше задачу о выводе на экран всех целых чисел от 0 до 99.

 

//----------- Вывод значений в цикле ------------

 

#pragma hdrstop

#include <iostream.h>

#include <conio.h>

 

#pragma argsused

int main(int argc, char* argv[])

{

int k; // объявляем переменную-счетчик

for(k=0; k<100; k=k+1) // цикл по k от 0 до 99 с шагом 1

{

cout<<k<<endl; // тело цикла: вывод на экран k

}

getch(); // задержка

return 0;

}

//-----------------------------------------------

 

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

В приведенном примере переменная-счетчик k объявлена в программе отдельной записью int k. Однако C++ также допускает объявление счетчика непосредственно в заголовке цикла

 

for(int k=0; k<100; k=k+1)

{

cout<<k<<endl;

}

 

В Turbo C++ такая переменная будет действительна и видна только внутри цикла for, тогда как область действия переменной k из примера выше распространяется до конца программы.

В качестве счетчика цикла может использоваться не только целочисленная, но и вещественная переменная. Шаг изменения счетчика также может быть любым, в том числе дробным и отрицательным. К примеру, следующий фрагмент кода выводит на экран значения функции sin(x) на интервале [0, 2p] с шагом p/180

 

for(float x=0; x<2*M_PI; x=x+M_PI/180)

{

cout << x << ” ” << sin(x) << endl;

}

 

Аналогично if-else, операторы в теле цикла for (внутри фигурных скобок) принято смещать на несколько позиций вправо для улучшения читаемости программного кода.


2. Сокращенные варианты записи

 

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

for( <инициализация>; <условие_продолжения>;<изменение_счетчика> )

оператор;

Отдельные (или все) блоки в заголовке цикла for могут быть пустыми, однако разделительные точки с запятой являются обязательными. К примеру, запись

for(;;;)

{

<операторы>;

}

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

for(;;;)

{

<операторы>;

if(<условие>) break;

}

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

Стандартная запись Описание Сокращенная запись Пример использования
A = A + 1; увеличить значение переменной A на 1 A++; i++;
A = A – 1; уменьшить значение переменной A на 1 A--; index--;
A = A + B; увеличить значение A на величину B A += B; x += 0.1;
A = A – B; уменьшить значение A на величину B A -= B; result -= 10;
A = A * C; увеличить значение A в C раз A *= C; R *= rs;
A = A / D; уменьшить значение A в D раз A /= D; S /= 10.;

 

В частности, записи

k = k + 1;

k++;

k += 1;

 

в программе являются эквивалентными, и означают одно и то же действие – увеличение значения k на единицу.

Пример 2. Рассчитайте сумму слагаемых ряда . Заданными считаются: 1-е слагаемое a0, и рекуррентное соотношение, связывающее k-е слагаемое ak с предыдущим (k-1)-м слагаемым ak-1 в виде (арифметическая прогрессия). Значения вводятся с клавиатуры.

Решение. Будем использовать вспомогательную переменную ak для хранения значения очередного члена ak, и переменную sum для вычисления суммы. Расчет организуем с помощью цикла for, в котором будем последовательно вычислять значение ak, прибавлять его к sum и выводить на экран текущую информацию (номер шага k, значение очередного слагаемого, текущую сумму).


//-------------- Расчет суммы ряда --------------

 

#pragma hdrstop

#include <iostream.h>

#include <conio.h>

 

#pragma argsused

int main(int argc, char* argv[])

{

float d, a0, ak; // вещественные d, a0, ak

int k, N; // целочисленные k, N

 

cout<<"Vvedite N = "; // вводим с клавиатуры исходные

cin>>N; // значения - N, a0, d

cout<<"Vvedite a0 = ";

cin>>a0;

cout<<"Vvedite d = ";

cin>>d;

 

float sum = 0; // вспомогательная переменная

for(k=0; k<=N; k++) // цикл по k от 0 до N

{ // начало тела цикла

ak = a0 + d*k; // 1. вычисляем ak

sum = sum + ak; // 2. добавляем ak к sum

cout<<"shag "<<k<<": ak=" // 3. выводим на экран

<<ak<<",S="<<sum<<endl;

} // окончание тела цикла

cout<<"Summa - "<<sum; // результат на экран

getch();

return 0;

}

//-----------------------------------------------

 

Наберите и откомпилируйте код этой программы. Исследуйте результаты ее работы. Изобразите блок-схему и объясните алгоритм работы этого приложения.

Вложенные операторы цикла

 

Аналогично операторам условия if-else, циклы for могут быть вложены друг в друга, причем степень «вложенности» также может быть произвольной. В качестве счетчиков такие циклы, как правило, используют различные переменные.

Основное применение вложенных циклов в компьютерных программах связано с перебором значений в нескольких измерениях (то есть нескольких координат). В качестве примера рассмотрим задачу о расчете значений функции 2-х переменных внутри квадрата хÎ[-p, p], yÎ[-p, p] с шагом p/8 по обеим сторонам. Задача может быть решена программно с помощью вложенных циклов, как показано ниже (приведен только фрагмент)

 

for(float x=-M_PI; x<M_PI; x+=M_PI/8)

for(float y=-M_PI; y<M_PI; y+=M_PI/8)

cout << x << ” ”<< y << ” ” << exp(-x)*sqrt(y) << endl;

 

Здесь внешний цикл перебирает все значения x-координаты точки, и запускает вложенный в него цикл по y-координатам. Во внутреннем цикле искомые значения функции выводятся на экран.

Рассмотрим еще один пример использования вложенных циклов.

Пример 3. На пустой шахматной доске находится черный ферзь в позиции (n,m). Найдите все возможные положения белого короля, в которых он не находится под ударом. Текущие координаты ферзя вводятся с клавиатуры.

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

 

· k!= n – нет атаки по вертикали

· l!= m – нет атаки по горизонтали

· l - k!= m - n – нет атаки по диагонали «северо-восток»

· l + k!= m + n – нет атаки по диагонали «северо-запад»

 

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

Ниже приведен листинг программы, решающей поставленную задачу

 

//------------ Шахматная задача 2--------------

 

#pragma hdrstop

#include <iostream.h>

#include <conio.h>

 

#pragma argsused

int main(int argc, char* argv[])

{

int n, m, k, l, num = 0;

 

cout << "Enter black queen position:" << endl;

cout << " colunm n = ";

cin >> n;

cout << " row m = ";

cin >> m;

 

cout << endl << "Safe white king positions:" << endl;

for(k=1; k<=8; k++) // цикл по столбцам

{

for(l=1; l<=8; l++) // цикл по строкам

{

if((k!=n)&&

(l!=m)&&

(l-k!=m-n)&&

(l+k!=m+n)) // если все условия выполнены

{ // выводим позицию (k,l) на экран

cout << "(" << k << "," << l << ")" << endl;

num++; // и увеличиваем счетчик на 1

}

} // конец цикла по строкам

} // конец цикла по столбцам

cout << "number of safe positions - " << num;

getch();

return 0;

}

//---------------------------------------------



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2021-04-20 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: