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

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

Теоретическая часть

Часто число повторений цикла заранее неизвестно, и определяется в процессе реализации циклического алгоритма. Рассмотрим, например, следующую задачу.

Вычислить для некоторого значения x с заданной точностью >0 сумму:

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

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

из которого получим

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

цифры в его записи):

и. т. д.

Этот процесс заканчивается, когда очередное слагаемое удовлетворит условию:

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

Здесь (повторять) и (пока не; до) – служебные слова, – последовательность выполняемых в цикле операторов (тело цикла), – логическое выражение, управляющее повторением цикла.

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

Рассмотрим применение оператора цикла с постусловием на примере решения приведенной выше задачи вычисления y(x). Предварительно укажем имена переменных, которые будут использованы в программе:

esp –заданная точность (заметим, что нельзя использовать греческую букву );

k – номер слагаемого суммы y(x), начиная с нулевого;

a – очередное слагаемое суммы y(x);

y – частичная сумма, соответствующая сумме первых k слагаемых.

Пример1.

program pr1;

var eps,a,y,x: real;

k: integer;

begin

writeln (‘введите x и eps’);

readln(x,eps);

k:=0;a:=1; y:=0;

repeat

y:=y+a;

k:=k+1;

a:=a*x/k

until abs(a/y)<eps;

writeln(‘y(‘,x:4:2,’)=’,y,’, число слагаемых равно=’,k:3);

writeln(‘exp(‘,x:4:2,’)=’,exp(x))

end.

Выполнение приведенной выше программы инициирует следующие действия. Переменным k, a и y присваиваются начальные значения 0, 1, 0, соответственно. В цикле вычисляются значения частичной суммы y, номер следующего члена суммы k и значение этого члена a. Затем при выходе из цикла проверяется условие: . Если это условие не выполняется, то происходит возврат на начало цикла, и последовательность операторов в цикле выполняется вновь. В противном случае цикл завершается и на экран выводится результат вычисления суммы y(x). Помимо этого выводится число слагаемых, обеспечивающее вычисление суммы с заданной точностью eps, а также для контроля, значения , вычисленное с помощью обращения к функции exp(x). (Обратите внимание: так как нумерация членов суммы начинается с 0, то истинному числу слагаемых соответствует значение k + 1. Именно оно и выводится на экран.)

Приведем пример использования оператора цикла repeat…until для вычисления бесконечного произведения. Рассмотрим следующую задачу. Вычислить с заданной точностью бесконечное произведение.

Считать, что требуемая точность достигнута, если выполнено неравенство .

Пример 2.

program pr2

var k: integer;

P, eps: real;

begin

writeln (‘ Введите точность eps’);

read (eps);

k:=2; P:= 1;

repeat

P:= P *(1-2/(k*(k+1)));

k:= k+ 1;

until 1/(k*k) <=eps;

writeln ('P=', P: 6: 3,' число сомножителей-', k: 10)

end.

В программе использованы переменные: k – номер очередного сомножителя; P – произведение k сомножителей; eps – требуемая точность вычислений. После ввода eps переменной k присваиваем первое значение, равное 2. Переменной P присваиваем значение 1 (т.к. далее мы вычисляем произведение, а умножение на 1 не меняет результат). Далее входим в цикл, где вычисляем текущее произведение P; задаем номер очередного сомножителя k и, наконец, при выходе из цикла проверяем условие . Если оно выполнено, то цикл завершается и на экран выводятся произведение и число сомножителей, при котором достигается требуемая точность eps. Если условие выхода из цикла не выполнено, последовательность операторов цикла повторяется вновь.

В заключении отметим еще раз:

операторы цикла с постусловием выполняются хотя бы один раз, так как вычисление логического выражения, стоящего после until, осуществляется в конце цикла;

цикл выполняется до тех пор, пока логическое выражение, вычисляемое в конце цикла, не станет true.

Контрольные вопросы.

1. Какими зарезервированными словами обозначается оператор цикла с постусловием?

