Сделай Сам Свою Работу на 5

Отличия операторов repeat и while

Отличий три:

· Компьютер выходит из цикла оператора repeat тогда, когда условие истинно, а из цикла оператора while - когда условие ложно.

· while может ни разу не выполнить оператор, стоящий после do. repeat же хотя бы раз операторы, стоящие между repeat и until, выполнит.

Так, фрагмент k:=8; repeat k:=1 until 3>2; WriteLn(k) напечатает 1.

А фрагмент k:=8; while 2>3 do k:=1; WriteLn(k) напечатает 8.

· При компиляции оператор while дает несколько более эффективную программу, чем оператор repeat.

 

Часто эти отличия для начинающих малосущественны, поэтому выбирайте оператор по вкусу. Мне, например, надоели паскалевские begin и end, поэтому я охотнее пользуюсь оператором repeat.

Оператор цикла for

Выполняя программу печати чисел 3 5 7 9, оператор repeat выполнил цикл 4 раза. То же самое сделал и оператор while. Однако, обычно, когда мы пишем операторы repeat и while, нам совсем неважно знать, сколько раз они выполнят цикл. Тем не менее, существует много задач, для решения которых цикл нужно выполнить именно определенное количество раз. В этом случае удобно использовать оператор цикла for.

Задача: 200 раз напечатать слово ФУТБОЛ.

Попробуем сначала решить задачу при помощи оператора goto. Начнем с такого фрагмента:

metka: WriteLn('ФУТБОЛ');
goto metka

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

i:=1;
metka: WriteLn('ФУТБОЛ');
i:=i+1; {увеличение i на 1}
if i<=200 then goto metka

END.

Здесь i вначале равно 1, но к каждому следующему выполнению цикла оно увеличивается на 1. В первый раз выполняя оператор if, компьютер проверяет условие 2<=200 и найдя его истинным, выполняет оператор goto metka. Во второй раз проверяется условие 3<=200 и т.д. В 199-й раз компьютер проверяет условие 200<=200 и найдя его истинным, выполняет оператор goto metka. В 200-й раз компьютер проверяет условие 201<=200 и найдя его ложным, выходит из цикла.



В нашем фрагменте "полезную" работу выполняет только одна строка из четырех - WriteLn('ФУТБОЛ'). Остальные три строки заняты тем, что обеспечивают выполнение "полезной" строки ровно 200 раз. Нам пришлось организовать специальную переменную, значение которой в каждый момент выполнения программы говорит о том, в какой раз выполняется цикл. Переменная с таким свойством называется счетчиком циклов.

А теперь запишем программу полностью, правда, несколько усложнив ее, так чтобы логика ее выполнения полностью соответствовала логике выполнения программы с оператором for, которую я привожу параллельно и поясняю немедленно.

LABEL m1,m2; VAR i : Integer; BEGIN i:=1; m1: if i>200 then goto m2; WriteLn('ФУТБОЛ'); i:=i+1; goto m1; m2: END. VAR i : Integer; BEGIN for i:=1 to 200 do WriteLn('ФУТБОЛ') END.

Слово forчитается "фо", переводится "для". Слово to читается "ту", переводится "до". Слово doчитается "ду", переводится "делай". Конструкция for i:=1 to 200 do по-русски читается так: Для i, изменяющегося от 1 до 200, делай оператор, стоящий после слова do. Смысл повторения здесь такой же, как и в операторе while. Оператор, стоящий после do, тоже, конечно, может быть составным.

Синтаксис оператора for:

FOR имя := выражение1 TO выражение2 DO оператор

Пример записи: for j:=a+b to2*s dok:=k+1.

Пояснения к синтаксической схеме:

имя - это имя произвольной переменной порядкового типа (см. 5.7 и 12.8), в частности целочисленной, называемой переменной цикла,

выражение1 ивыражение2 - произвольные выражения порядкового типа, в частности - целого.

Работа оператора for:

