Egorova1
.pdfДаны вещественные числа a, b, c, d. Если a ≤b ≤c ≤d, то каждое из чисел заменить на наибольшее из них. Если a> b> c> d, то числа оставить без изменения, в противном случае все числа заменить их квадратами. Вывести исходные и преобразованные числа a,b,c,d.
N26.
Даны x, y (x=y). Меньшее из этих двух чисел заменить их суммой, а большее - их удвоенным произведением. Вывести исходные и полученные значения x, y.
N27.
Даны четыре целых числа a, b, c, d, представляющие собой числители и знаменатели двух дробей ba , dc .
Написать программу, выводящую одно из трех сообщений:
1)"первая дробь больше второй",
2)"вторая дробь больше первой",
3)"дроби равны", -
взависимости от отношения между дробями.
N28.
Даны три вещественных не равных между собой числа a, b, c. Переменной Y присвоить значение той переменной, которая находится между двумя другими на числовой оси. Например, если a=5, b=2, c=4, то ответ должен быть "Y=4".
N29.
Даны целые числа R,l. Если R ≠l, то заменить каждое из них одним и тем же числом, равным большему из исходных, а если R=l, то заменить числа нулями. Вывести их начальные и конечные значения.
N30.
Вычислить для заданных вещественных величин a, b, c:
= max(a,b) max(a,b, c)
Y a +b + c max(a2 ,b2 ).
N31.
Определить, верно ли, что при делении неотрицательного целого числа а на положительное целое число b получается остаток, равный одному из заданных чисел r или S.
2.7КОНТРОЛЬНЫЕ ВОПРОСЫ И ЗАДАНИЯ ПО МОДУЛЮ 2
2.7.1Простой, составной и пустой оператор - что это такое ?
2.7.2Что такое "скалярные типы данных"? По какому принципу сравниваются значения определенного скалярного типа ?
2.7.3Что представляет собой логическое выражение ?
2.7.4Логические операции - дайте их обозначение и таблицы истинности.
2.7.5Что представляет собой условный оператор IF (общая форма записи, реализуемый алгоритм, выполнение, примеры) ?
2.7.6Что представляет собой оператор выбора CASE (общая форма записи, реализуемый алгоритм, выполнение, примеры) ?
51
3 ОПЕРАТОРЫ ЦИКЛА (ПОВТОРЕНИЯ)
Цель изучения данного модуля - познакомиться с циклическими операторами, а также приобрести практический опыт разработки алгоритмов и программ циклической структуры.
Цикл - это многократное повторение некоторой последовательности операторов. Многократно повторяемый участок программы называется телом цикла. В правильно построенной программе цикл обычно повторяется при различных начальных значениях входящих в него переменных.
Для реализации циклов в Паскале существуют три оператора: WHILE, REPEAT, FOR. Циклы делятся на структурные и итерационные. Число повторений в структурном цикле задаётся до начала выполнения цикла. В программе структурный цикл реализуется
оператором FOR.
Число повторений итерационного цикла заранее не известно, выход из цикла происходит при выполнении некоторого условия, например, при достижении какой-либо переменной заданного значения. Различают итерационный цикл с предусловием (реализуется оператором WHILE) и с постусловием (реализуется оператором REPEAT).
3.1 ОПЕРАТОР ЦИКЛА С ПРЕДУСЛОВИЕМ WHILE
Оператор цикла с предусловием WHILE предназначен для реализации в программе итерационного цикла с предусловием. Выражение "предусловие" означает, что вначале проверяется некоторое условие, а затем, в соответствии с этим условием, выполняется тело цикла.
Общий вид оператора WHILE: WHILE L do S ,
где L - логическое выражение, условие выполнения цикла; S - оператор (простой, пустой или составной), тело цикла;
WHILE, do - ключевые слова ("while" - пока, "do" - делать, выполнять).
Дословный перевод оператора "While L do S" - пока выполняется условие L, повторять
оператор S. |
|
|
|
|
|
|
Оператор реализует следующий алгоритм. |
|
|
||||
|
|
|
|
Выражение L вычисляется перед каждым выполнением |
||
|
|
вход в цикл |
оператора S. Если выражение L имеет значение "истина" |
|||
|
|
|
F |
(true), то выполняется тело цикла S |
и управление опять |
|
|
L |
|
передаётся на вычисление выражения L; иначе, то есть если |
|||
|
|
|
||||
|
|
|
|
выражение L имеет значение "ложь" (false), тело цикла S не |
||
|
T |
|
|
выполняется и происходит выход |
из цикла. |
Если |
|
|
|
первоначальное значение выражения L - false, то тело цикла |
|||
|
|
|
|
|||
|
S |
|
|
S не выполнится ни разу. Если же выражение L |
всегда |
|
|
|
|
|
имеет значение true, то оператор S будет выполняться |
||
|
|
|
|
|||
|
|
выход из цикла |
бесконечное число раз, то есть произойдёт зацикливание |
|||
|
|
|
|
программы. |
|
|
Пример 1. Рассмотрим фрагмент программы, состоящий из двух операторов: оператора
присваивания "x:=abs(x)" и циклического оператора while. |
|
|
|
|
K |
Если x не равняется 0, то будут |
|||
var x:integer; |
выполняться |
операторы |
"c:=c+1/x; |
|
K |
x:=x-1" и управление передается на |
|||
x:=abs(x); |
проверку условия "x<>0". Как только |
|||
while x<>0 do |
это условие перестанет выполняться, |
|||
begin |
управление |
сразу |
же |
передается |
52
c:=c+1/x; |
оператору, следующему за словом end. |
x:=x-1; |
|
end; |
|
K |
|
Пример 2. |
|
Задание |
|
Даны числа a,b |
(предполагается, что a>1). Необходимо получить все члены |
бесконечной последовательности a, a 2 , a3 , a 4 K, меньшие заданного числа b.
Обозначения Дано: a,b - числа (real).
Результат: c - очередной член последовательности (real). Математическая постановка
Очередной член последовательности - это предыдущий член последовательности, умноженный на a. Условно это можно записать так:
Сновое = Сстарое*a; Структурная схема и программа
вход |
program prim2a; |
|
var a,b,c:real; |
||
|
||
|
begin |
|
ввод a,b |
readln(a,b); |
|
|
c:=a; |
|
|
while c<b do |
|
c = a |
begin |
|
|
writeln(c); |
|
|
||
F |
c:=c*a |
|
c < b |
end |
|
T |
end. |
|
|
||
|
|
|
вывод с |
|
|
|
|
|
|
|
|
c = c a |
|
|
|
|
выход
Пример 3.
Задание Написать программу вычисления наибольшего общего делителя (НОД) двух заданных
натуральных чисел a и b. Алгоритм
Если числа равны, то в качестве НОД взять любое из них, например a.
Если числа не равны, то большее из чисел заменить разностью большего и меньшего числа и начать исполнять данный алгоритм сначала.
Структурная схема |
Программа |
|
вход |
program prim3; |
|
|
var a,b:integer; |
|
ввод a, b |
begin |
|
writeln('Введите два натуральных числа: '); |
||
|
||
1 |
readln(a,b); |
|
while(a<>b) do |
||
|
if a>b then a:=a-b |
53
1
|
|
F |
|
else b:=b-a; |
|
a≠b |
|
write('НОД чисел равен ',a) |
|
|
|
|
end. |
|
|
|
|
|
|
|
T |
|
|
|
T |
a>b |
F |
|
|
|
|
|
|
|
|
|
|
|
|
a=a-b |
|
|
b=b-a |
|
|
|
|
|
|
вывод a
выход
Пример 4. Рассмотрим оператор While, который часто используется для того, чтобы в конце работы программы задержать изображение экрана пользователя с результатами работы до нажатия любой клавиши.
...
writeln('Для окончания работы нажмите любую клавишу'); While Not KeyPressed do;
...
В данном случае используется стандартная функция KeyPressed, которая описана в стандартном модуле Crt. Функция возвращает логический результат:
true - если на клавиатуре нажата клавиша, false - в противном случае.
Функция KeyPressed не распознает клавиш перевода регистра, таких как Shift, Alt, NumLock.
Замечание. Иногда для задержки экрана используют стандартную функцию Readkey в виде :
Readkey;
Эта функция считывает символ с клавиатуры без отображения на экран. Если перед обращением к функции Readkey функция Keypressed имела значение true, то символ считывается немедленно, в противном случае функция ожидает нажатия клавиши.
3.2 ОПЕРАТОР ЦИКЛА С ПОСТУСЛОВИЕМ REPEAT
Оператор цикла с постусловием REPEAT предназначен для реализации в программе итерационного цикла с постусловием. Выражение "постусловие" означает, что вначале выполняется тело цикла, а затем проверяется условие того, выполнять ли тело цикла еще раз.
Общий вид оператора REPEAT: REPEAT S until L ,
где L - логическое выражение, условие выполнения цикла; S - оператор (простой, пустой или составной), тело цикла;
REPEAT, until - ключевые слова ("repeat" - повторять, "until" - до тех пор пока).
Дословный перевод оператора "Repeat S until L" - повторять оператор S до тех пор, пока не будет выполнено условие L.
Оператор реализует следующий алгоритм.
Тело цикла S выполняется хотя бы один раз. Затем
S |
54 |
|
|
вычисляется выражение L. Если его значение - это "ложь" (false), то тело цикла S вновь выполняется; иначе, то есть если выражение L имеет значение "истина" (true), оператор REPEAT завершает свою работу. Если значение выражения L - true с самого начала выполнения оператора, то тело цикла S выполнится один раз. Если же выражение L будет всегда иметь значение false, то оператор S будет выполняться бесконечное число раз, то есть произойдёт зацикливание программы.
Замечание. Для составного оператора S операторные скобки BEGIN...END не являются обязательными, так как соответствующая группа операторов уже ограничена служебными словами REPEAT...UNTIL.
Пример 1. Рассмотрим фрагмент программы, состоящий из двух операторов: оператора присваивания "x:=abs(x)" и циклического оператора repeat.
K |
Сначала выполнятся операторы "c:=c+1/x; |
var x:integer; |
x:=x-1", затем проверяется условие "x=0". |
K |
Если x<>0, то повторяются указанные |
x:=abs(x); |
операторы; иначе, если x=0, управление |
repeat |
передаётся оператору, следующему за |
c:=c+1/x; |
строкой "until x=0". |
x:=x-1; |
|
until x=0; |
|
K |
|
Задание
Даны числа a,b (предполагается, что a>1). Необходимо получить все члены бесконечной последовательности a, a 2 , a3 , a 4 K, меньшие заданного числа b.
Обозначения Дано: a,b - числа (real).
Результат: c - очередной член последовательности (real). Математическая постановка
Очередной член последовательности - это предыдущий член последовательности, умноженный на a. Условно это можно записать так:
Сновое = Сстарое*a; Замечание
Данная задача была решена с помощью оператора while в примере 2 в п.3.1. Ниже для сравнения приведены два текста программы для решения данной задачи: слева - с оператором while, справа - с оператором repeat.
|
Программы |
program prim2a; |
program prim2b; |
var a,b,c:real; |
var a,b,c:real; |
begin |
begin |
readln(a,b); |
readln(a,b); |
c:=a; |
c:=a; |
while c<b do |
repeat |
begin |
writeln(c); |
writeln(c); |
c:=c*a; |
c:=c*a; |
until c>=b; |
end; |
end. |
end. |
|
Пояснение |
|
55
Вторая программа с оператором repeat для данного случая не совсем корректна, так как если a>b с самого начала, то это значение a всё равно будет распечатано (repeat - цикл с постусловием). В этом случае необходимо перед циклом repeat сделать дополнительную проверку с помощью оператора if.
Пример 3.
Задание
Дано целое (не более, чем четырёхзначное) положительное число n. Определить старшую цифру числа n.
|
Алгоритм |
|
|
Возьмём целое положительное число n, содержащее не более 4-х знаков. |
|
1. |
Делим n нацело на 1000: |
|
|
a:=n div 1000. |
|
|
Если a<>0, то нашли старшую цифру; конец алгоритма. |
|
|
Если a=0, то число содержит менее 4-х знаков; продолжаем алгоритм. |
|
2. |
Делим n нацело на 100: |
|
|
a:=n div 100. |
|
|
Если а<>0, то нашли старшую цифру; конец алгоритма. |
|
|
Если a=0, то число содержит менее 3-х знаков; продолжаем алгоритм. |
|
3. |
Продолжим аналогично, пока не получим a<>0. |
|
|
Структурная схема |
Программа |
|
в х о д |
|
в в о д |
n |
|
c = 1 0 0 0 0 |
|
|
c = c |
d i v |
1 0 |
a = n |
d i v |
c |
F |
a < > 0 |
|
|
||
|
T |
|
в ы |
в о д |
a |
|
в ы х о д |
program prim3; var c,a,n:integer; begin
write('Введите целое положит. число (не более
4-х цифр): '); readln(n); c:=10000; repeat
c:=c div 10; a:=n div c; until (a<>0);
writeln('Число: ',n,' старшая цифра: ',a) ; end.
Замечание
Изменим условие. Пусть n>=0, то есть возможна ситуация, когда n=0. В этом случае, чтобы избежать зацикливания, необходимо по концу цикла проверять сложное условие "a<>0 или c=1" вместо "a<>0". Изменение в программе: вместо строки "until (a<>0)"
следует записать "until (a<>0) or (c=1)".
Пример 4. Ниже приведен фрагмент диалога программы с пользователем. Программа
ждёт от пользователя ввода только знака-цифры.
K
var сh:char;
K.
repeat
write('Введите цифру: '); readln(ch);
until (ch>='0') and (ch<='9');
K
56
Пример 5. Ниже приведен фрагмент диалога программы с пользователем. Программа ждёт от пользователя ответа в виде 'y' или ‘n' ('y' - да (yes), 'n' - нет (no)). Пока пользователь не введет один из требуемых ответов, программа "циклит" за счет оператора
repeat.
K
var h:char;
K
repeat
write('Ответ? (y/n): '); readln(h);
until (h='y') or (h='n');
K
Пример 6. Ниже приведен фрагмент диалога программы с пользователем. Программа ждет от пользователя ввода значения переменной x в определенном интервале,
например: 0<x<1.
K
var x:real;
K
repeat
write('Введите x (0<x<1): '); readln(x);
until (x>0) and (x<1);
K
Пример 7. В примере 4 в п.3.1 рассмотрен оператор
While Not KeyPressed do;
который часто используется для того, чтобы в конце работы программы задержать изображение экрана пользователя с результатами работы до нажатия любой клавиши. Для
этой же цели можно использовать следующий оператор repeat:
K
writeln('Для окончания работы нажмите любую клавишу');
Repeat Until KeyPressed;
K
3.3 ОПЕРАТОР ЦИКЛА С ПАРАМЕТРОМ FOR
Оператор цикла с параметром FOR предназначен для реализации в программе структурного цикла.
Оператор FOR имеет две формы:
1) For i:=A to C do S - это цикл по возрастающим значениям параметра цикла i;
2)For i:=A downto C do S - это цикл по убывающим значениям параметра цикла i. Здесь:
i- переменная, параметр цикла (иногда называют "счетчик цикла");
A - выражение, определяющее начальное значение параметра цикла i; C - выражение, определяющее конечное значение параметра цикла i; S - оператор (простой, пустой или составной оператор), тело цикла;
For, to, downto, do - ключевые слова("for" - для, "to" - вверх до, "downto" - вниз до, "do" -
выполнять).
Переменная i и выражения A, C должны быть одного и того же скалярного типа (но не real).
Дословный перевод оператора "For i:=A to(downto) C do S" - для каждого значения i, изменяющегося от A до C (to - по возрастанию, downt - по убыванию), повторять оператор S.
57
Выполнение оператора. Переменная i принимает последовательные значения от A до C, при этом для каждого значения i выполняется тело цикла S.
Если A,C,i - целого типа, то шаг, с которым значение переменной i последовательно изменяется от A до C, всегда равен +1 (оператор for...to) или -1 (оператор for...downto). В этом случае имеем следующие структурные схемы для оператора FOR:
1)For i:=A to C do S; |
2)For i:=A downto C do S; |
||||||
|
|
вход в цикл |
|
|
вход в цикл |
||
|
|
|
|
|
|
||
* |
i = a |
|
* |
i = a |
|
||
|
|
|
|
|
|
||
|
* |
F |
|
* |
F |
||
|
i |
≤ c |
|
i |
≥ c |
||
|
T |
|
|
|
T |
|
|
|
|
S |
|
|
|
S |
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
* |
i = i + 1 |
|
* |
i = i - 1 |
|
||
|
|
|
|
|
|
||
|
выход из цикла |
|
выход из цикла |
||||
|
|
|
|
Переменная i последовательно принимает значения: 1)A,A+1,A+2,...,C, 2)A,A-1,A-2,...,C;
причём для каждого из этих значений выполняется тело цикла S.
Блоки, отмеченные на структурной схеме значком "*", выполняются самим оператором FOR и специально программировать их не нужно, поэтому иногда в структурных схемах
для изображения алгоритма, реализуемого |
оператором |
FOR, используется более |
|||||
компактный блок цикла: |
|
|
|
|
|
||
1)For i:=A to C do S; |
2)For i:=A downto C do S; |
||||||
|
вход |
|
|
вход |
|
||
|
i = a,c;+1 |
|
|
i = a,c;-1 |
|
||
|
|
|
|
|
|
|
|
|
S |
|
|
|
S |
|
|
|
|
|
|
|
|
|
|
|
выход |
|
|
выход |
|
||
Если A,C,i - символьного типа и, например, |
A='a'; C='z', то для оператора |
||||||
"For i:=A to C do S" переменная |
i принимает последовательные значения в порядке |
||||||
латинского алфавита. |
|
|
|
|
|
||
Замечания: |
|
|
|
|
|
1)внутри цикла FOR не следует изменять ни начальное, ни конечное значение переменной цикла (A и C), а также и текущее значение переменной цикла i;
2)переменная i не должна входить в выражения A и C;
3)если в цикле FOR...TO начальное значение A больше конечного значения C, то цикл не выполнится ни разу; аналогично для цикла FOR...DOWNTO, если A меньше C;
4)после завершения цикла значение переменной i становится неопределённым, поэтому не следует использовать значение счётчика цикла после выхода из него.
Пример 1.
Задание
Дано число x. Напечатать: x2 , x4 , x8 , x16 , x32 .
58
Пояснение Необходимо вычислить и напечатать 5 значений. Значит, параметр цикла, назовем его
n, будет меняться от 1 до 5. Ниже представлено две программы решения задачи: в программе слева использован оператор for...to, в программе справа - оператор for...downto.
Программы |
|
program prim1_1; |
program prim1_2; |
var x:real; |
var x:real; |
n:integer; |
n:integer; |
begin |
begin |
readln(x); |
readln(x); |
for n:=1 to 5 do |
for n:=5 downto 1 do |
begin |
begin |
x:=x*x; |
x:=x*x; |
writeln(x); |
writeln(x); |
end; |
end; |
end. |
end. |
Пример 2. |
|
Задание
Дано целое положительное число n. Вычислить факториал n, то есть n!=1*2*3*...*n. Обозначения
Дано: n - число (integer)
Результат: fakt - значение n! (integer) Промежуточные данные: i - счетчик цикла (integer)
Структурная схема
вход |
Здесь i - счетчик цикла. Начальное значение i равно |
|||
|
||||
ввод n |
1; после каждого вычисления тела |
цикла |
(блок |
|
"fakt=fakt*i") значение i увеличивается на 1. |
||||
|
||||
|
Вычисления в цикле повторяются, |
пока |
i ≤n; |
|
fakt = 1 |
конечное значение i равно n. |
|
|
|
|
В данном случае цикл повторится n раз: |
|
|
|
|
|
|
i = 1 |
|
1-ое выполнение цикла: |
||
|
|
|
i=1 |
fakt=fakt*1=1*1=1! |
|
|
|
||
i ≤ n |
F |
2-ое выполнение цикла: |
||
|
i=2 |
fakt=fakt*2=1!*2=2! |
||
T |
|
|||
|
3-е выполнение цикла: |
|||
fakt=fakt i |
|
i=3 |
fakt=fakt*3=2!*3=3! |
|
|
|
|
|
M |
|
|
|
|
|
|
|
|
n-ое выполнение цикла: |
|
i=i+1 |
|
|||
|
|
|
i=n |
fakt=fakt*n=(n-1)!*n=n! |
|
|
|
вывод fakt
выход
Для того, чтобы первое выполнение цикла прошло успешно, необходимо до
выполнения цикла в переменную fakt |
записать начальное значение произведения, равное |
1 (умножение на 1 не изменит значение конечного результата): блок "fakt=1". |
|
Блоки СС "i=1", "i ≤n", "i=i+1" |
реализуются оператором for и специально |
программировать их не надо, поэтому подобную СС можно изобразить более компактно с помощью специального блока структурного цикла, имеющего следующий вид:
59
Тогда получим следующую СС и программу.
вход |
program facter(i,o); |
|
|
var i,n,fakt:integer; |
|
ввод n |
begin |
|
write('Введите целое число n: '); |
||
|
||
|
readln(n); |
|
fakt = 1 |
fakt:=1; |
|
|
for i:=1 to n do |
|
|
||
i = 1, n,+1 |
fakt:=fakt*i; |
|
|
writeln('n=',n,' n!=',fakt) |
|
|
end. |
|
fakt=fakt i |
||
вывод fakt |
|
|
выход |
|
Пример 3.
Задание Составить фрагмент структурной схемы для вывода всех четных чисел, не
превосходящих заданного числа n, n>2.
Структурная схема (фрагмент)
. . .
k = 2
F
k ≤ n T
вывод k
k=k+2
СС слева очевидна для решения данной задачи, но использовать оператор for для нее нельзя, так как в операторе for счетчик k должен изменяться на единицу а в схеме слева он изменяется на двойку. Поэтому перейдем к эквивалентной схеме, изображенной справа, в которой счетчик i изменяется на единицу. Программная реализация этого алгоритма: for i:=1 to n div 2 do writeln(2*i);
. . .
i = 1
i ≤ndiv2 F
T
вывод 2 i
i=i+1
. . . |
. . . |
Замечание В данном случае можно было воспользоваться стандартной функцией Турбо-Паскаля
odd:
true, еслиi - нечетно, odd( i ) =
false, еслиi - четно,
где тип аргумента i - integer;
тип результата odd( i ) - boolean.
Тогда:
for i:=1 to n do
if odd( i )=false then writeln(i);
Пример 4.
Задание
60