- •1. Краткие теоретические сведения
- •1.1. Понятие циклического вычислительного процесса
- •1.2. Типовая блок-схема организация цвп
- •1.3. Классификация цвп
- •Повторений и специальной переменной - счетчиком циклов
- •1.4. Общие сведения об операторах цикла
- •1. Оператор while:
- •2. Оператор do…while:
- •3. Оператор for:
- •1.5. Оператор цикла типа "прогрессия" for
- •1.6. Основные правила и порядок выполнения оператора цикла for:
- •Оператор цикла со спецификацией, заданной скалярным выражением
- •1.7. Оператор цикла while
- •1.5.4.1. Оператор цикла while
- •1.5.4.3. Оператор цикла while
- •1.5.5.4. Оператор цикла while
- •1. Цикл с предусловием:
- •1.5.5.5. Основные правила использования и порядок выполнения оператора цикла while:
- •1.5.5.6. Пример № 1
- •1.8. Оператор цикла do...While
- •1.5.5.1. Оператор цикла do while
- •1.5.5.2. Оператор цикла с постусловием do
- •1.5.5.3. Оператор цикла do while
- •1.5.5.4. Оператор цикла do-while
- •2. Цикл с постусловием:
- •1.9. Табулирование функций
- •1.10. Вычисление конечных сумм и произведений
- •1.11. Правила организации циклических алгоритмов
- •1.12. Операторы перехода и их использование в циклах
- •1.12.1. Оператор прерывания циклов break
- •1.Break – оператор прерывания цикла.
- •1.12.2. Оператор перехода к следующей итерации цикла continue
- •Оператор продолжения continue для циклов do, while, for
- •1.12.3. Оператор перехода goto
- •1.12.4. Оператор возврата из функции return
- •Замечание:
- •2. Задание
- •2.1. Изучить теоретические сведения
- •2.4. Задания для выполнения на занятиях
- •2.4.1. Задание 1. Табуляция неразветвляющейся функции
- •2.4.1.1. Условие задания
- •Варианты заданий
- •2.4.2. Задание 2. Табулирование разветвляющейся функции
- •2.4.2.1. Условие задания
- •2.4.3. Задание 3. Табулирование разветвляющейся функции
- •2.4.3.1. Условие задания
- •2.5. Задания для дома
- •2.5.1. Задание 1. Табулирование неразветвляющейся функции в равноотстоящих точках
- •2.5.1.1. Условие задания
- •2.5.2. Задание 2. Табулирование разветвляющейся функции в равноотстоящих точках
- •2.5.2.1. Условие задания
- •2.5.2.2.Пример программы табулирования функции
- •3. Выводы
- •4. Требование к отчету
- •4. Краткие теоретические сведения.
- •5. Вопросы для самоконтроля
- •Литература
- •1. Краткие теоретические сведения 2
- •1.1. Понятие циклического вычислительного процесса 2
1.6. Основные правила и порядок выполнения оператора цикла for:
1. До начала выполнения тела цикла выполняется один раз список p1.
2. Выполняются операторы и выражения списка p2; производится анализ полученного значения последнего выражения из p2 (в дальнейшем p2):
еслиp2 истинно (!=0), то тело цикла выполняется;
если p2 ложно (==0), то тело цикл завершается;
если p2 ложно (==0) до первого выполнения тела цикла, то тело цикла не выполняется ни разу.
3. После выполнения рабочей части цикла выполняются операторы и выражения p3 и осуществляется переход к п. 2) данных правил.
4. Появление в любом месте тела цикла оператора continue вызывает переход к выполнению списка p3, п. 3) данных правил.
5. Появление в любом месте тела цикла оператора break вызывает переход к оператору, следующему после оператора цикла, т. е. осуществляется выход из цикла. При этом параметр цикла сохраняет то значение, при котором произошло завершение выполнения цикла.
6. После нормального завершения цикла значение параметра цикла равно значению, которое привело к завершению цикла.
Пример 7.10
for (i=1; i<5; i++); printf ( "i=%d\n",i);
Приведен цикл, не содержащий тела цикла, так как сразу после заголовка цикла стоит символ ";" (тело цикла - пустой оператор), и оператор вывода значения i. Выполнение цикла завершится при i=5. Значение 5 и будет выведено.
7. Если в заголовке цикла отсутствует список p1 и/или p2 и/или p3, то символы ";" должны остаться. Например,
for ( ; ;); //Бесконечный цикл
for (i=1; ; i++); //Бесконечный цикл for (i=1; i<5 ;); //Бесконечный цикл
Примечание. Использование в заголовке цикла посторонних вычислений считается плохим стилем. Следует использовать заголовок цикла for для операций по управлению циклом.
Пример 7.11
Вычислить и вывести степени двойки - значения 2n для n=1, 2, k (k>1).
Решение. Пусть x - искомые значения. Положим x=1. Тогда первая степень двойки x равна х*2, что равно 21. Если положить х=х*2, то вторая степень двойки есть х*2, что равно 22. И так далее. Т. о., степени двойки от первой до к-ой можно вычислить, выполнив к раз рекуррентное соотношение х=х*2, положив предварительно х=1. Реализовать такой алгоритм можно с использованием цикла с параметром и с предусловием. Графическая схема алгоритма, программа на языке С++, результаты выполнения программы при к=15 изображены на рис. 2.1 10.1(стр 41). Параметр цикла i (степень двойки) принимает значения 1, 2, ., к, следовательно, является счетчиком.
Пример 7.12
Вычислить сумму элементов арифметической прогрессии
Покажем, как задача решается с использованием цикла for.
int main ()
{
int n, Sum = 0;
int i;
printf ("\nВведите число элементов прогрессии \n");
scanf ("%d", &n);
for ( i = 1; i <= n; i ++)
Sum += i;
printf("Сумма арифметической прогрессии %d", Sum);
}
Особенности выполнения оператора for .
1. Управляющая переменная цикла for не обязательно целого типа, она может быть вещественной или символьной.
Пример 7.13
Вычислить сумму геометрической прогрессии
, где i изменяется по закону i — = i * 1,1.
int main ()
{
float Sum = 1, i;
for (i = 1.; i <= 2.; i *= 1.1)
Sum += i;
printf("\nСумма геометрической прогрессии %f", Sum);
}
2. Любое из трех выражений, любые два, или все могут отсутствовать, но разделяющие из символы «;» опускать нельзя. Если «выражение2» отсутствует, то считается, что оно истинно, и цикл превращается в бесконечный, для выхода из которого необходимы специальные средства. Бессмысленно использовать несколько «выражений2», так как управление выполняется по первому условию.
3. Оператор цикла for удобен тем, что интегрирует в заголовке описание всего процесса управления. Тело цикла, в общем случае, блок. Поскольку начальных присваиваний и выражений приращения может быть несколько, весь цикл, вместе с телом, может быть записан одной строкой. Например, тот же цикл в стиле С может выглядеть так:
for ( Sum = 0, i = 1; i <= n; Sum +=i ++);
Здесь два начальных присваивания, и тело цикла записано в его заголовке.
Пример 7.14
С помощью оператора for вывести таблицн кодов ASCII символов
char ch;
for(ch = 'a'; ch <= 'z'; ch++)
printf("Значение ASCII для %c - %d.\n",ch,ch);
В данном примере в качестве счетчика цикла выступает переменная ch, которая инициализируется символом 'a'. Это означает, что в переменную ch заносится число 97 - код символа 'a'. Именно так символы представляются в памяти компьютера. Код символа 'z' - 122, и все малые буквы латинского алфавита имеют коды в диапазоне [97; 122]. Поэтому, увеличивая значение ch на единицу, получаем код следующей буквы, которая выводится с помощью функции printf(). Учитывая все вышесказанное, этот же пример можно записать следующим образом:
for(char ch = 97; ch <= 122; ch++)
printf("Значение ASCII для %c - %d.\n",ch,ch);
Здесь следует отметить, что переменная ch объявлена внутри оператора for. Это особенность языка С - возможность объявлять переменные в любом месте программы.
Существует много особенностей реализации данного оператора, отметим основные из них, которые могут заметно повысить скорость написания программ. Следующим примером продемонстрируем особенности изменения значения счетчика цикла.
int line_cnt = 1;
double debet;
for(debet = 100.0; debet < 150.0; debet = debet*1.1, line_cnt++)
printf("%d. Ваш долг теперь равен %.2f.\n",line_cnt, debet);
Следующий фрагмент программы демонстрирует возможность программирования сложного условия внутри цикла.
int exit = 1;
for(int num = 0;num < 100 && !exit; num += 1)
{
scanf("%d",&mov); if(mov == 0) exit = 0;
printf("Произведение num*mov = %d.\n",num*mov);
}
Оператор for с одним условием:
int i=0;
for(;i < 100;) i++;
и без условия
int i=0;
for(;;;) {i++; if(i > 100) break;}
В последнем примере оператор break служит для выхода из цикла for, т.к. он будет работать «вечно» не имея никаких условий.
Примеры использования цикла с параметром.
1. Уменьшение параметра:
for ( n=10; n>0; n--)
( <тело цикла>};
2. Изменение шага корректировки
for ( n=2; n>60; n+=13)
{ <тело цикла>};
3. Проверка условия отличного от того, которое налагается на число итераций
for ( num=l;num*num*num<216; num++)
{ <тело цикла>};
4. Коррекция с помощью умножения
for ( d=100.0; d<150.0;d*=1.1)
for ( d=100.0; d<150.0;d*=l.l)
{ <тело цикла>};
5. Коррекция с помощью арифметического выражения
for (х=1;у<=75;у=5*(х++)+10)
{ <тело цикла>};
6. Использование нескольких инициализирующих или корректирующих выражений, тело цикла отсутствует
for (x=1, y=0; x<10;x++;y+=x);
Пример 7.15
Функция F(x) может быть достаточно сложной, тогда в теле цикла нужно позаботиться о правильной записи блока, вычисляющего функцию. Пусть для x ∈ [–π/2;+π/2] требуется вычислить таблицу значений функции, имеющей разрыв в точках | x | = π/4, по формуле
// Код программы примера 7.15
#include <stdio.h>
#include <math.h>
// В библиотеке math.h определена константа M_PI – значение числа π.
int main ()
{
float x, y; // Аргумент и значение функции.
printf ("\n Таблица значений функции\n");
printf ("------------------------------------\n");
printf (" x y \n");
printf ("------------------------------------\n");
// x – параметр цикла, в заголовке цикла for задано полное управление.
for ( x = – M_PI/2.; x < = M_PI/2.; x += 0.2 ) // Цикл вычисления таблицы.
{ // Блок вычисления значения функции использует оператор if.
if (fabs (x) <= M_PI/4.) // Логическая запись формулы вычисления.
y = sin(x);
else
y = cos(x);
printf ("%11.2f %11.2f\n" ,x, y); // Вывод строки таблицы.
}
} // End of main
Пример 7.16
Вычислить функцию (7.1) с использованием оператора цикла со спецификацией типа арифметической прогрессии (см. пример 7.5).
При использовании указанной формы оператора for для нашего примера имеем:
for (x =0; x <2.01; x += 0.1 )
{
z= (a*x*x+b)/c;
y=atan(sqrt(z)+log(z));
cout << "x= " << x << " y= " <<y << endl;
}
В данном примере в качестве управляющей переменной используется аргумент функции, вычисляемой в цикле, а в качестве выражений р1, р2, р3 взяты константы, как частный случай выражений.
Пример 7.17.
Используя оператор цикла со специфичней типа арифметической прогрессии описать алгоритм, представленный на рис. 7.2,а (см. пример 7.4).
Программа, реализующая циклические вычисления площади поверхности и объема шара может иметь вид:
int main()
float R, RM, DR, PT, S, V;
cout << "Введите DR, RM: "; cin >> DR >> RM;
float PI=3.14159;
for (R =0; R <RM; x += DR)
{
S=4*PI*R*R;
V=S*R/3;
cout << "R= " << R << " S= " <<S << " V= " <<V << endl;
{
Пример 7.18 (5.6)
Вычислить значения В„ во формула
для -1,5 б х ^1,5 и 4** 0,1.
Для случая х « ±1 (когда знаменатель дроби равен нулю) положить Вк - 0.
Фрагмент программы, реализующий циклические вычисления данного выражеиия, может иметь вид:
Нетрудно убедиться, что выбор константы 0,1 для проверки условия (х2 - 1) > 0,1 вместо х2 – 1 =0 достигает цели. Для этого достаточно, например, проанализировать значения л •*( - 1" ) для х в окрестности х ■ I яри заданном шаге:
х ! |
й. ! |
0,1 |
1 х ! |
А 1 |
-ОД |
|
. ■—. |
|
+ 1,0 |
0 |
нзт |
1 М |
0,36 |
да |
i 1Д |
0,21 |
да |
t °> |
0,19 |
да |
|
- |
■ * - |
В целом ряде случаев, особенно при работе с массивами, требуется организовать вычисления не только по нарастанию параметра цикла, но и по убыванию, то есть разность (шаг) арифметической прогрессии должка быть отрицательной. Рассматриваемый оператор цикла позволяет это сделать.
Пример 7.19 (5.7).
Организовать вычисление функции (7.1) по убыванию аргумента.
Фрагмент программы вычислений для нашего примера будет иметь вид:
В операторе цикла со спецификацией типа арифметической прогрессии разрешается менять местами выражения р1 и р3, то есть
for
Так, последовательность операторов, реализующая вычисление функции примера 7.1, может быть записана следующим образом:
Чаще всего в рассматриваемом операторе цикла в качестве p1, p2, p3 используются константы либо простые переменные, как частный случай скалярных выражений, но в общем случае ими могут быть сколь угодно сложные скалярные выражения. Рассмотрим примеры,
Пример 7.20.
Напечатать таблицу значений функции
y =
для α изменяющегося от /4 до /2 с шагом /8.
Фрагмент программы на С++, реализующий указанные вычисления, может иметь вид:
Пример 7.21 (5.9).
Вычислить значение функции
где t изменяется от f 4 i* ftnA до --*CCS(X! с иагом 1,112
i-cosx yzj + t.
Расчеты произвести при заданных значениях « 1,8; 7 ■ 3,1*; х =0,5.
Фрагмент программы на С++, реализующий циклические вычисления мо-жет иметь вид:
2 - 1.8; PI - 3.14; X - 0.5; ЬОи Г= f/2* -> <!i#(X))/(1- crt(X)) аВУи
1,1й * QC+ 3)/(Х +20) с ГО и (2 * С0$!(Х))/ $PJ.T(X**2 + S)l У* 7* Ш(АбиШ(Р1*£//г))); PITT* №Р«МГЙи (Г, у); &Ш\
При выполнении операторов цикла со спецификацией типа арифметической прогрессии значения выражений p1 , p2, p3 вычисляются только один раз - перед началом выполнения спецификации, до первого входа в цикл, и их значениями будут вполне определенные числа (константы). При всех последующих циклах вычислений значения p1 , p2 и p3 остаются раз и навсегда неизменными и изменить их значения за счет внутренних операторов цикла уже не представляется возможным. Здесь же заметим, что значение управляющей переменной (параметра цикла) за счет внутренних операторов цикла, если это потребуется, можно изменить. Таким образом, значение параметра цикла внутри цикла можно изменять, а значения p1, p2, p3 внутри цикла изменить нельзя. Об этом всегда следует помнить. Если оператор цикла содержит несколько спецификаций, то значения начального значения, шага и конечного значения вычисляются заново перед началом выполнения следующей спецификации.
Из всех разновидностей оператора цикла языка С++, рассматриваемый тип оператора цикла как никакой другой нашел самое широкое применение при работе с массивами (работу с массивами рассмотрим в последующих лабораторных работах). В этом случае в качестве параметра цикла используется специальная индексная переменная - счетчик циклов. Еще раз заметим, что индексная переменная и индексированная переменная (переменная с индексами) это не одно и то же; об этом следует помнить при использовании операторов цикла. Но с использованием индексной переменной можно реализовать ЦВП не только с массивами чисел. Рассмотрим этот случай на конкретном примере.
Пример 7.22.
Организовать вычисления в цикле функции (7.1). используя при этом в качестве параметра цикла специальную индексную переменную - счетчик циклов.
Фрагмент программы, реализующей указанные вычисления на С++ может иметь вид:
X - 0;
ЪОЛ - ОцТО*2(VBJ«I; Z - v.A*X**2 + В)/С; У ■ кТАН ( ft?/?/4Z) *Z#(Z) );
put* ship и data *{х,ю;
X = X + 0.1;
Как видно из приведенного фрагмента программы, параметр цикла I не входит (не участвует в вычислениях) в операторы, образующие тело цикла. Но, тем не менее цикл будет выполнен 21 раз, и результаты вычислений функции у будут аналогичны результата» вычислений, когда в роли параметра цикла выступал аргумент х (см. примеры 7.3, 7.4).
Рассмотрим еще один пример на использование оператора цикла о управляющей переменной - счетчиком циклов.
Пример 7.23.
Используя оператор цикла описать алгоритм, представленный на рис. 7.2,б (см. пример 7.5).
Программа, реализующая алгоритм, представленный на рис. 7.2,6, может иметь вид:
Как уже отмечалось ранее, ЦВП могут быть реализованы и без использования оператора цикла, а за счет совместного использования оператора присваивания, оператора перехода и условного оператора. Рассмотрим, как можно это сделать, на конкретном примере.
Пример 7.24.
Организовать циклические вычисления функции (7.1) без использования оператора цикла.
В операторе цикла со спецификацией типа арифметической прогрессии любой элемент спецификации, кроме начального значения (р1), может быть опущен.
Если в спецификации оператора цикла опущена конструкция р3, то в этом случае по умолчанию считается, что значение р3 равно 1 (единице). Например, в операторе цикла
90*1 .- 1«Т0« 20;
предполагается, что шаг (приращение) параметра цикла равен единице, то есть параметр цикла последовательно принимает значения 1,2,3,4,5, б. .... 15,20.
Если в операторе цикла опущены одновременно две конструкции р3 и р2, то оператор имеет следующую форму:
£метка0 ЬОа параметр цикла « СКВ/ ;
Ш
&» $п •
6НЬ f meikaj ;
С помощью этой частной формы оператора цикла со спецификацией типа арифметической прогрессии имеется возможность выполнить тело цикла только для одного значения управляющей переменной, и приращение значения параметра цикла в этом случае не делается.
Разрешен также оператор, в котором отсутствует конструкция р2, то есть
Но в этом случае среди операторов тела цикла обязательно должен быть оператор, проверяющий окончание цикла по какому-то условию (как правило это реализуется совместным использованием короткой формы условного оператора и оператора перехода).
Рассматриваемый оператор со спецификацией типа арифметической прогрессии, когда присутствуют все три конструкции р1, р2, р3 выполняется по блок-схеме, приведенное на рис. 7.4ч. На рис. 7.4 в роли параметра цикла выступает переменная X.
Рис. 7.4. Блок-схема выполнения оператора цикла со спецификацией типа арифметической прогрессии в алгоритмическом языке С++
В общих чертах семантика выполнения рассматриваемого оператора цикла такова. До входа в цикл вычисляются значения скалярных выражений р1, р2, р3 и в виде числовых констант присваиваются вспомогательным переменным ХН, ХК, DX, соответственно. Далее параметр цикла X получает начальное значение X = ХН. Если текущее значение параметра цикла не вышло за границу конечного значения ХК, то выполняются операторы, образующие тело цикла, иначе происходит выход из цикла, после выполнения операторов тела цикла параметр цикла изменяется на величину DX и снова проверяется конец цикла и так далее.
Как видно из блок-схемы, при такой организации работы оператора цикла он может быть вообще не выполнен ни разу. Это произойдет в том случае, когда для первого же значения параметра X = ХН будет сразу же выполнено условие
( X - ХК)* > 0 . (7.3)
При проверке цикла с помощью сомножителя ЯХЬМ X) учитывается не правление изменения параметра цикла. Это позволяет каждое очередное новое значение параметра цикла проверять не только на конец цикла, но и на допустимость этого значения. Настоящий факт особенно важен, если учесть, что оператор цикла может не выполниться ни разу в связи с нарушением естественных для арифметической прогрессии соотношений между выражениями р1, р2 и р3 . Наиример, оператор цикла
MrXf" 3« Byv - 2^10*7; §» Х**2;
Ш i
не выполнится ни разу, так как сразу значение логического выражения (3 - 7)* SJuv(-2) - 4 > 0 окажется истинным (ветвь "да" на рис. 7.4).
Из определения (7.3) также следует, что при составлении р2 нужно учитывать точность представления в машине действительных переменных не целого типа. Это обстоятельство подчеркивалось при рассмотрении отношений в условных операторах. При программировании операторов цикла об атом также не следует забывать. Покажем это на конкретном примере:
D"u X « 1„ ВУ„г«10и 13;
У ;
END »
Если параметр цикла X в рассматриваемом примере описан как переменная целого типа, например, с атрибутами OECuFJXЈJ>{Z), то оператор тела цикла S будет выполнен для всех значений X = 1, 3, .... 11, 13 включая и последнее значение X = 13. Это обстоятельство объясняется тем, что целые числа в ЭВМ всегда представляются точно (без погрешностей), поэтому при проверке соотношения (7.3) в случае X ==ХК, разность между последними величинами будет действительно равна нулю (т.е. X – ХК = 0), поскольку они представлены точно, и управление в этом случае будет передано на выполнение оператора цикла для X = ХК.
Если же параметр цикла X в рассматриваемом примере не будет являться переменной целого типа, например, имеет атрибуты МСи FIXEbvfcq) или DECu FЈ>D.4T(.p), ила же не описан вовсе (тогда по умолчанию параметру цикла X будут назначены атрибуты МС и РШТ ) оператор цикла для последнего значения X = 13 может быть не выполнен из-за погрешности представления величины ХК. Так, вместо ожидаемого точного значения ХК = 13 в ЭВМ ХК может быть представлено как ХК = 12,999999. Вследствие этого условие (7.3) очень часто оказывается выполненным на один шаг раньше, чем 'то следовало бы. Так, для рассматриваемого примера, при X = 13, вместо того, чтобы передать управление на продолжение циклических вычислений (случай X - ХК = 0), будет передано управление на окончание цикла, так как окажется, что X - ХК > 0 (например, для X =13 и ХК - 12,999999 имеем 13 - 12.999999 * 0.000001 > 0).
Для устранения этого явления в операторе цикла со спецификацией типа арифметической прогрессии есть очень простое средство: рекомендуется в качестве значения ХК брать значение ХК + 0,5 *DX (то есть брать значение p2 = p2 +0,5*p3).
С учетом сказанного, для нашего примера, если параметр X имеет атрибуты DEC и /г1/0АГ(р') или PECvFZXeD (р,0, то есть описан, как не целая величина, в заголовок цикла необходимо внести изменения и представить оператор цикла в виде
МЛ - 1и Ши 2 „ ТС„ 14;
У; емэ;
Работа оператора цикла со спецификацией типа арифметической прогрессии эквивалентна действиям следующих операторов:
X * хн;
STMT', и IFU 0C-XK) * >0\,
rue** 6-0 v 7VU FT#iS//; gg;
X - X + V X; (5.4)
Здесь SS - операторы, образующие тело цикла; S - приемник оператора цикла. В общем случае выход из цикла ( &0и ТО* FIA/IStf) указнвает либо переход к следующей спецификации списка спецификаций оператора Ж> , либо, если уже выбранная спецификация является последней в списке, переход к следующему оператору программы (ем. рис. 7.4). Из вышеприведенной эквивалентной группы операторов и рис. 7.4 видно, что в операторе цикла реализованы многие действия, которые выполняются программистом при использовании оператора перевода или условных операторов для программирования ЦВП.
В заключение сделаем несколько общих, замечаний, относящихся к оператору цикла:
1. правилами синтаксиса запрещается переход из вне оператора цикла во внутрь оператора на операторы, образуйте тело цикла, то есть метка (метки) внутри оператора цикла (в операторах тела цикла) недоступны оператору перехода, расположенному вне оператора цикла;
2. выход из оператора цикла возможен до исчерпания списка спецификации, если среди операторов тела цикла записан оператор перехода, ведущий к метке вне оператора цикла. В этом случае переменная - параметр цикла сохраняет значение, которое она имела непосредственно перед выполнением оператора перехода;
3. если окончание цикла происходит после исчерпания списка спецификаций (цикл заканчивается естественным образом), то управляющая переменная - параметр цикла имеет значение, которое привело к окончанию цикла;
4. выражения, не содержащие (не зависящие от) переменной - параметра цикла, рекомендуется (целесообразно) вычислять вне оператора цикла и подставлять их в операторы тела цикла своими значениями;
5. скалярные выражения, входящие в элементы спецификации циклов р1, р2, р3^, СКВ3 и не зависящие от параметра цикла, рекомендуется (следует) вычислять также вне операторов цикла, подставлять в заголовки циклов своими значениями;
6) скалярные выражения начального значения р1, конечного значения р2 и приращения р3 управляющей переменной вычисляются при выполнении оператора НО только один раз (до выполнения оператора цикла). Операторы тела цикла операторе ЬО не могут изменить эти выражения ; можно лишь изменять значения управляющей переменной в теле цикла. Если i-ри этом изменении значение управляющей переменной превысит конечно'! значение, то лри положительном приращении произойдет выход из цикла.
Рассмотрим приведенные основные свойства операторов М более подробно, с привлечением конкретных примеров.
Как уже отмечалось, если цикл заканчивается естественным образом, то есть,когда список спецификаций исчерпан, то управляющая переменная имеет значение, которое привело к окончанию выполнение цикла. Например, для фрагмента программы
Wu I •« 10„.ВУ, 5U Т0„ 60;
BND ;
после выполнения цикла управляющая переменная I будет иметь значение 65. Теким образом,для оператора цикла, где параметр цикла изменяется по закону арифметической прогрессии, после исчерпания списка спецификации и выгода из оператора цикла, параметр цикла сохраняет значение;
на шаг (СКВ}) больше , чем последнее использованное в вычислениях тела цикла значение (СКВ,») при СКВ5>0 (положительное приращение);
на шаг (СКВа) меньше, чем последнее использованное в вычислениях тела цикла значение (СКВ/> при СКВ3 < 0 (отрицательное приращение).
Вход в оператор цикла допускается только через заголовок цикла .Это означает, что внутри тела цикла могут быть метки, однако передавать на них управление с помощь» операторов перехода из вне тела соответствующего цикла не разрешается. Например, запись №1 *.-2«-ВУ.,1„Т0«/ 30; М: У ■ А * X;
С * А + X; END \ ••
^«Т0„М;
неверна, так как оператор перехода {GPu T0U М) из вне цикла передает управление оператору с меткой М внутри тела цикла.
Правильной является такая последовательность операторов: и: «ЬО,* »„2.,ByvI„TO</30; У ■ А* X; С « А + X; SNDu М; fO^IQu К;
Заметим, что внутри тела цикла на передачу] управления с помощью оператора перехода &ty ТО никаких ограничений в ЙЛ/Х не делается.
Часто при программировании возникает ситуация, когда необходимо для текущего значения параметра цикла прервать выполнение операторов, образ, лщих тело цикла, с последующим возвращением на повторение цикла. Для этого оператором перехода управление передается на конец тела цикла, воспользовавшись пустым оператором для помещения метки перед клю»
чевым словом BNJ). Возвращение на повторение цигла осуществляется через последний оператор тела цикла, так как переход к подобной метке вызывает завершение выполнения тела цикла. Отмеченное обстоятельство описано ниже.
Пример 7.25.
Вычислить и вывести на печать значения функции
у V а3 / (х*- I) при х изменяющемся от 0 до 3 с шагом 0,1. Из рассмотрения исключить особую точку х ■ I. Значение а принять равным 10.
Фрагмент программы, реализующей указанные вычисления, может иметь ■ид;' ■ ■ ■ Л
а - Ю; *«?«Х - O„T0,,3»rV#/O.I»
xf„x - I итнени вои WufM;
У » А**3/(Х**2 - 1); fltii**
end;
В приведенном фрагменте программы меткой FIN помечен не символ END , что синтаксически не предусмотрено в BJ/I, а пустой оператор, расположенный перед END < Оператор цикла согласно его определению (см. рис. 7.4 и выражение (7.4) ) будет транслироваться в соответствии с эквивалентным ему условным оператором If, Ври этом метка flHt очевидно, окажется перед операторами X = X + DX (в вашем случав X » X + 0.1) и 60 и ТО и START (в нашем случае 60и Щ. на_новторение цикла).
Приведем еще один пример, иллюстрирующий высказанное положение.
Пример 7.26.
Вычислить и вывести на печать значение функции Z « х* /к2 , большее а, если к « 1,2,3, 100. Расчеты произвести для х - 10 и а - 5000.
Фрагмент программы, реализующей указанные вычисления, может иметь вид:
X - 10; А - 5000; D^w К - 1иТ0.ЛСО; Zm X»* К/К** 2;
IF и Z <■ - А и TfifN и &0иТ0и ЛМ',
ptrTu$Kl?»l>ATAu(KtZ)'
КОН: ;
ENO\
Выход из тела цикла осуществляется либо посредством оператора перехода $0и ТО ,
передающего управление на кетку вне тела цикла и входящего в его состав, либо в результате исчерпания списка спецификаций цикла, через заканчивающий тело цикла оператор END . Если выход из тела цикла произошел с помощью к»:,, то-либо оператора, то значение параметра цикла будет таким, кадим оьо было непосредственно перед выполнением оператора перехода, проиллюстрируем замечание о значении параметра цикла в случае выхода из цикла до его окончания.
Пример 7.27.
Определить минимальное число / такое, что сумми первых с значений функции у » х' ft* ье превышает или равна в, при этом /=1,2, .... п . Однапо в случае, когда такого значения / нет, нужно принять, что с * я . Расчеты произвести для в » 10000, п - 100, х » 5.
Фрагмент программы, реализующей указанные вычисления, может иметь вид:
sitm = jef; в - х * f3 n*
Ь0и1 * -I* ТО., N и Ши1\ WM* $ЧГМ у Х**1/1 **2; IF и StTM > - В н THEN и 6-0и Т4и SON; END I I" N\
вой: ptfTu skip oDa tau (i);
В приведенном фрагменте программы выход из цикла к метке Ш произойдет по оператору £$и Т0«/8М, ест gtfM z В и I £ N . В таком случае, как бы;.о отмечено, значение параметра цикла I определено и будет таким, каким оно было непосредственно перед выполнением оператора перехода (для принятых значений в примере х - 5 и в «■ 10000 оно окажется равным I - 9). Но если SVM^B , а цикл уже закончен, при выходе из цикла "через"" значение параметра цикла согласно определению будет I.» 100 +1 = 101. Однако по условию в этом случае ну..;но считать, что с ■ п , поэтому после END ; помещен оператор присваивания I ■ Щ, делающий в этом случае значение / определенным согласно условию задачи.
Сгалярные выражения, входящие в элементы спецификаций циклов и не зависящие от параметра цикла, следует вычислять вне оператора цикла и подставлять в заголовок цикла своими значениями. Этот прием повышает, в первую очередь, наглядность самого опе^татора цикла, да и программы в целом.
Пример 7.28.
Организовать циклические вычисления функции примера 5.9. Предусмотреть при этом вычисление скалярных выражений спец и-кации цикла до входа в цикл.
фрагмент программы, реализующий циклические вычисления функции поимера 5.9, с учетом высказанного замечания, может иметь вид: £ • 1,8; PI - 3.14; " X - 0."
тн - уг*ье&{ (t +ш(х)>,, i -дяЧх));
М - 1,112* (Х + 3)/(Х + 20); ТК - (2 *С0.£(Ж)У$ОЙТ(Х,** 2 + *); гОиЧ - ТН^ВУо Т„Т0„ТК;
У » цШ (4в£(Ш(Р1 * S/T)))-Р!/Ти SHIP и ЪАТА* (Г, у); BMP',
Срав» 'чие фри денюв программ гримеров 5,9 и 5.16, реализующие одинаковые исчисления, показывает, что введение вспомогательных переменных ТН, J)T и ТК и предварительного вычисления элементов спецификации (до входа в цикл), значительно повышает наглядность программы.
Выражс ля, вычисляемые в теле цикла и не 'авиеящяе от параметра щ ела, также следует вычислять до входа в цикл и далее подставлять их в операторы тела цикла своими значениями. Это позволяет существенно сократить общее время циклических вычислений.
Пример 7.30.
С 'тавить программу для вычисления и печати таблицы значений функции
у » 2-&гс£% а - sinjf* • Saj~j> при х - 2,15; 2,20; ...; 2,50 и а - 0,8.
Поскольку выражение 2-aictg.a. не зависит от параметра цикла х, то имеет смысл вычислить его однажды, jo входа в цикл; результат вычислений присвоить вспомогательной переменной, например, в, и впредь в циклических вычислениях вместо вычисления в каждом цикле выражения Z-ttctg а пользоваться переменной в с постоянным значением.
Программа, реализующая указанные циклические вычисления, может иметь вид:
Р/Ш517: PROCu 0РГ1М?(МА£Л); А - 0,8;
В - 2* ATAW (А); t>0u X - 2.I5./T0./2.5O*- ВУ* 0.05; У - В - ШМ*Ш(ЛВ$рС/<$'л
BHD; * J'
BNbu Рл1м517;
при организации ЦВл средствами языка ПЛ/I необходимо знать правила организации циклов, входа и выхода из операторов цикла, а также корректно з^дава-ь пересчет значений параметра цикла.
Наиболее характерной ошибкой при программировании циклов является "зацикливание". Зачастую оно происходит вслздетвие неверного изменение? значений параметра цикла.
Заметим также, что наиболее часто встречающиеся в практике программирования являются ЦВП, в которых значения переменных меняются по закону арифметической прогрессии, и, следовательно, сред»! о ераторов цикла оператор цикла со спецификацией типа арифметической прогрессии наиболее употребим.
Все замечания по работе и использованию оператора цикла со спецификацией типа арифметической прогрессии, сделанные здесь, в равной степени относятся ко всем другим конструкциям оператора цикла.