Прежде всего вычисляется выражение1, и переменной цикла (пусть это будет i) присваивается его значение. Затем вычисляется выражение2 и сравнивается с i. Если i > выражения2, то оператор for завершает свою работу, так ничего и не сделав. В противном случае выполняется оператор, стоящий после do. После выполнения этого оператора значение i увеличивается на 1 и снова сравнивается с выражением2. Если i > выражения2, то оператор for завершает свою работу, иначе снова выполняется оператор, стоящий после do, снова i увеличивается на 1 и т.д.

В нашем примере переменная i кроме того, что обеспечивает нам выход из цикла, никакой "полезной" работы не выполняет. Усложним же немного задачу. Пусть компьютер печатает такую информацию:

10 ФУТБОЛ 11 ФУТБОЛ 12 ФУТБОЛ . . . . . 200 ФУТБОЛ

Вот программа:

VAR i : Integer;
BEGIN
for i:=10 to 200 do
begin Write(i);
Write(' ФУТБОЛ ')
end
END.

Здесь после do стоит уже составной оператор.

Можно ли удобно использовать оператор for для печати такой информации?:

100 ФУТБОЛ 99 ФУТБОЛ 98 ФУТБОЛ . . . . . 40 ФУТБОЛ

Вполне, так как оператор for позволяет не только увеличивать, но и уменьшать переменную цикла. Однако, для этого нельзя писать for i:=100 to 40, а нужно писать for i:=100 downto 40. Читается downto - "'даунту", переводится буквально "вниз до". Соответственно, для выхода из цикла должно быть истинным не условие i > выражения2, а условие i < выражения2.

Вот объединенный синтаксис оператора for:

FOR имя := выражение1 TO DOWNTO выражение2 DO оператор

 

Вертикальная черта между двумя элементами конструкции «TOиDOWNTO» говорит о том, что в конструкции должен присутствовать один из этих элементов.

Задание 42: Напечатать с помощью оператора for:

Прямой счет: -5 -4 -3 -2 -1 0 1 2 3 4 5 Обратный счет: 5 4 3 2 1 0 -1 -2 -3 -4 -5 Конец счета

 

Глава 7. Типичные маленькие программы

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

Вычислительная циклическая программа

Задача: Во дворце 40 залов. Известны длина, ширина и высота каждого зала. Вычислить площадь пола и объем каждого зала.

Сначала напишем фрагмент для одного зала:

ReadLn (dlina, shirina, visota);

S:=dlina*shirina; {Площадь пола}

V:=S*visota; {Объем}

WriteLn(S,’ ‘,V)

Для решения задачи этот фрагмент нужно выполнить 40 раз, для чего вполне естественно использовать оператор for:

VAR i, dlina, shirina, visota, S, V: Integer;
BEGIN

for i:=1 to 40 do begin

ReadLn (dlina, shirina, visota);

S:=dlina*shirina;

V:=S*visota;

WriteLn(S,’ ‘,V)

end {for}
END.

Обратите внимание, что здесь мы несколько модифицировали описанный нами в 5.4 ступенчатый стиль, а именно записали end не под соответствующим ему begin, а под соответствующим ему for. Эта практика также распространена, так как экономит место по вертикали. Мне она нравится больше, поэтому я буду ее придерживаться. Чтобы не спутаться, откуда взялся end, пишем рядом комментарий {for}.

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

VAR i, dlina, shirina, visota, N, S, V : Integer;
BEGIN

WriteLn(’Введите число залов‘);

ReadLn (N); {N - число залов}

for i:=1 to N do begin

WriteLn(’Введите длину,ширину и высоту зала‘);

ReadLn (dlina, shirina, visota);

S:=dlina*shirina;

V:=S*visota;

WriteLn(‘Площадь пола=’,S,’ Объем зала=‘,V)

end
END.

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

Пусть во дворце три зала размерами 20*15*4, 30*20*5 и 10*5*3. В этом случае мы вводим N=3 и оператор for выполняет цикл три раза. На каждом выполнении цикла компьютер останавливается на операторе ReadLn (dlina, shirina, visota), мы вводим числа и получаем результаты:

Площадь пола=300 Объем зала=1200

Площадь пола=600 Объем зала=3000

Площадь пола=50 Объем зала=150

Задание 43: Даны стороны N кубиков. Вычислить объем каждого.

Роль ошибок

