|
Оператор цикла for
Оператор цикла for
Лабораторная Работа На тему: ОПЕРАТОР ЦИКЛА for ОПЕРАТОР ЦИКЛА for 1. Назначение и синтаксис В компьютерных программах часто возникает необходимость выполнения определенного набора операторов заданное число раз, (или, иначе, до тех пор, пока выполнено некоторое условие). Такие алгоритмы реализуются с помощью циклов. Под циклом будем понимать повторяющееся действие (или набор действий), организованное с помощью структуры, управляемой счетчиком. Рассмотрим это на следующем простом примере. Пример 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 argsusedint 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, 2] с шагом /180for(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 argsusedint main(int argc, char* argv[]){float d, a0, ak; // вещественные d, a0, akint k, N; // целочисленные k, Ncout<<"Vvedite N = "; // вводим с клавиатуры исходныеcin>>N; // значения - N, a0, dcout<<"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. вычисляем aksum = sum + ak; // 2. добавляем ak к sumcout<<"shag "<<k<<": ak=" // 3. выводим на экран<<ak<<",S="<<sum<<endl;} // окончание тела циклаcout<<"Summa - "<<sum; // результат на экранgetch();return 0;}//-----------------------------------------------Наберите и откомпилируйте код этой программы. Исследуйте результаты ее работы. Изобразите блок-схему и объясните алгоритм работы этого приложения.3. Вложенные операторы циклаАналогично операторам условия if-else, циклы for могут быть вложены друг в друга, причем степень «вложенности» также может быть произвольной. В качестве счетчиков такие циклы, как правило, используют различные переменные. Основное применение вложенных циклов в компьютерных программах связано с перебором значений в нескольких измерениях (то есть нескольких координат). В качестве примера рассмотрим задачу о расчете значений функции 2-х переменных внутри квадрата х[-, ], y[-, ] с шагом /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; } //---------------------------------------------
|
|