Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР7-С++-05 апреля-2012.doc
Скачиваний:
19
Добавлен:
15.09.2019
Размер:
2.45 Mб
Скачать

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) без использования оператора цикла.

22

Фрагмент программы, реализующей циклические вычисления функции (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 необходимо знать правила организации циклов, входа и выхода из операторов цикла, а также кор­ректно з^дава-ь пересчет значений параметра цикла.

Наиболее характерной ошибкой при программировании циклов является "зацикливание". Зачастую оно происходит вслздетвие неверного изменение? значений параметра цикла.

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

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