2. Как работает оператор repeat?

3. В каком случае тело оператора цикла с постусловием не будет выполнено ни разу?

Задания

I. Вычислить с точностью бесконечную сумму или произведение для выбранного значения x. Проследить за изменением результата при изменении величины eps. Для контроля в каждом примере в квадратных скобках приведено или выражение, представляющее данную сумму или произведение, или их табличное значение (при x =1), взятое из справочника.

1.

[sh(x)]

2.

[cos(x)]

3.

, <1 [ln(1+x)]

4.

<1 [arctg(x)]

5.

[sin(x)]

6.

[ch(x)]

7.

, <1,

8.

, <x [ /4]

9.

II. Вычислить бесконечное произведение P при заданном значении x. Для контроля в каждом задании в квадратных скобках приведено точное значение вычисляемого произведения.

1.

[cos(x)]

2.

Лабораторная работа№6.

Одномерные массивы.

Цель работы – научиться составлять программы с использованием одномерных массивов.

Теоретическая часть

В математике широко используются обозначения более сложные, чем имена вида x,y,s и тому подобное. Так, полином степени n часто представляется в виде

Коэффициенты при степенях x обозначены одним и тем же именем и различаются между собой подстрочным индексом. Обычно индексы представляют собой последовательные целые числа (в примере от 0 до n). Таким образом, имя a используется для обозначения совокупности чисел, а не одного числа, как это имеет место в случае простых переменных.

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

Массив (индексированные переменные) - подмножество однотипных переменных, объединенных по какому-либо признаку и имеющих общее имя. Отдельные величины, составляющие массив, называются его элементами. Доступ к конкретному элементу массива осуществляется с помощью индексов, которые указывают в скобках после имени. Количество элементов в списке индексных типов называется размерностью массива.

Характеристики массивов, как и любого объекта, используемого в программе, должны быть определены в разделе описаний. При этом необходимо указать:

а). имя массива (общее имя переменных, составляющих массив);

б). наибольшее и наименьшее значение, которое может принимать индекс(тем самым определяется число элементов в массиве, так как принято, что допустимые значения индекса заполняют без пропусков весь интервал между наименьшим и наибольшим значениями);

в). тип элементов массива.

Описание может быть выполнено несколькими способами, которые иллюстрируются на следующем примере.

Объявить массив вещественных чисел

Способ 1. Вся требуемая информация задается одновременно:

var x: array [-50.. 50] of real;

Фактически описание представляет собой оформленную по правилам Турбо Паскаля фразу: x – это совокупность (array) вещественных (real) чисел, пронумерованных через 1 от -50 до 50.

Способ 2. Этот вариант описания аналогичен следующему возможному фрагменту математического текста: «Определение. Вектором называется совокупность вещественных чисел, пронумерованных от –n до n (n<=50). Пусть x –некоторый вектор…»

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

Для введения новых типов предназначен раздел определения типов, который предшествует разделу описания переменных и имеет следующий формат:

type имя типа = описание типа;

Здесь type – служебное слово, имя типа – выбирается программистом с соблюдением правил образования имен вТурбо Паскале, а описание типа – обуславливается правилами языка Турбо Паскаль. В последующем тексте программы имя типа может быть использовано так же, как и имена стандартных типов real, integer, boolean.

В рассматриваемом примере определим новый тип данных, которому дадим имя vector

type vector = array [-50..50] of real;

то есть vector – это совокупность (array) вещественных (real) чисел, пронумерованных через 1 от -50 до 50. Описание массива x теперь производится обычном образом как описание переменной типа vector

var x: vector;

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

var i: -50.. 50;

Диапазонному типу данных можно дать свое имя, определив его в разделе type, и далее использовать это имя в описаниях. Например,

type index = -50.. 50;

var x: array [index] of real;

i: index;