Из 2.2 мы знаем, что по ошибочной программе компьютер выдает ошибочные результаты. Например, если в нашей программе мы вместо V:=S*visota напишем V:=S+visota, то результаты будут такими:

Площадь пола=300 Объем зала=304

Площадь пола=600 Объем зала=605

Площадь пола=50 Объем зала=53

Если случайно вместо for i:=1 to N написать for i:=2 to N то результаты будут такими:

Площадь пола=300 Объем зала=1200

Площадь пола=600 Объем зала=3000

На этом программа закончит работу и не спросит размеров третьего зала. Вам не кажется странным, что она посчитала 1 и 2 залы, а не 2 и 3? Если кажется, то учтите, что пользователь ничего не знает об ошибке в программе, а компьютер не говорит ему, размеры какого по счету зала ему нужно вводить.

Задания 44-45:

Определите без компьютера, что будет, если

44) строку for i:=1 to N do begin поместить под строкой ReadLn (dlina, shirina, visota)

45) поменять местами строки WriteLn(‘Площадь пола=’,S,’ Объем зала=‘,V)и end

 

Если задания не получаются, введите программы в компьютер и используйте отладочный режим.

Счетчики

Задача 1: В компьютер с клавиатуры вводятся числа. Компьютер после ввода каждого числа должен печатать, сколько среди них уже введено положительных.

Фрагмент, решающий задачу:

c:=0; {Обнуляем счетчик}

m: ReadLn(a); {Вводим очередное число}

if a>0 then c:=c+1;

WriteLn('Из них положительных - ' ,c);

goto m

Пояснения: В 6.6 мы придумали переменную i, которую назвали счетчиком циклов. Здесь мы тоже придумали переменную c. Она у нас выполняет роль счетчика положительных чисел. Сердце счетчика - оператор c:=c+1. Именно он в нужный момент увеличивает счетчик на 1. Но и без if a>0 thenтоже никак нельзя. Если бы его не было, то c подсчитывал бы все числа без разбору, то есть был бы обыкновенным счетчиком циклов. В нашем же фрагменте увеличение с на 1 выполняется не всегда, а лишь при положительном а.

Пусть мы вводим числа 8, -2, 10 . . . В этом случае порядок выполнения операторов будет такой:

Оператор а с Печать
c:=0 ?  
ReadLn(a)  
if a>0 then c:=c+1  
WriteLn('Из них положительных - ' ,c) Из них положительных 1
goto m  
ReadLn(a) -2  
if a>0 then c:=c+1 -2  
WriteLn('Из них положительных - ' ,c) -2 Из них положительных 1
goto m -2  
ReadLn(a)  
if a>0 then c:=c+1  
WriteLn('Из них положительных - ' ,c) Из них положительных 2
goto m  

Не забывайте обнулять счетчик перед входом в цикл, а не то он начнет считать вам не с нуля, а бог знает с чего. Как бы вам понравилось, если бы таксист в начале поездки не обнулил счетчик?

В нашем фрагменте значения счетчика печатаются при каждом выполнении цикла. Изменим задачу.

Задача 2:В компьютер вводится ровно 200 чисел. Компьютер должен подсчитать и один раз напечатать, сколько среди них положительных.

Программа:

VAR c,i :Integer;

a :Real;

BEGIN

c:=0; {Обнуляем счетчик}

for i:=1 to 200 do begin

ReadLn(a);

if a>0 then c:=c+1

end {for};

WriteLn('Из них положительных - ' ,c)

END.

Пояснения:Путь рассуждений здесь тот же, что и в первой задаче. В результате применения оператора for фрагмент ReadLn(a);if a>0 then c:=c+1 выполняется ровно 200 раз, благодаря чему счетчик с накапливает нужное значение. Оператор WriteLn выполняется только один раз и печатает это значение.

Совет: Если вы запускаете эту программу в компьютере, то с числом 200 возиться крайне долго. Поменяйте его на 3 или 4. Смысл программы от этого не изменится.

 

Задание 46: Что будет, если

1) Вместо c:=0 написать c:=10.

2) Вместо c:=c+1 написать c:=c+2.

