Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






О п е р а т о р ц и к л а с п а р а м е т р о м






 

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

Пример 1. Вычислить путем многократного умножения ( - целое положительное число).

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

Приведенный в блок-схеме алгоритм решения задачи легко реализовать с помощью цикла while.

 
 

 


Си-программа с циклом while.

 

intmain()

{

inti, n;

doublex, y;

//Ввод значения x, n

y=1.; i=1;

while(i< =n)

{ y*=x; i++; }

//Печать y

getch();

return0;

}

 

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

 
 

 


Тогда блок-схема задачи будет иметь вид:

 

 
 

 

 


Си-программа с циклом for

 

intmain()

{

inti, n;

doublex, y;

//Ввод значения x, n

y=1.;

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

y*=x;

//Печать y

getch();

return0;

}

Оператор for описывает цикл, который является обобщением цикла while. Если сравнить его с ранее написанным while, то станет ясно, как он работает. Внутри скобок имеются три выражения, разделяемые точкой с запятой. Первое выражение — инициализация i = 1 выполняется один раз перед тем, как войти в цикл. Второе — проверка условия продолжения цикла i < = n. Условие вычисляется, и если оно истинно, выполняется тело цикла. Затем осуществляется приращение шага: i++, и условие вычисляется снова. Цикл заканчивается, когда условие становится ложным. Как и в случае с while, тело for -цикла может состоять из одного оператора или из нескольких, заключенных в фигурные скобки. На месте этих трех выражений (инициализации, условия и приращения шага) могут стоять произвольные выражения.

Выбор между while и fоr определяется соображениями ясности программы. Цикл for более удобен в тех случаях, когда инициализация и приращение шага логически связаны друг с другом общей переменной и выражаются единичными инструкциями, поскольку названный цикл компактнее цикла while, а его управляющие части сосредоточены в одном месте.

Оператор for формально записывается, в следующем виде:

for (выражение_1; выражение_2; выражение_3) тело_цикла

1.Тело цикла составляет либо один оператор, либо несколько операторов, заключенных в фигурные скобки {... } (после блока точка с запятой не ставится). В выражениях 1, 2, 3 фигурирует специальная переменная, называемая управляющей. По ее значению устанавливается необходимость повторения цикла или выхода из него.

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

3.Выражение_2 проверяется перед исполнением тела цикла, а значит, если оно ложно, то тело цикла ни разу не исполнится.

4.Любое из трех выражений в цикле for может отсутствовать, однако точка с запятой должна оставаться. Таким образом, for (;;) {...} - это бесконечный цикл, из которого можно выйти лишь другими способами.

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

 

intmain()

{

inti, n;

doublex, y;

//Ввод значения x, n

for(y=1., i=1; i< =n; y*=x, i++);

//Печать y

getch();

return0;

}

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

В рассмотренном выше примере при n=10 и x=2 в результате получится y=1024 (y=xn, т.е. y=210). Если записать цикл в виде for(y=1., i=1; y*=x, i< =n; i++), то ошибки при компиляции не будет. Однако, в результате получится y=2048.

 

Пример 2. Вычисление факториала y=n! =

 

Блок-схема

 

 
 

 

 


Си-программа

 

intmain()

{

nsignedchari, n;

unsignedlonglonginty;

//Ввод значения n

y=1;

for(i=2; i< =n; i++)

y*=i;

//Печать y

getch();

return0;

}

 

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

Пример 3. Вычисление двойного факториала y=n!!

Двойной факториал – это произведение четных чисел при четном значении переменной n или произведение нечетных чисел при нечетном n.

Блок-схема

 
 

 


Начальное значение параметра цикла устанавливается равным 2, если n четное, и равное 3 при нечетном значении n. В цикле применяется шаг, равный 2. В этом случае параметр цикла принимает только четные или нечетные значения.

 

Си-программа

 

intmain()

{

unsignedchari, n;

unsignedlonglonginty;

//Ввод значения x, n

y=1;

for (i = (n % 2? 3: 2); i < = n; i += 2)

y *= i;

//Печать y

getch();

return0;

}

 

 

Пример 4. Распечатать цифры целого числа a в обратном порядке.

 