Введение имени типа для индекса имеет следующие достоинства. Во-первых, упрощаются описания. Во-вторых, появляется возможность отдельно объявить переменные, которые будут использоваться в качестве индекса у элементов массива (переменная i в последнем примере). Это делает текст программы более наглядным и понятным. Кроме того, при изменении значений переменных диапазонного типа (а именно таков тип индекса) можно

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

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

const nmax = 50;

type vector = array [-nmax…nmax] of real;

var x: vector;

Для адаптации последнего описания. например, к неравенству n<=100, достаточно исправления значения константы nmax.

Для переменных – массивов, допустима только одна операция - присваивание. Ее выполнение создает копию массива. Оба имени, участвующие в операции, должны именовать объекты одного и того же типа. Например, пусть имеются три варианта объявления двух массивов:

a). var x,y: vector;

b). var x,y array [index] of real;

c). var x: vector;

y: array [index] of real;

Во всех вариантах структуры массивов идентичны- это совокупности одинаково пронумерованных вещественных чисел. Но только в вариантах a) и b) типы x и y считаются одинаковыми (тождественными). Поэтому оператор присваивания y:=x при трансляции будет ошибочным, когда использовано описание c).

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

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

Рассмотрим примеры работы с массивами.

Пусть последовательность вещественных чисел (n<=50) представлена в программе массивом x, а его описание и описание прочих переменных имеют вид:

type ind=1…50;

vec= array [ind] of real;

var

x: vec;

i,n: ind;

max,s: real;

Ниже приведены фрагменты программ, реализующие некоторые типичные задачи по обработке массивов:

1). ввести последовательность из n элементов.

readln (n);

for i:= 1 to n do

read (x[i]); {набор каждого числа завершается нажатием клавиши ENTER}

2). вывести массив на экран дисплея.

for i:= 1 to n do

writeln(x[i]); {числа на экране образуют столбец}

3).вычислить сумму элементов последовательности.

s:= 0;

for i:= 1 to n do

s:= s+x[i];

4).найти номер первого отрицательного элемента (в предположении, что в последовательности есть отрицательные элементы).

i:=1;

while x[i]>=0 do

i:= i+1;

5).найти наибольший элемент последовательности.

max:=x[1];

for i:= 2 to n do

if x[i]>max then max:= x[i];

Приведем примеры законченных программ.

Пример 1. Дана последовательность вещественных чисел (n<=30).Найти их среднее значение.

program mid;

const

nmax=30;

type

index= 1..nmax;

vec= array[index] of real;

var

x: vec;

i,n:index;

s: real;

begin

write (‘n=’); {ввод числа элементов}

readln (n);

for i:= 1 to n do {ввод}

begin {значений}

write(‘x[‘,i,’]=’); {элементов}

readln(x[i]) {массива}

end;

s:=0 {вычисление}

for i:= 1 to n do {суммы}

s:= s+x[i];

s:= s/n; {среднее}

writeln (‘Среднее=’, s)

end.

Пример 2. Вычислить значение полинома P(x)= (n<=20) при заданном значении x.

Для решения этой задачи воспользуемся схемой Горнера вычисления значения полинома, основанной на представлении его в следующей форме

Значение полинома получается n-кратным выполнением оператора присваивания

p:= p*x+ , i=1,2,...n

при начальном значении p= .

program pol;

const nmax=20;

type ind=0..nmax;

coef= array[ind] of real;

var a:coef;

i,n: ind;

x,p: real;

begin

write (‘n=’); {ввод степени}

readln (n); {полинома}

for i:= 0 to n do

begin {ввод}

write (‘a[‘,i,’]=’); {коэффициентов}

readln (a[i]) {полинома}

end; {P(x)}

write(‘x=’);

readln(x); {ввод x}

p:=a[0]; {вычисление}

for i:= 1 to n do { значения}

p:= p*x+a[i]; {полинома}

writeln(‘P(‘,x,’)=’, p)

end.

Пример 3. Задано натуральное число N=50 и одномерный массив натуральных чисел , не имеющий одинаковых элементов. Требуется упорядочить этот массив по возрастанию, то есть переставить его элементы так, чтобы после перестановки выполнялось условие .