3) Строки end {for} и WriteLn поменять местами.

4) Строки c:=0 и for поменять местами.

5) Строки for и ReadLn поменять местами.

Задача 3:В компьютер один за другим вводятся произвольные символы. Ввод заканчивается символом "/". Подсчитать, какой процент от общего числа введенных символов составляют символ "W" и символ ":" по отдельности.

Здесь мы организуем три счетчика одновременно: сW и сDv - для подсчета букв W и двоеточий соответственно, а также i - счетчик циклов, то есть общего числа введенных символов.

Программа:

VAR i,cW,cDv, procent_W, procent_Dv : Integer;

simvol :Char;

Begin

i:=0; cW:=0; cDv:=0; {Обнуляем все три счетчика}

repeat {Повторяй цикл}

ReadLn (simvol); {Введи символ}

i:=i+1; {«Посчитай» его}

case simvol of

'W' :cW:=cW+1; {Если это W, увеличь счетчик символов W}

':' :cDv:=cDv+1 {Если это :, увеличь счетчик символов :}

End

until simvol = '/'; {пока не наткнешься на символ /}

procent_W :=Round(100*cW/i); {Вычисляй процент символов W}

procent_Dv :=Round(100*cDv/i); {Вычисляй процент символов :}

WriteLn(procent_W,' ',procent_Dv)

End.

Задание 47: В компьютер вводится N чисел. Подсчитать по отдельности количество отрицательных, положительных и тех, что превышают число 10.

Задание 48: В компьютер вводятся пары целых чисел. Подсчитать, сколько среди них пар, дающих в сумме число 13. Подсчет закончить после ввода пары нулей.

Напомню, что пару чисел можно ввести оператором ReadLn(a,b).

Сумматоры

Если вы поняли идею счетчика, то понять идею сумматора вам будет нетрудно. Посмотрим, как будет работать следующий фрагмент:

s:=0; {Обнуляем сумматор. Это не менее важно, чем обнулить счетчик}

m: ReadLn(a);

s:=s+a; {Увеличиваем сумматор}

WriteLn(‘Сумма=’, s);

goto m;

 

Пусть мы вводим числа 8, 4, 10 . . . В этом случае порядок выполнения операторов будет такой:

Оператор а s Печать
s:=0 ?  
ReadLn(a)  
s:=s+a  
WriteLn(‘Сумма=' ,s) Сумма=8
goto m  
ReadLn(a)  
s:=s+a  
WriteLn(‘Сумма=' ,s) Сумма=12
goto m  
ReadLn(a)  
s:=s+a  
WriteLn(‘Сумма=' ,s) Сумма=22
goto m  
……….      

Как видите, в ячейке s накапливается сумма вводимых чисел a, поэтому назовем эту ячейку сумматором. Отличие сумматора от счетчика в том, что счетчик увеличивается на 1 оператором c:=c+1, а сумматор - на суммируемое число оператором s:=s+a.

Задача: В компьютер вводится N чисел. Вычислить и один раз напечатать их сумму.

Программа:

VAR i,N :Integer;

a,s :Real;

BEGIN

ReadLn(N);

s:=0;

for i:=1 to N do begin

ReadLn(a);

s:=s+a

end {for};

WriteLn(‘Сумма равна ' ,s:20:10)

END.

Задание 49: Пусть N=2, a=5 и 3. Тогда по этой программе Паскаль напечатает 8. Что он напечатает, если:

1) Вместо s:=0 написать s:=10.

2) Вместо s:=s+a написать s:=s+a+1.

3) Строки end {for} и WriteLn поменять местами.

4) Строки s:=0 и for поменять местами.

5) Строки for и ReadLn поменять местами.

6) Строки s:=s+a и end {for} поменять местами.

7) Вместо for i:=1 to N написать for i:=2 to N.

Задания 50-52: Написать программы для следующих задач:

50) Во дворце 40 залов. Известны длина и ширина каждого зала. Вычислить площадь пола всего дворца.

51) Вычислить средний балл учеников вашего класса по физике.

52) Вычислить произведение N произвольных чисел.



©2015- 2019 stydopedia.ru Все материалы защищены законодательством РФ.