В разделе «Цикл с предусловием», пример 5, рассматривался алгоритм решения задачи с использованием цикла while. При использовании цикла for в качестве параметра цикла используется переменная a1. Инициализация параметра производится в заголовке цикла (a1=abs(a)). Изменение его значения производится здесь же (a1/=10). Проверка условия продолжения цикла (a! = 0) в программе проводится, с учетом рассматриваемого выше правила, что false – значение равное 0, а любое значение, отличное от 0, рассматривается, как true.

Блок-схема.

 
 

 

 


Си-программа

 

intmain()

{

inta, d, a1;

//Ввод значения а

for(a1=abs(a); a1; a1/=10)

{

d=a1%10;

printf(" %1d", d);

}

getch();

return0;

}

Пример 5. Вычислить ряд

четырьмя способами:

1) последовательно слева направо;

2) последовательно справа налево;

3) слева направо отдельно положительные и отрицательные элементы, затем их вычитание;

4) то же, но справа налево.

 

intmain()

{

float

SumLR, // сумма, все слева направо

SumRL, // сумма, все справа налево

SumLRNeg, // сумма, отрицательные эл-ты, слева направо

SumLRPos, // сумма, положительные эл-ты, слева направо

SumRLNeg, // сумма, отрицательные эл-ты, справа налево

SumRLPos, // сумма, положительные эл-ты, справа налево

ElemLRNeg, // очередной отриц.элемент, слева направо

ElemLRPos, // очередной полож.элемент, слева направо

ElemRLNeg, // очередной отриц.элемент, справа налево

ElemRLPos; // очередной полож.элемент, справа налево

inti; // параметр цикла

SumLR=0; SumRL=0; SumLRPos=0; SumLRNeg=0;

SumRLPos=0; SumRLNeg=0;

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

{

ElemLRPos=1./(2*i-1); ElemLRNeg=1./(2*i);

ElemRLPos=1./(10001-2*i); ElemRLNeg=1./(10002-2*i);

SumLR=SumLR+ElemLRPos-ElemLRNeg;

SumRL=SumRL+ElemRLPos-ElemRLNeg;

SumLRNeg=SumLRNeg+ElemLRNeg;

SumLRPos=SumLRPos+ElemLRPos;

SumRLNeg=SumRLNeg+ElemRLNeg;

SumRLPos=SumRLPos+ElemRLPos;

}

printf(" SumLR = %10.7f\n", SumLR);

printf(" SumRL = %10.7f\n", SumRL);

printf(" SumLRPos-SumLRNeg = %10.7f\n", SumLRPos-SumLRNeg);

printf(" SumRLPos-SumRLNeg = %10.7f\n", SumRLPos-SumRLNeg);

getch();

return0;

}

 

Примечание. Для описания вещественных переменных использован тип floate вместо типа double, чтобы более четко показать влияние погрешности представления вещественных значений на результат вычислений (в типе floate мантисса имеет длину 23 бита вместо 52, как в типе double, что определяет меньшее количество значащих цифр в представлении вещественного числа).

 

Программа печатает следующие результаты:

SumLR 0.6930732

SumRL 0.6930972

SumLRPos-SumLRNeg 0.6931019

SumRLPos-SumRLNeg 0.6930976

 

Наиболее точная здесь сумма - SumRL.

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

 

Рассмотрим, как изменяется число 1/9000 при сложении его с числом 1/8998 или с числом 1/3. Мантиссу будем представлять с семью десятичными цифрами.

 

1/9000 = 0, 0001111111 = 0, 1111111 ×

1/8998 = 0, 0001111357 = 0, 1111357 ×

1/3 = 0, 3333333 = 0, 3333333 ×

 

a) 0, 1 1 1 1 1 1 1 ×

+ 0, 1 1 1 1 3 5 7 ×

¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾

0, 2 2 2 2 4 6 8 ×

б) 0, 1 1 1 1 1 1 1 × 0, 0 0 0 1 1 1 1 ×

+ 0, 3 3 3 3 3 3 3 × Þ + 0, 3 3 3 3 3 3 3 ×

¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾ ¾

0, 3 3 3 4 4 4 4 ×

 

Во втором случае в первом слагаемом потеряны три значащие цифры.

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

 

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.