Для решения этой задачи воспользуемся известным методом сортировки - методом “пузырька”, так как при его реализации наибольшие и наименьшие элементы, как пузырьки, перемещаются (“опускаются” или “поднимаются”) в массиве (в его конец или начало).При такой сортировке организуется последовательный перебор массива и сравнение значений двух соседних элементов, в нашем случае на выполнение условия . При невыполнении условия элементы меняются местами и просмотр возобновляется с очередного элемента .По завершении цикла сравнений наибольший элемент массива передвигается на последнее место, а просмотр массива возобновляется с первого элемента при уменьшении на единицу количества просматриваемых элементов (до N-1 элемента), так как наибольший из оставшихся элементов после каждого просмотра будет оказываться в конце. Массив будет упорядочен до конца после просмотра, в котором участвуют только первый и второй элементы, следовательно, количество просмотров ограничено значением N-1.

При сортировке по убыванию изменяется на противоположное только условие проверки.

program sortirovka;

const N=50;

type vec =array[1..N] of real;

var A: vec;

i: integer;

begin

writeln(‘ввести массив’);

for i:= 1 to N do

begin

write(‘A[‘, i: 2,’] =’);

readln(A[i])

end;

for i:= 1 to N-1 do

for j:=1 to N-1 do

if A[j]>A[j+1] then { условие проверки}

begin

P: = A[j];

A[j]:= A[j+1];

A[j+1]:= P

end;

writeln(‘вывести массив’);

for i:= 1 to N do

begin

write(‘A[‘, i: 2,’] =’);

readln(A[i])

end;

end.

Контрольные вопросы.

1.Дайте определение массиву?

2. Что такое размерность массива?

3.Какие характеристики массивов должны быть определены в разделе описаний?

4.Какие способы описания массивов вы знаете?

5.Можно ли один массив присвоить другому массиву того же типа?

6.Можно ли к массивам применять операции отношения?

Задания.

1. Найти наименьший элемент последовательности (n 15) и его номер.

2. Вычислить сумму элементов последовательности (n 20), удовлетворяющих неравенству x>p.

3. Даны натуральное число N и одномерный массив A 1, A 2, …, AN, AN +1 вещественных чисел. Определить наибольшее из нечетных и количество четных чисел, входящих в этот массив.

4. Даны натуральное число N и одномерный массив A 1, A 2, …, AN целых чисел. Получить массив, который отличается от исходного тем, что все нечетные элементы удвоены, а четные получены сложением собственного значения с первоначальным значением последующего нечетного.

5. Даны натуральное число N (N >5) и одномерный массив A 1, A 2, …, AN вещественных чисел. Определить три максимальных и два минимальных значения этого массива.

6. Даны натуральное число N и одномерный массив A 1, A 2, …, AN целых чисел. Определить наименьшее положительное среди A 1, A 2, …, AN.

7. Даны натуральное число N и одномерный массив A 1, A 2, …, AN целых чисел. Определить, является ли данный массив упорядоченным по убыванию.

8. Даны натуральное число N и одномерный массив A 1, A 2, …, AN целых чисел. Упорядочить массив по возрастанию.

9. Дан массив действительных чисел с размерностью N. Определить, сколько в нем отрицательных и положительных элементов.

10. Дан массив действительных чисел с размерностью N. Определить, сколько в нем нулевых элементов.

11. В заданном одномерноммассиве поменять местами соседние элементы, стоящие на четных местах, с элементами, стоящими на нечетных местах.

12. Дана последовательность целых чисел .Вывести на печать только те числа, для которых .

13. В массив А[N] включены натуральные числа. Найти сумму элементов массива больше заданного K.

14. Дана последовательность натуральных чисел . Создать массив из четных чисел этой последовательности. Если таких чисел нет, вывести соответствующее сообщение.

15. Дана последовательность чисел, среди которых имеется один нуль. Вывести на печать все числа до нуля включительно.

Лабораторная работа №7.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: