4. Условный оператор

advertisement
Евгений Волосатов
program Turbo_Pascal;
begin
writeln ('Учебный курс')
end.
Висагинас
2003
Евгений Волосатов
2
Turbo Pascal
Магистр информатики
Волосатов Евгений Витольдович
Turbo Pascal. Учебный курс
Ознакомление с основами программирования
на примере языка Turbo Pascal
Замечания и предложения присылайте по адресу: pascal@dkd.lt
Объём: 60 стр. Тираж: 20 экз.
Висагинас, Литва
Май 2003 года
Евгений Волосатов
3
Turbo Pascal
Учебный курс языка
Turbo Pascal
Содержание
1.
1.1.
1.2.
1.3.
1.4.
1.5.
1.6.
1.7.
1.8.
2.
2.1.
2.2.
2.3.
3.
3.1.
3.2.
3.3.
3.4.
4.
4.1.
4.2.
4.3.
4.4.
4.5.
4.6.
4.7.
Первая программа ........................................... 5
ЧТО ТАКОЕ ПРОГРАММА? ........................................................................... 5
ИМЕНА ....................................................................................................... 5
ЗАРЕЗЕРВИРОВАННЫЕ СЛОВА .................................................................... 6
ПЕРЕМЕННЫЕ ............................................................................................. 6
КОНСТАНТЫ ............................................................................................... 7
СТАНДАРТНЫЕ МАТЕМАТИЧЕСКИЕ ОПЕРАЦИИ ......................................... 7
ОПЕРАТОР ПРИСВАИВАНИЯ ....................................................................... 8
ПРИМЕР ПРОГРАММЫ ................................................................................. 9
Операторы ввода и вывода. ............................ 9
ОПЕРАТОР ВВОДА READLN ......................................................................... 9
ОПЕРАТОР ВЫВОДА WRITE ....................................................................... 10
САМОСТОЯТЕЛЬНЫЕ ЗАДАНИЯ ................................................................ 12
Работа с цифрами ......................................... 12
ВЫДЕЛЕНИЕ ЦИФР ЧИСЛА ........................................................................ 12
КОНСТРУИРОВАНИЕ ЧИСЛА ПО ЕГО ЦИФРАМ .......................................... 12
ОБОБЩЕНИЕ ............................................................................................. 13
САМОСТОЯТЕЛЬНЫЕ ЗАДАНИЯ ................................................................ 13
Условный оператор........................................ 14
ЧТО ТАКОЕ УСЛОВИЕ................................................................................ 14
УКОРОЧЕННЫЙ ВАРИАНТ УСЛОВНОГО ОПЕРАТОРА ................................. 16
СОСТАВНОЙ ОПЕРАТОР ............................................................................ 16
СОСТАВНЫЕ УСЛОВИЯ ............................................................................. 17
ВЛОЖЕННЫЕ УСЛОВНЫЕ ОПЕРАТОРЫ ...................................................... 18
ОПЕРАТОР ВЫБОРА CASE .......................................................................... 18
САМОСТОЯТЕЛЬНЫЕ ЗАДАНИЯ ................................................................ 20
Евгений Волосатов
5.
ОБЩИЙ ОБЗОР СТАНДАРТНЫХ ТИПОВ. ......................................................20
ЦЕЛЫЕ ТИПЫ .............................................................................................21
ВЕЩЕСТВЕННЫЕ ТИПЫ .............................................................................22
ЛОГИЧЕСКИЙ ТИП .....................................................................................26
СИМВОЛЬНЫЕ ТИПЫ .................................................................................26
Подпрограммы ............................................... 29
ЗАЧЕМ НУЖНЫ ПОДПРОГРАММЫ? ............................................................29
ПРОЦЕДУРЫ ..............................................................................................29
АРГУМЕНТЫ ПРОЦЕДУРЫ ..........................................................................31
РЕЗУЛЬТАТЫ ПРОЦЕДУРЫ .........................................................................32
ФУНКЦИИ ..................................................................................................33
САМОСТОЯТЕЛЬНЫЕ ЗАДАНИЯ .................................................................34
6.1.
6.2.
6.3.
6.4.
6.5.
6.6.
7.
Циклы ............................................................. 34
ЦИКЛ FOR...................................................................................................35
НАХОЖДЕНИЕ СУММЫ ..............................................................................38
НАХОЖДЕНИЕ ПРОИЗВЕДЕНИЯ .................................................................39
НАХОЖДЕНИЕ КОЛИЧЕСТВА .....................................................................39
ЦИКЛ WHILE ..............................................................................................40
ЦИКЛ REPEAT ... UNTIL........................................................................41
СРАВНЕНИЕ ЦИКЛОВ .................................................................................42
САМОСТОЯТЕЛЬНЫЕ ЗАДАНИЯ .................................................................43
7.1.
7.2.
7.3.
7.4.
7.5.
7.6.
7.7.
7.8.
8.
Натуральные числа ...................................... 44
ДЕЛИТЕЛИ ЧИСЕЛ ......................................................................................44
ПРОСТЫЕ ЧИСЛА .......................................................................................45
НАИБОЛЬШИЙ ОБЩИЙ ДЕЛИТЕЛЬ .............................................................46
НАИМЕНЬШЕЕ ОБЩЕЕ КРАТНОЕ ................................................................46
8.1.
8.2.
8.3.
8.4.
9.
Turbo Pascal
Стандартные типы переменных .................. 20
5.1.
5.2.
5.3.
5.4.
5.5.
6.
4
Массивы ......................................................... 47
9.1.
9.2.
9.3.
10.
10.1.
10.2.
10.3.
10.4.
10.5.
ОПРЕДЕЛЕНИЕ И ПРИМЕРЫ .......................................................................47
ОПЕРАЦИИ С ЭЛЕМЕНТАМИ МАССИВА .....................................................49
АНАЛИЗ ИНФОРМАЦИИ В МАССИВЕ..........................................................51
Рекуррентные соотношения ...................... 52
ПОСЛЕДОВАТЕЛЬНОСТЬ ФИБОНАЧЧИ...................................................52
ДРУГИЕ РЕКУРРЕНТНЫЕ ПОСЛЕДОВАТЕЛЬНОСТИ .................................53
ОПТИМИЗАЦИЯ ПРОГРАММ ...................................................................54
ЗАДАЧА ПРО ИНТЕЛЛИГЕНТНОГО СТУДЕНТА ........................................55
САМОСТОЯТЕЛЬНЫЕ ЗАДАНИЯ .............................................................57
Приложение .......................................................... 57
Евгений Волосатов
1.
5
Turbo Pascal
Первая программа
1.1.
Что такое программа?
С помощью любого языка программирования создаются программы.
Программа – это последовательность действий, которые должен выполнить
компьютер в строго указанной очерёдности.
Любая программа на языке Pascal состоит из трёх частей: заголовка,
секции описания и операторной части. Как в кулинарном рецепте: название,
ингридиенты, порядок приготовления.
Ознакомимся с форматом записи программы:
program «Имя»;
const ...
type ...
var
...
procedure
function
;
;
;
... ;
... ;
begin
«оператор1» ;
...
«операторN»
end.
Заголовок программы
Секция описаний:
описание констант
описание типов
описание переменных
описание процедур
описание функций
Операторная часть
тело программы
Любая часть программы, кроме операторной части, может отсутствовать.
Операторная часть состоит из операторов – команд, которые выполняет
компьютер. Операторы отделяются друг от друга точкой с запятой.
1.2.
Имена
Текст программы записывается при помощи арабских цифр, 26 латинских
букв и специальных символов (например: +, –, *, /, ^, (, ), #, &).
В программе для обозначения переменных, названия программы,
названия процедур, функций и других объектов существуют имена.
Имя может состоять из любой последовательности букв и цифр, которая
начинается с буквы. Большие и маленькие буквы не различаются, поэтому все
следующие имена идентичны: kolobok, Kolobok, kOlObOk, KoloboK.
Евгений Волосатов
6
Turbo Pascal
В имени также можно использовать знак подчёркивания «_» для
разделения слов в одном имени, например: prosto_primer. Кстати, имя
может начинаться с подчёркивания: _drug.
Имя может быть любой длины, но Turbo Pascal считает значимыми
только первые 63 символа. Вот примеры правильных и неправильных имён.
Таблица 1. Примеры имён
Пример правильных имен:
A1
Jevgesha
end_of_work
integer
1.3.
a24mt_9
end_end
_zx_
write
Неправильные имена и пояснения
1a
begin
сумма
Dima&Masha
Начинается с цифры.
Это зарезервированное слово.
Использованы русские буквы.
Символ & не цифра и не буква.
Зарезервированные слова
В любой программе есть зарезервированные слова – стандартные слова
для обозначения блоков программы, например, блок описания переменных,
начало операторной части и др. Здесь и далее зарезервированные слова в
программах мы их будем подчёркивать.
Зарезервированные слова нельзя использовать в качестве имён.
Список наиболее часто используемых зарезервированных слов::
and
array
begin
сase
const
1.4.
div
do
downto
else
end
file
for
function
if
in
mod
not
of
or
procedure
program
repeat
string
then
to
until
uses
var
while
xor
Переменные
Данные, которыми оперирует компьютер, называются переменными.
Каждая переменная имеет своё собственное имя, которое используется для
доступа к данным.
Переменные бывают разных типов: целые числа, действительные числа,
символы, таблицы и др. Каждая переменная должна быть определена каким-то
одним типом, чтобы компьютер знал, какие действия можно производить с
этой переменной. Пока мы с вами будем работать только с данными целого
типа. Это тип integer.
В программе все переменные должны быть описаны в разделе описания
после служебного слова var в таком виде:
var «имя переменной» : «имя типа» ;
Здесь «имя переменной» – имя, которое будет использоваться для доступа
к данным; «имя типа» – имя типа, которым описывается указанная
переменная. Например:
var a : integer ;
Евгений Волосатов
7
Turbo Pascal
Если в программе используется несколько однотипных переменных, то их
можно описать все вместе:
var «имя п.1», «имя п.2», …, «имя п.N» : «имя типа»;
Например:
var a, b, x, y, z : integer ;
После описания переменной в компьютере для неё выделяется память,
где хранится её значение. В самом начале значение переменной не определено,
там может храниться любое значение.
1.5.
Константы
В программе кроме переменных можно использовать константы –
данные, которые не меняют своего значения во время работы программы.
Константы определяются перед описанием переменных после служебного
слова const:
const «имя константы» = «значение» ;
Например:
const chislo_pi = 3.1415926535897932 ;
dlina_ekvatora = 40000000 ;
В программе константы используются как обычные переменные за тем
исключением, что им нельзя ничего присваивать.
1.6.
Стандартные математические операции
В таблице перечислены основные операции, которые можно производить
над целыми числами.
Таблица 2. Знаки операций
Операция
+
–
*
div
mod
Название
Сложение
Вычитание
Умножение
Целочисленное деление
Выделение остатка
Пример
a + 5
4 – x
5 * d
17 div 5
17 mod 5
Обратите внимание на запись операции умножения: она обозначается
звёздочкой, которую пропускать ни в коем случае нельзя. Если в математике
возможна запись 2ab, то в Паскале надо записывать 2*a*b.
Из-за того, что при делении одного целого числа на другое может
получиться дробное число, в Паскале используют две операции деления для
целых чисел: операцию деления нацело (дробную часть от результата просто
откидывают) и операцию нахождения остатка. Вот несколько примеров с
этими операциями.
Евгений Волосатов
17 mod 5 = 2
32 div 11= 2
27 div 3 = 0
8
Turbo Pascal
17 div 5 = 3
10 mod 9 = 1
0 div 11= 0
28 mod 4 = 0
4 mod 5 = 4
0 div 3 = 0
Найдите в этих примерах одну ошибку! А еще не забывайте правило, что:
в информатике, как и в математике, на ноль делить нельзя!
Кроме знаков математических операций в выражениях можно использо–
вать функции. С функциями вы знакомы из алгебры: sin (x), cos (x), y(x) и т.д.
Для целых чисел в Паскале определены целочисленные функции вычисления
модуля abs (x) и возведения в квадрат sqr (x), например:
abs (12) результат 12,
abs (0) результат 0,
abs (-4) результат 4,
sqr (-5) результат 25,
sqr (3) результат 9,
sqr (0) результат 0.
Аргументом у этих функций может быть не только конкретное число, но и
любая целая переменная или даже выражение. Все эти функции и знаки
математических операций можно использовать совместно для создания
выражений любой сложности, например:
23 div a + abs (b)
sqr (a mod 4) + abs (b div 7)
sqr (sqr (2)) + abs (51 mod 17)
Найдите значения этих выражений, если a=7, b=–15.
1.7.
Оператор присваивания
Значение переменной можно изменять, записывая в неё новое значение.
Для этого используют оператор присваивания. Формат записи:
«имя переменной» := «выражение» ;
Здесь «имя переменной» – любое допустимое имя переменной,
которое предварительно было описано в разделе описания переменных;
«выражение» - выражение, в котором можно использовать знаки
математических действий, стандартные функции, имена переменных,
константы. Компьютер вычисляет значение этого выражения и записывает
полученный результат в ту переменную, что записана слева от знака :=.
Старое значение затирается новым и пропадает.
Допустим переменная а – целого типа (integer), тогда после оператора
a := 3;
в область памяти, которая выделена для переменной a запишется значение 3.
Если потом выполнить оператор
a := a + 1;
то компьютер сначала вычислит выражение справа от знака присваивания.
Вместо а он берёт значение, записанное в области памяти, выделенной для
Евгений Волосатов
9
Turbo Pascal
этой переменной, то есть число 3. К нему прибавляет 1, получает 4. Эту
четвёрку записывает обратно в память, где хранится значение переменной а.
При этом старое значение 3 бесследно исчезает.
Рассмотрим немного более сложный пример, уже с двумя переменными x
и y, которые определены целым типом integer.
x
y
x
y
x
:=
:=
:=
:=
:=
10;
x + 5;
x + y;
x + y;
y mod 3 + x div 7;
x=10
x=10
x=25
x=25
x= 4
y= ? (пока не определено)
y=15
y=15
y=40
y=40
Здесь вы видете две колонки. Слева колонка операторов присваивания,
которые выполняются поочерёдно. Справа – колонка со значениями
переменных, после выполнения каждого оператора.
1.8.
Пример программы
Теперь у нас уже достаточно знаний, чтобы составить первую работающую программу.Напишем программу для нахождения суммы двух чисел.
program Summa;
var a, b, s : integer;
begin
a := 7;
b := 15;
s := a + b;
writeln (s)
end.
заголовок программы
описание переменных
начало программы
определение начальных значений
вычисление суммы
печать результата на экран
конец программы
Оператор writeln выводит результат на экран.
2.
Операторы ввода и вывода.
Для общения компьютера с человеком или, по-другому, диалога,
необходимо, чтобы программа выводила на экран разную информацию и
запрашивала данные. Для этого существуют операторы ввода (readln) и
вывода (write) данных. Оформлять программы нужно для того, чтобы
пользователь всегда знал, в каком состоянии находится компьютер: ожидает
он ввод или производит расчёты. Согласитесь, что не очень приятно сидеть
перед чёрным экраном монитора и думать: «Что же тебе от меня надо?»
2.1.
Оператор ввода readln
Используя оператор readln можно вводить значения переменных с
клавиатуры во время работы программы. Вот как используют этот оператор:
readln («список переменных»);
Евгений Волосатов
10
Turbo Pascal
Здесь «список переменных» – одна или несколько переменных,
разделенные запятыми. Например:
readln (a);
readln (x, y);
В первом случае компьютер будет запрашивать ввод одной переменной.
Как только при выполнении программы компьютер встретит этот оператор,
работа приостановится и компьютер будет ждать ввода значения переменной с
клавиатуры. После того, как значение введено, надо нажать клавишу ENTER.
Во втором случае компьютер будет ожидать ввод двух чисел. Их значения
нужно ввести на одной строчке через пробел (пробел – это символ пропуска,
используемый для разделения слов друг от друга). Первое число будет
присвоено переменной x, второе – переменной y.
Оператор readln по своему характеру – молчаливый оператор. Он ничего
не выводит на экран перед началом своей работы. Просто молча ждёт, когда
пользователь догадается, что надо что-то вводить. Поэтому, чтобы ему было
веселее, его надо использовать в паре с оператором write, который выведет
на экран просьбу ввести нужные данные.
2.2.
Оператор вывода write
Нормальная работа с программой невозможно без вывода информации
на экран. Выводить на экран можно и нужно различные сообщения:
приветствия, подсказки, результаты подсчётов наконец. Для печати
сообщений на экран используется оператор вывода. Вот несколько способов
его записи:
write ;
write («число»);
write («строка»);
write («строка», «число», «строка», ... );
write («число», «число», «строка», «число», ... );
Здесь «число» – имя переменной, константа или, в общем случае,
математические выражение; «строка» – это любая последовательность
символов, заключенная в ’кавычки’. Строку символов выводят на экран как
дополнительную информацию (подсказку). Примеры:
write
write
write
write
(22);
(day);
(year*365);
(’Всем привет!’);
В операторе write можно использовать несколько аргументов, в этом
случае они разделяются запятыми. Например:
write (’Поздравляем с Новым ’, year, ’ годом!’);
Евгений Волосатов
11
Turbo Pascal
В зависимости от значения переменной year на экран будет выводиться
соответствующая строка. Например, если year равно 2000, то компьютер
при выполнении этой строки напечатает:
Поздравляем с Новым 2000 годом!
Другая разновидность оператора write – оператор writeln. Чтоб
понять, чем они отличаются друг от друга, надо ввести понятие курсора –
маленького мигающего прямоугольника на экране.
Курсор – это особым образом помеченная позиция
экрана, в которую будет напечатан следующий символ.
Любое сообщение выводится на экран посимвольно (то есть по одному
символу). После вывода на экран каждого символа курсор смещается вправо,
указывая место для следующего символа. После выполнения оператора write
курсор оказывается в конце выведенной фраз. А оператор writeln
дополнительно переводит курсор на начало новой строки. Эффект различия
этих операторов скажется при следующей попытке вывода на экран.
Теперь мы уже умеем вводить и выводить данные, поэтому давайте
будем в каждой составляемой программе использовать эти возможности!
Составим, например, программу для ввода двух чисел и нахождения их
суммы, стараясь красиво оформить диалог компьютера с пользователем.
program Summa_s_dialogom;
var a, b, s : integer;
begin
write (’Введите два целых числа через пробел: ’);
readln (a, b);
s := a + b;
writeln (’Сумма чисел ’, a, ’ и ’, b, ’ равна ’, s)
end.
В последнем операторе writeln выделены строки символов. Они
выводятся на экран без изменений. А вместо имен a, b, s выводятся
настоящие значения этих переменных, которые хранятся в памяти
компьютера.
Обратите внимание на расстановку пробелов в символьных строчках
(которые помечены). Если убрать «лишние» пробелы в начале и в конце фраз,
то в выводимом на экран тексте не будет разделения между буквами и
числами. Будет что-то вроде такого:
Сумма чисел10и15равна25
Евгений Волосатов
2.3.



3.
12
Turbo Pascal
Самостоятельные задания
Составьте программу, которая выведет на экран вашу визитную карточку.
Даны два года: g1, g2 (эти числа вводятся с клавиатуры). Написать,
сколько между ними лет.
Дано: год и месяц начальной даты; год и месяц конечной даты.
Вычислить, сколько месяцев между этими датами.
Работа с цифрами
Мы уже рассмотрели стандартные операции, которые можно производить
с целыми (integer) числами. Теперь разберём основные типы задач, которые
решаются с использованием этих операций, а именно: работа с цифрами числа.
3.1.
Выделение цифр числа
Используя операции деления mod и div можно выделять нужные цифры
числа. Проще всего выделить последнюю цифру числа, для этого надо найти
остаток от деления числа на 10, например:
3456 mod 10 = 6 – последняя цифра числа 3456
Теперь давайте попробуем найти предпоследнюю цифру. Существует два
способа решения этой задачи:
Первый способ сводится к нахождению последней цифры числа. Для этого
надо сначала «отбросить» правую цифру в исходном числе, тогда искомая
цифра окажется последней. А последнюю цифру мы умеем находить. Как же
«отбросить» последнюю цифру? Очень просто, надо число поделить на 10:
3456 div 10 = 345 - начальное число без последней цифры
Теперь выделим последнюю цифру нового числа:
345 mod 10 = 5 - искомая предпоследняя цифра!
Теперь объединим эти два действия в одну строчку:
3456 div 10 mod 10 = 5.
Во втором способе мы подойдём к числу с другой стороны и выделим
сначала две крайние правые цифры, получим двузначное число:
3456 mod 100 = 56
Теперь от этого двузначного числа надо «отбросить» последнюю цифру:
56 div 10 = 5
Вот и всё. Осталось только объединить эти два действия в одну строчку:
3456 mod 100 div 10 = 5
Ещё раз самостоятельно разберите эти примеры и попробуйте выделить
третью с конца цифру двумя способами.
3.2.
Конструирование числа по его цифрам
Как из цифр числа составить само число?
Евгений Волосатов
13
Turbo Pascal
Может быть помните, как в 4-ом классе на уроке математики расписывали
числа по разрядам:
89743 = 8*10000 + 9*1000 + 7*100 + 4*10 + 3
В чём суть этого равенства? В том, что можно числа собирать из цифр, как
машинку из деталей конструктора. Например, у нас есть три переменные a,
b, c, в которых записаны цифры трёхзначного числа, которое символически
можно обозначить так: (abc). Тогда собрать по цифрам это число можно так:
chislo := 100*a + 10*b + c
Например, если a=3, b=7, c=1, то
(abc) = 100*3 + 10*7 + 1 = 371
Попробуйте аналогичным образом собрать следующие числа из их цифр:
(abcd)
(cd)
(dbase)
(snickers)
(dardva)
3.3.
Обобщение
Зная, как доставать из числа цифры и как конструировать число по его
цифрам можно решать задачи вот такого типа:
Дано трёхзначное число, переписать его цифры в обратном порядке.
Общий принцип решения задания: сначала выделяем все цифры числа,
потом собираем их в нужном порядке. Эта идея реализована в следующей
программе, где цифры числа хранятся в переменных c1, c2, c3.
program Zadom;
var a, c1, c2, c3, rez : integer;
begin
readln (a);
{ Вводим трёхзначное число }
c3 := a mod 10;
{ Выделяем третью цифру }
c2 := a div 10 mod 10;
{ Выделяем вторую цифру }
c1 := a div 100;
{ Выделяем первую цифру }
rez := c3*100 + c2*10 + c1 { Конструируем нужное число из цифр }
end.
Фразы, записанные в {фигурных} скобках, называются комментариями.
Комментарии не обрабатываются компьютером, но служат подсказками для
человека, читающего программу.
3.4.
1.
2.
3.
4.
5.
6.
Самостоятельные задания
В трёхзначном числе поменять местами первую и среднюю цифры.
В середину двузначного числа вставить две двойки.
Из трёхзначного числа «вычеркнуть» среднюю цифру.
Выделить из семизначного числа среднюю цифру.
В семизначном числе поменять местами 2 и 5 цифры, а также 3 и 4.
В пятизначное число вставить двойку после первой цифры и
вычеркнуть предпоследнюю цифру.
Евгений Волосатов
4.
14
Turbo Pascal
Условный оператор
Программы, которые мы составляли до сих пор, можно сравнить с
автомобилем, который может ехать только прямо. Далеко на таком автомобиле
не уедешь. Надо уметь поворачивать. Для таких «поворотов» используется
условный оператор if. Он позволяет изменять ход выполнения программы, в
зависимости от некоторых условий.
Формат записи условного оператора:
if «условие»
then «оператор1»
else «оператор2»
Здесь «условие» – некоторое утверждение, относительно которого
можно сказать: истинно оно или ложно. При выполнении условного оператора
компьютер проверяет «условие». Если оно верно, то выполняется
«оператор1», после чего выполнение условного оператора завершается. Если
условие не верно, то компьютер выполняет «оператор2».
4.1.
Что такое условие
Итак, условие или высказывание – это некоторое
относительно которого можно сказать: истинно оно или ложно.
утверждение
Примеры высказываний: “светит солнце”; “мне сейчас хорошо”; “сегодня
пятница триннадцатое”. Относительно любого из упомянутых высказываний
можно сказать: истинны они или нет на данный момент. А вот фраза: “сколько
тебе лет?” высказыванием не являются, так как требуют более подробного
ответа, чем "Да" или "Нет". Приведите несколько примеров высказываний.
Теперь посмотрим, что может быть высказыванием (условием) в языке
программирования. Самый простой случай – это сравнение двух чисел,
например, утверждение «5 больше, чем 3» – это утверждение истинно. Все эти
условия и способы их записи в языке Pascal приведены в таблице:
Таблица 3. Математические условия
Математическая запись
a=b
a>b
a<b
a≥b
a≤b
a≠b
Наименование
равно
больше
меньше
больше или равно
меньше илии равно
не равно
Запись в языке Pascal
a
a
a
a
a
a
= b
> b
< b
>= b
<= b
<> b
В языке Pascal существуют условия-константы, которые всегда имеют
одно и то же значение. Это утверждение-константа True, которая всегда
истина, и False, которая всегда ложна.
Евгений Волосатов
Примеры условий и их значений:
5 > 3
истинно
a+1 = a ложно
True
истинно
15
4 <= 4
a <> a
False
Turbo Pascal
истинно
ложно
ложно
Примеры выражений, которые не являются условиями:
5 + 5
Это арифметическое выражение целого типа
a + b
Это тоже некоторое выражение нелогического типа, так как
логические выражения нельзя складывать операцией "+".
a := 5
Оператор присваивания (как и любой другой оператор) не
может быть условием.
Приведём пример использования условного оператора:
if nashi > vashi
then writeln (’Победа за нами! Ура!!!’)
else writeln (’Главное – не победа, а участие!’);
Будет напечатана ликующая фраза, если "наши" набрали больше очков,
чем "ваши" (условие nashi > vashi верно), либо ободряющий лозунг в
обратном случае (условие nashi > vashi не верно, то есть либо
nashi < vashi, либо nashi = vashi).
Обратите внимание, что точка с запятой перед служебным словом else не
ставится, потому что точка с запятой используется только для разделения
операторов друг от друга, а структура if – then – else – это один оператор,
хотя он и содержит в себе два других. Точка с запятой ставится только в конце
условного оператора.
Давайте теперь вместе составим небольшую программу, которая попросит
ввести два числа a и b, и найдёт из них максимальное. Для этого в условном
операторе надо воспользоваться условием, при истинности которого можно
будет утверждать, что одно число точно больше другого. Это условие "a > b".
Если оно истинно, то максимальным будет число a, и его надо будет вывести
на экран. Если это условие ложно, то либо максимальным будет число b, либо
a и b равны между собой. В любом случае печатаем значение переменной b.
program Bolshee_iz_dvuh;
var a, b : integer;
begin
write (’Введите два числа: ’);
readln (a, b);
if a > b
then writeln (’Max: ’, a)
else writeln (’Max: ’, b)
end.
Евгений Волосатов
4.2.
16
Turbo Pascal
Укороченный вариант условного оператора
Довольно часто в случае ложности условия не нужно производить
никаких действий. В таких случаях строчку else с оператором можно просто
опускать. Тогда получится укороченный вариант условного оператора:
if «условие»
then «оператор1»
Например:
if temperatura > 30
then writeln (’Не правда ли, жарко?!’)
При выполнении этого условного оператора компьютер напечатает
указанную фразу, если условие temperatura > 30 верно. В противном
случае ничего сделано не будет.
4.3.
Составной оператор
По правилам записи условного оператора после then может быть
только один оператор. А что делать если в случае истинности условия нужно
выполнить два, три или больше операторов? Для этих целей нужно
использовать составной оператор. Вот как он оформляется:
begin
«оператор1»;
...
«операторN»
end;
Это – один оператор, внутри которого содержится несколько. Они
выполняются последовательно. Перед словом end точку с запятой обычно не
ставят, потому что точка с запятой служит для разделения операторов друг от
друга, а служебное слово end оператором не является, оно просто замыкает
последовательность операторов. Но если поставите точку с запятой – ошибки
не будет, так как компьютер подумает, что после «оператораN» есть еще
один пустой оператор.
Пример использования составного оператора:
if nashi > vashi
then begin
writeln (’Победа за нами! Ура!!!’);
nashi := 0;
{ Обнуление результатов }
vashi := 0
end ;
Евгений Волосатов
4.4.
17
Turbo Pascal
Составные условия
Условие может быть составным, то есть состоять из нескольких других
условий. Эти условия необходимо связывать при помощи логических
операций and, or, not и xor.
ОПЕРАЦИЯ AND
Логическую операцию and (и) используют, когда нужно, чтобы
одновременно выполнялись два условия. Например, условие
“Книга интересная И книга красивая”
будет верно тогда и только тогда, когда книжка будет и интересной, и
красивой одновременно. В Паскале это записывается так:
(«условие1») and («условие2»)
Например, составим условие, которое будет истинно тогда и только тогда,
когда переменная х принадлежит промежутку от 10 до 20: 10 < x < 20. Это
произойдёт только в том случае, когда х будет больше 10 и меньше 20:
(x > 10) and (x < 20)
Проверка. Возьмём вместо х число 0. Первая часть условия ложна, вторая
часть верна, значит всё условие ложно (0 в самом деле не принадлежит
промежутку от 10 до 20). Самостоятельно проверьте это условие для
следующих значений переменной х: 25, 11, 20, 10, 19.
ОПЕРАЦИЯ OR
Логическую операцию or (или) используют, когда хотят
сформулировать условие, которое будет истинно в том случае, когда верно
хотя бы одно условие из двух. Например, условие
“Идёт снег ИЛИ светит солнце”
будет истинно, если либо идёт снег, либо светит солнце, либо выполняется и
то, и другое. В Паскале эта операция записывается так:
(«условие1») or («условие2»)
ОПЕРАЦИЯ NOT
Логическую операцию not (не – логическое отрицание) используют,
если нужно проверить условие на ложность. Эта операция делает ложным
истинное условие и истинным ложное. Вот как это записывается:
not («условие»)
ОПЕРАЦИЯ XOR
Это редко используемая логическая операция, которая называется
«исключающее или» или по-другому «строгое или». В отличие от обычного
«или», она принимает ложное значение при истинности обоих условий.
(«условие1») xor («условие2»)
Евгений Волосатов
18
Turbo Pascal
Все комбинации аргументов и результатов этих логических операций
расписаны в таблице. Значения логических величин обозначены логическими
константами False (ложно), и True (истинно).
Таблица 4. Логические операции
A
B
not A
A and B
A or B
A xor B
False
False
True
True
False
True
False
True
True
True
False
False
False
False
False
True
False
True
True
True
False
True
True
False
A и B в свою очередь тоже могут быть составными условиями.
Например, следующее логическое утверждение истинно, что показывается
последовательным его преобразованием:
(5
=
=
=
4.5.
> 3)
True
True
True
and
and
and
and
not ((3 <> 3) or (7 > 9)) =
not (False or False) =
not False =
True = True
Вложенные условные операторы
Оператор, записанный в условном предложении после then или else,
тоже может быть условным оператором. Так получаются вложенные условные
операторы.
Например:
program Bolshee_iz_treh;
var a, b, c : integer;
begin
write (’Введите три числа через пробел: ’);
readln (a, b, c);
write (’Максимальное число – ’);
if a > b
then if a > c
{ Случай, когда a > b }
then writeln (a)
else writeln (c)
else if b > c
{ Случай, когда a <= b }
then writeln (b)
else writeln (c)
end.
В этом примере оператор writeln (a) выполнится только в том случае,
если а будет больше b, и a будет больше c. А другие когда?
4.6.
Оператор выбора case
Попробуйте самостоятельно решить такое задание:
Дан номер месяца m. Вывести на экран название этого месяца.
Евгений Волосатов
19
Turbo Pascal
Если бы вы начали решать это задание, то столкнулись бы с необходимостью много раз использовать условный оператор:
if m = 1 then write (’Январь’);
if m = 2 then write (’Февраль’);
и так далее.
В таких случаях значительно удобней использовать оператор выбора case:
case «переменная» of
«список1 возможных значений» : «оператор1» ;
...
«списокN возможных значений» : «операторN» ;
else «операторN+1»
end
Оператор выбора case работает так. Сначала компьютер берёт значение
переменной, которая записывается после служебного слова case, и проверяет,
входит ли она в «список1 возможных значений». Если да, то
выполняется «оператор1», после чего выполнение оператора выбора
заканчивается. В противном случае, компьютер проверяет, входит ли значение
переменной в «список2 возможных значений». Если да, то выполняется
«оператор2», после чего выполнение оператора выбора заканчивается. В
противном случае проверка продолжается дальше до тех пор, пока есть списки
возможных значений. Если значение переменной не вошло ни в один из этих
списков, то выполняется «операторN+1», записанный после слова else.
В списке возможных значений можно указать одно число, несколько
чисел через запятую или целые промежутки.
Составим программу, которая по номеру месяца выведет время года:
program Vremena_goda;
var month : integer;
begin
write (’Введите номер месяца: ’);
readln (month);
case month of
3, 4, 5: write (’Весна’);{Можно перечислить все возможные значения}
6
: write (’Лето’); { Можно указать только одно значение }
7, 8
: write (’Лето’); { Можно указать только одно значение }
9..11 : write (’Осень’); { Можно задать промежуток }
1..2,12: write (’Зима’);
else write (’Задан неверный номер месяца.’)
end
end.
Как и в условном операторе, в операторе выбора строка со словом else и
оператором может отсутствовать. Это будет укороченный вариант записи
оператора выбора.
Евгений Волосатов
20
Turbo Pascal
Остаётся добавить, что если в оператора case после двоеточия нужно
указать более одного оператора, то надо использовать составной оператор.
4.7.





Самостоятельные задания
Составить программу, которая запрашивает два числа и находит наибольшее.
Дано два чётных числа. Вывести сначала то, что меньше, потом то, что больше.
Найти сумму цифр введенного трёхзначного числа.
Ввести время: часы, минуты и секунды. Сколько будет вермени через 1 секунду?
Дано два целых числа: a, b. Найти:
min (a, b) ;
max (a+b, a–b) ;
min (a*b, a+b, 2*a–b) .
Даны длины трёх отрезков. Определить, можно ли из них составить треугольник.
Ввести с клавиатуры дату (день, месяц, год), записать ее, назвав месяц словами.
Придумать и выполнить интересное задание на использование оператора case.



5.
Стандартные типы переменных
5.1.
Общий обзор стандартных типов.
До сих пор мы работали только с переменными целого типа. Сейчас мы
кратко познакомимся со всеми стандартными типами. В таблице приведены
характеристики всех стандартных типов.
Таблица 5. Стандартные типы
Вид типа
Целый
Вещественный
Логический
Символьный
Имя
типа
byte
shortint
word
integer
longint
single
real
double
extended
comp
boolean
char
string
Диапазон возможных
значений
0 … 255
-128 … 127
0 … 65535
-32768 … 32767
-2147483648…2147483647
1.5e-45 … 3.4e38
2.9e-39 … 1.7e38
5.0e-324 … 1.7e308
3.4e-4932 … 1.1e4932
-263 … 263-1
False и True
один любой символ
строка символов
Объём
памяти
1 байт
1 байт
2 байта
2 байта
4 байта
4 байта
6 байт
8 байт
10 байт
8 байт
1 байт
1 байт
256 байт
Значащих
цифр
7 – 8
11-12
15-16
19-20
целые числа
Евгений Волосатов
5.2.
21
Turbo Pascal
Целые типы
Для разных целей нужны разные диапазоны возможных значений.
Скажем, если в переменной хранится возраст человека в годах, то для
хранения этого значения вполне достаточно интервала от 0 до 150. Для того
чтобы разумно распределить память компьютера используют разные типы.
5.2.1. Тип byte
Переменная этого типа может принимать значения от 0 до 255. Если вы
попробуете присвоить ей большее значение, то компьютер вместо этого
значения возьмёт остаток от деления на 256. Это происходит из-за того, что в
представлении компьютера числа идут «по кругу» и после 255 идёт 0.
Зачем же надо использовать тип byte, если у него такой маленький
диапазон значений? Ответ прост: для экономии памяти. Переменная этого
типа занимает в памяти компьютера всего 1 байт.
5.2.2. Тип shortint
Этот тип также позволяет сохранять только 256 разных целых чисел, но
уже и с отрицательными значениями. Его диапазон от –128 до 127. В памяти
компьютера этот тип также занимает один байт. При переполнении (попытке
записать число, выходящее за диапазон возможных значений) компьютер
начнёт считать от –128. Например, в его «арифметике»: 127 + 1 = –128,
поэтому:
127 + 10 = (127+1) + 9 = –128 + 9 = –119.
5.2.3. Тип word
Если целой переменной выделить не 1 байт, а 2 байта, то она сможет
принимать в 256 раз больше разных значений, то есть числа от 0 до 65535
(65536 = 2562). При попытке присвоить такой переменной большее значение,
будет использован лишь остаток от деления на 65536.
5.2.4. Тип integer
integer – первый тип, с которым мы познакомились. Уже упоминалось,
что он позволяет хранить числа от –32768 до 32767. Для этого типа есть даже
специально определённая константа maxint, которая хранит максимальное
целое число, представимое этим типом. В памяти он занимает 2 байта.
5.2.5. Тип longint
Это целый тип, который работает с самым большим диапазоном
от –2147483648 до 2147483647
Максимальное значение хранится в константе maxlongint. Этого
диапазона хватает для многих практических целей, но для хранения
переменной этого типа необходимо уже 4 байта.
Евгений Волосатов
5.3.
22
Turbo Pascal
Вещественные типы
Переменные этого типа могут хранить рациональные (дробные) числа с
разной степенью точности. Точность зависит от выбранного типа. Всего
существует 5 вещественных типов. В таблице №5 наглядно показано, какой
тип какой точностью обладает и сколько ему требется памяти.
5.3.1. Способ записи вещественных чисел
Запись вещественных чисел отличается от записи целых. Вещественное
число, как известно, состоит из целой и дробной части. Они разделяются не
запятой, как в математике, а точкой. Причём десятичная точка должна быть
использована в любой вещественной константе, даже если задаётся целое
число, так как иначе компьютер не сможет отличить константу целого типа от
константы вещественного типа.
Например:
2.2
2.0
0.35
12.84
0.3333
Запись 2.0 обозначает вещественную константу, а просто 2 – целую.
Вещественные числа можно ещё записывать в стандартном виде с
использованием степени числа 10. Эта форма удобна для записи очень
больших и очень маленьких чисел. Числа в стандартном виде записываются в
таком формате:
«мантисса» ∙ 10«порядок»
5,2 ∙ 103 — в математике
«мантисса»e«порядок» 5.2e3 — в информатике
5.2e3 = 5,2 ∙ 103 = 5,2 ∙ 1000 = 5 200,0
Здесь 5,2 – мантисса, а 3 – порядок числа.
В Паскале сначала записывается мантисса, потом ставится английская буква e,
после которой указывается порядок числа, то есть на какую степень числа 10
надо умножить мантиссу, чтобы получить значение записываемого числа:
5.32e6 – эта запись обозначает число, равное 5,32 ∙ 10 6
2.12e-5 – эта запись обозначает число, равное 2,12∙10 –5 =
= 2,12 ∙ 0,00001 = 0,0000212
Мантисса числа всегда больше либо равна 1, но меньше 10 (кроме 0).
Разберите ещё несколько примеров перевода чисел из обычной формы
записи в стандартную. Обратите внимание на запись отрицательных чисел.
45.2 = 4.52e1
1235.0
= 1.235e3
100.0 = 1.0e2
5.0
= 5.0e0
0.03= 3.0e-2
0.0012= 1.2e-3
0.0 = 0.0e0
25000.0
= 2.5e4
-28.17=-2.817e1
-1.0
=-1.0e0
Закройте один из столбиков и поупражняйтесь в переводе чисел из
стандартной записи в обычную и наоборот, контроллируя свои результаты.
Запишите следующие числа в стандартном виде:
457.1 , 5.4201 , 45214.0 , 0.00453 , -42000.0 , 0.00005 .
Евгений Волосатов
23
Turbo Pascal
Решите примеры. Для этого переведите числа в обычную форму, сложите
их и запишите результат в стандартном виде. В конце пункта 5.3 будет ответ.
1)
2)
3)
4)
2.2e1 + 3.08e2 = ?
5.53e15 + 2.34e14 = ?
2.11e-10 + 1.01e-12 = ?
1.52e10 + 2.42e-8 = ?
5.3.2. Вывод на экран вещественных чисел
Вещественные числа можно выводить на экран оператором writeln:
d := 575.22;
writeln (d)
Однако вместо ожидаемого «575.22» на экране появится «абракадабра»:
5.75219999999739E+0002
Однако, если внимательней присмотреться, то можно заметить, что это и в
самом деле наше число, но «округленное» и записанное в стандартном виде.
«Округление» происходит из-за особенности представления числа в памяти.
Для того чтобы компьютер печатал число в более привычном для нас виде,
надо сообщить ему об этом следующим образом:
writeln (d : «всего символов» : «дробная часть»);
Параметр «всего символов» показывает, сколько надо выделить
символов (знакомест, позиций) экрана для вывода числа, а параметр
«дробная часть» – сколько знаков после десятичной точки необходимо
отобразить. Этот способ вывода называет форматированным выводом.
Если в предыдущем примере оператор вывода сделать форматированным:
writeln (d : 6 : 2);
то компьютер напечатает долгожданное
575.22
Форматированный вывод можно употреблять и для целых чисел. Но для
них задаётся только один параметр – «всего символов».
5.3.3. Точность вещественных чисел
Под точностью понимают число значащих цифр (см. таблицу №5). В
мантиссе не должно быть цифр больше, чем это возможно для данного типа. В
противном случае число будет округлено. Например:
program tip_single;
var d : single;
{вещественный тип с точностью 7-8 цифр}
begin
d := 9.87654321e5; {попытка записать число с мантиссой из 9 цифр}
writeln (d);
end.
Эта программа печатает на экран:
9.87654312500000E+0005
Евгений Волосатов
24
Turbo Pascal
На первый взгляд кажется, что запомнено достаточно много цифр, но при
детальном анализе выясняется, что точно записаны лишь 7 первых цифр. Если
вместо типа single использовать тип Real, то получим следующий
результат:
9.87654321000099E+0005
5.3.4. Диапазон значений вещественных чисел
В таблице 5 указано, какое максимальное и минимальное положительное
значение позволяет записать каждый тип. Другими словами – это допустимый
диапазон порядка числа. При попытке сохранить значение больше
максимального произойдет ошибка «Floating point overflow» «переполнение в операции с плавающей точкой». При попытке сохранить
значение меньше минимального1, появится так называемый «машинный нуль»
– компьютер посчитает это значение равным нулю.
5.3.5. Функции вецественного аргумента
Таблица 6. Математические операции и функции
Название
Обозначение
Способ записи
Сложение
Вычитание
Умножение
Деление
Квадратный корень
Квадрат числа
Модуль числа
Синус
Косинус
Тангенс
Арктангенс
Степень числа e
Натуральный логарифм
Целая часть
Дробная часть
Случайное число от 0 до 1
Возведение в степень
x+y
x–y
x∙y
x/y
x
x2
|x|
sin x
cos x
tg x
arctg x
ex
ln x
[x]
{x}
x + y
x – y
x * y
x / y
sqrt (x)
sqr (x)
abs (x)
sin (x)
cos (x)
tan (x)
arctan (x)
exp (x)
ln (x)
int (x)
frac (x)
random
exp (y*ln(x))
xy
Все эти функции работают только с вещественными числами. Для целых
переменных можно использовать только sqr и abs, а также операции +, –,.*.
Тригонометрические функции работают с углами в радианах.
1
Ещё раз обратите внимание, что имеется в виду положительные значения.
Евгений Волосатов
25
Turbo Pascal
5.3.6. Тип comp
Об этом вещественном типе стоит поговорить особо… Дело в том, что
этот тип по своей сути является целым, но с очень большим диапазоном
значений. А именно:
от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807,
всего 18 446 744 073 709 551 615 возможных значений.
Посмотрите внимательно на последнее число! Именно столько зёрен
пшеницы должен был выдать падишах Индии изобретателю шахмат по
легенде. Изобретатель попросил за первую клетку шахматной доски одно
зерно пшеницы, за вторую – две, за третью – четыре. И так далее: за каждую
следующую – в два раза больше, чем за предыдущую. Падишах только
посмеялся над столь мизерной просьбой, сказав: «Житницы мои не оскудеют!
Завтра тебе вынесут твой мешок пшеницы». Однако такого количества зёрен
не найдётся и на всей матушке-земле.
5.3.7. Линейная запись математических выражений
Математические выражения на языке Pascal должны быть записаны в так
называемой линейной записи, которая состоит из цепочки символов без всяких
индексов, например, вместо x1, x2 надо писать x1, x2.
Надо уметь переводить любую формулу из обычной записи в линейную и
наоборот. Например:
Выполните следующие два упражнения:
1. Перевести из линейной записи в обычную:
1.
3.
5.
7.
9.
(a+b)/c
a/b/c
1/sqrt(1+x)
(a+b)/(c+d)
2*sin((a+b)/2)*cos((a-b)/2)
2.
4.
6.
8.
10.
a+b/c
1/sqr(1+x)
a+b/c+d
arctan(x/sqrt(1-x*x))
sqr(sin(abs(x+int(x)))/2*x)
2. Перевести из обычной записи в линейную:
Ответ на задание к пункту 5.3.1:
1) 3.3e2, 2) 5.764e15, 3) 2.1201e-10,
4) 1.52e10 (маленькое число не влияет на результат).
Евгений Волосатов
5.4.
26
Turbo Pascal
Логический тип
Условия, которые мы записывали после слова if, оказывается тоже можно
сохранять. Для этого существуют переменные логического типа boolean.
Например:
program tip_boolean;
var b : boolean ;
begin
b := 23 > 10 ;
{ b = true }
if b
{ b можно использовать вместо условия! }
then writeln (b)
end.
Выражение 23>10, как вы уже знаете, называется высказыванием или
условием. Оно может быть истинно или ложно. Переменные логического типа
могут принимать только два значения: True или False, то есть "истина" или
"ложь". Поэтому нет ничего удивительного в таком операторе присваивания,
над логическими переменными можно производить такие же действия, как и
над условиями.
Можно также выводить на экран значения логических переменных,
используя оператор write. А вот вводить значения логических переменных
оператором read нельзя.
Так как логическая переменная может хранить одно из двух значений True
или False, то для хранения её значения достаточно 1 бита, однако в памяти
компьютера ей выделяется всё-таки целый байт.
5.5.
Символьные типы
До сих пор мы работали только с числами. Строчки нам встречались
только в операторе write при выводе сообщений на экран. Теперь мы
научимся работать со строчками и отдельными символами.
5.5.1. Тип string
Этот тип предназначен для хранения строк. Вспомним ещё раз, как мы
употребляли в операторе write строчки, string-константы:
write (’Какой чудесный день! Какой чудесный пень!’);
Итак, если мы опишем переменную типа string, то мы сможем
сохранять в этой переменной строки текста:
program String_Example;
var s1 : string ;
begin
s1 := ’Тра-ля-ля!’;
writeln (s1)
end.
Эта программа напечатает:
Тра-ля-ля!
Евгений Волосатов
27
Turbo Pascal
В строке может быть записано от 0 до 255 символов. Строка длиной 0
символов называется пустой и обозначается парой кавычек: ’’.
Строки можно не только выводить на экран, используя оператор write,
но и вводить с клавиатуры оператором readln.
5.5.2. Стандартные функции для работы со строками
Одна из главных характеристик строки – это её длина. Длину строки
можно вычислить с помощью функции
length (st)
Например:
length (’kolobok’) - результат 7 ;
length (’’) - результат 0.
Любые две cтроки можно сложить (склеить). Для этого используется знак
операции +. Например:
st := ’Д’ + ’a’ ;
{ st = ’Да’ }
st := st + ’ или нет.’; { Теперь st = ’Да или нет’ }
Следующая важная функция для выделения подстроки (т. е. части строки)
copy («строка», «от», «длина»)
Этой функции, как вы видите, требуется три аргумента. Первый –
строка символов – переменная типа string, из которой и производится
«выуживание» подстроки; «от» – целое число, указывающее, начиная с
какого символа надо начинать выделение подстроки; «длина» – задаёт длину
выделяемого фрагмента строки. Например:
s2 := copy (’doroga’, 3, 4); { s2 = ’roga’ }
В этом примере из слова doroga выделяется 4 символа, начиная с третьего.
При помощи квадратных скобок можно обратиться к одному символу строки:
st [«номер символа»]
Например, если st = ’Раз Два Три!’ , то:
st[1] равно ’Р’,
st[9] равно ’Т’.
Номером символа может быть и переменная целого типа.
Используя квадратные скобки можно не только читать значение
указанного символа, но и записывать на его место новый символ. Например:
st:= ’Раз
st [4] :=
st [8] :=
st [1] :=
Два Три!’;
’-’;
’-’;
’Щ’;
{
{
{
{
st
st
st
st
=
=
=
=
’Раз Два Три!’
’Раз-Два Три!’
’Раз-Два-Три!’
’Щаз-Два-Три!’
}
}
}
}
5.5.3. Тип char
Переменные типа char могут хранить только один какой-нибудь символ.
Символ – это любая буква, цифра, пробел или значок, который можно
вывести на экран компьютера. Символы на языке Pascal записываются при
помощи одинарных кавычек. Например:
Евгений Волосатов
’a’
’Б’
’$’
’’’’
-
28
Turbo Pascal
символ – маленькая латинская буква а,
символ – большая русская буква Б,
символ – знак доллара,
символ – одинарная кавычка.
Примеры ошибочного определения символа:
’zx’ – вместо одного символа – два.
”a” - символ должен быть в апострофах, а не в кавычках.
&
- символ должен быть в кавычках, а не просто так.
’’
- так обозначается пустая строка, её длина ноль символов, а не один.
Каждый символ имеет свой собственный код от 0 до 255. Поэтому любой
символ можно задать по его коду в таблице ASCII. Для этого ставится значок
решётки #, после которого пишется номер символа, например:
#33 символ ’!’;
#65 символ ’А’;
Таблица символов
Так как каждый символ имеет свой собственный код, то их можно
сравнивать друг с другом. Считается, что символы равны, если равны их коды.
Из двух символов больше тот, чей код в таблице ASCII больше.
Поэтому, хоть внешне некоторые символы похожи (например: ноль и буква О,
русская В и английская B) или имеют одну и ту же смысловую нагрузку
(например, D и d), но для компьютера они являются разными символами.
5.5.4. Стандартные функции для типа char
Есть несколько функций для работы с переменными типа char.
upcase (ch)
Эта функция переделывает строчную английскую букву в заглавную. Если
аргумент не является буквой, символ остается без изменения. Например:
upcase(’a’) = ’A’
upcase(’#’) = ’#’
upcase(’я’) = ’я’ (обрабатываются только английские буквы)
Евгений Волосатов
29
Turbo Pascal
Следующая функция
ord (ch)
определяет код символа. Каждый символ, имеет свой номер от 0 до 255.
Например: ord (’A’) равно 65. То есть символ А имеет код 65.
Обратная ей функция chr находит символ по его коду.
chr (nr)
Например:
chr (65) равно ’A’,
Так как функции ord и chr взаимно обратные, то
ord (chr (83)) равно 83, chr (ord (’S’)) равно ’S’
6.
Подпрограммы
6.1.
Зачем нужны подпрограммы?
В практике программирования часто встречаются случаи, когда по ходу
выполнения программы приходится производить однотипные вычисления, с
различными исходными данными. Чтобы исключить повторение одинаковых
записей и сделать тем самым программу проще и понятнее, можно выделить
эти повторяющиеся вычисления в самостоятельную часть программы, которая
будет использоваться многократно по мере надобности. Такая отдельная часть
программы, допускающая обращение к ней из различных частей основной
программы, называется подпрограммой.
Подпрограммы оформляются в виде замкнутых участков программы,
имеющих чётко обозначенные вход и выход. Самостоятельный характер
подпрограмм позволяет поручать их составление различным авторам. При
этом осуществляется разделение работы по программированию и ускоряется
разработка программного продукта. Для удобства этой работы имена
переменных в основной программе и в подпрограммах не зависят друг от
друга. Если, например, в основной программе фигурирует переменная с
именем А, то переменная с таким же именем А, но используемая в
подпрограмме, может иметь совершенно другое значение, никак не связанное
со значением переменной А в основной программе.
В языке Pascal есть два вида подпрограмм, процедуры и функции.
6.2.
Процедуры
Процедура – эта независимая часть программы, которая имеет своё имя.
По этому имени её можно вызывать из различных участков программы для
выполнения записанных в ней действий. Структура процедуры повторяет
структуру программы:
Евгений Волосатов
procedure «Имя» ;
... ...
begin
...
end;
30
Turbo Pascal
{ заголовок процедуры }
{ секция описаний процедуры }
{ операторы }
В программе процедуры записываются сразу после описания переменных:
program Р;
{pаздел описаний данных основной пpогpаммы Р}
procedure К;
{pаздел описаний пpоцедуpы К}
begin
{pаздел опеpатоpов пpоцедуpы К}
end;
begin
{pаздел опеpатоpов основной пpогpаммы Р}
end.
В секции описаний процедуры могут быть описаны локальные переменные,
локальными называют те переменные, которые могут быть использованы
только внутри некоторого блока. В данном случае – в процедуре. Из другого
места программы доступа к этим переменным нет.
Пример. Давайте составим программу с процедурой, которая будет
приостанавливать работу программы.
program primer_procedury;
var a, b, s : integer;
procedure pausa;
{так как в процедуре не используются переменные, секция описаний пропущена}
begin
writeln (’Нажмите ENTER для продолжения!’);
readln
end;
begin
write (’Введите первое число: ’);
readln (a);
a := a * a;
writeln (’Квадрат этого числа равен: ’, a);
pausa; { Вызов процедуры Pausa }
write (’Введите второе число: ’);
readln (b);
b := b*b;
writeln (’Квадрат этого числа равен: ’, b);
pausa;
s := a + b;
writeln (’Сумма квадратов введенных чисел равна ’, s);
pausa
end;
Евгений Волосатов
31
Turbo Pascal
Когда компьютер при выполнении этой программы дойдет до строчки Pausa,
он начнет выполнять действия, которые записаны в процедуре Pausa, то есть
выведет на экран строчку и будет ждать нажатия клавиши Enter. После
завершения работы процедуры компьютер продолжит выполнять программу с
того места, откуда она была вызвана.
6.3.
Аргументы процедуры
В процедуры можно передавать аргументы (параметры) – своего рода
начальные данные для процедуры, которые записываются в заголовке:
procedure «имя» («арг1» : «тип1»; «арг2» : «тип2»; ... );
где «аргN» – имя переменной-аргумента, «типN» – тип этой переменной.
Если среди аргументов есть несколько переменных одного типа, то их все
можно перечислить через запятую, а потом указать тип:
procedure Primer (a, b : integer; s : real);
Описанные в заголовке аргуметны могут использоваться в процедуре как
обычные переменные. Например:
program rabota_s_proceduroj;
var x, y : integer;
procedure summa (a, b : integer);
var s : integer; { использована локальная переменная }
begin
s := a + b;
writeln (’Сумма чисел ’, a, ’ и ’, b, ’ равна ’, s)
end;
begin
summa (4, 7);
write (’Введите два числа: ’);
readln (x, y);
summa (x, y)
end.
Во время выполнения этой программы на экране будет напечатано:
Сумма чисел 4 и 7 равна 11
Компьютер запросит ещё два числа, сложит их, и выведет сумму на экран.
Как видите, для вызова такой процедуры надо после её имени указать в
скобках значения, которые будут переданы в процедуру. Это могут быть как
конкретные числа, так и переменные.
Евгений Волосатов
6.4.
32
Turbo Pascal
Результаты процедуры
Процедура может ещё обладать результатами – это значения, которые
возвращаются из процедуры в программу. В предыдущем примере у
процедуры тоже был результат – сумма двух чисел. Однако он нигде не
сохранялся, а только выводился на экран.
Чтобы оформить переменную-результат, надо в заголовке процедуры перед
описанием переменной-результата приписать слово var. Вот пример полной
программы с процедурой Summa, у которой два аргумента и один результат.
program procedura_s_argumentami_i_rezultatom;
var p, q, r : integer;
procedure Summa (a, b : integer; var s : integer);
begin
s := a + b
end;
begin
write (’Введите два числа: ’);
readln (p, q);
Summa (p, q, r ); { p,q - аргументы, r - результат }
writeln (’Сумма введённых чисел: ’, r)
end.
При вызове процедуры переменные a, b внутри неё примут те же значения,
что и переменные p, q в основной программе, соответственно. По окончании
работы в глобальную переменную основной программы r запишется то число,
которое будет в переменной s (результате) процедуры.
При вызове процедуры в качестве аргументов можно указывать
конкретные числа, а в качестве результатов – нет. Подумайте, почему.
Процедура может иметь сколько угодно аргументов и сколько угодно
результатов. Главное, чтобы при вызове процедуры строго соблюдался
порядок следования всех параметров!
Напишем программу, которая запрашивает координаты концов отрезка и
находит координату точки, которая делит этот отрезок в отношении 1:3.
Процедуру Seredina нахождит середину отрезка координатам его концов.
program Geometrija;
var ax, ay, bx, by : integer;
cx, cy, dx, dy : real;
procedure Seredina (x1,y1,x2,y2 : integer; var x,y : real);
begin
x := (x1+x2) / 2;
y := (y1+y2) / 2
end;
Евгений Волосатов
33
Turbo Pascal
begin
write (’Введите координаты концов отрезка: ’);
readln (ax, ay, bx, by);
Seredina (ax, ay, bx, by, cx, cy); {точка (cx,cy) середина отрезка ab}
Seredina (bx, by, cx, cy, dx, dy); {точка (dx,dy) середина отрезка bc}
writeln (’Точка (’, dx, ’, ’, dy, ’) делит отрезок в отношении 1:3’)
end.
Так как процедуры могут возвращать результаты в виде переменных, то
отпадает необходимость выводить их на экран внутри процедуры.
6.5.
Функции
Другой вид подпрограммы – функция – оформляется так:
function «имя» («параметры») : «тип»;
... ... { секция описаний функции }
begin
...
{ раздел операторов }
end;
Отличительные особенности функции:
1. функция имеет только один результат типа «тип», но может иметь
несколько входных аргументов – «параметры»;
2. вызывать функции можно только из выражений;
3. результат обозначается именем функции и передаётся в вызываемое место.
Во всём остальном функция похожа на процедуру: она может иметь локальные
переменные, обладает аргументами, можно даже оформлять дополнительные
результаты так же, как и у процедуры.
Пример описания функции:
function
begin
if a >
then
else
end;
min (a, b : integer) : integer;
b
min := a
min := b
Функция находит меньшее из двух целых чисел. Здесь min - имя функции,
оно же является одновременно и результатом этой функции – целое число.
Формальными параметрами (аргументами функции) являются переменные
целого типа a и b. Вызывается функция по своему имени с указанием
фактических параметров. При этом вызов функции нужно делать
непосредственно внутри выражения, например:
y := min (x, y) + min (k, l);
Евгений Волосатов
34
Turbo Pascal
Нужно иметь ввиду, что при оформлении функции её результату (то есть её
имени) можно только присваивать значения, но нельзя его использовать как
переменную, так как в этом случае компьютер подумает, что вы хотите этой
записью снова вызвать функцию! Например:
function SummaCifr (a : integer) : integer;
begin
SummaCifr := a mod 10;
SummaCifr := SummaCifr + a div 10; { Ошибка! }
end;
Эта запись является ошибочной. В таких случаях нужно использовать
промежуточные переменные.
6.6.
Самостоятельные задания
1) Составьте программу нахождения суммы двух чисел, используя функцию.
2) Составьте программу нахождения площади круга по заданному целому
значению радиуса. Решите это задание двумя способами: с использованием
процедуры и с использованием функцией.
3) Составьте процедуру поиска суммы цифр двузначного числа. Если задано
не двузначное число, вернуть результат 0.
4) Составить функцию для поиска суммы цифр трёхзначного числа.
7.
Циклы
Цикл – это структура языка, которая предписывает
многократное выполнение указанного оператора.
Говоря проще, цикл - это многократное повторение некоторых действий.
Например:
ЦИКЛ 10 раз
начало цикла
write ('*');
конец цикла
В результате работы такой воображаемой структуры мы могли бы
получить 10 звездочек на экране, потому что всё, что заключено между
началом и концом цикла выполняется несколько раз. Все, что вне этих рамок только один раз. Для наглядности область цикла заключена в рамочку.
Рассмотрим ещё один пример:
Евгений Волосатов
35
Turbo Pascal
write ('<');
ЦИКЛ 5 раз
начало цикла
write ('Да-');
конец цикла
write ('>');
В результате выполнения этих операторов на экран напечатается следующее:
<Да-Да-Да-Да-Да->
Обратите внимание, что слово "Да" было напечатано 5 раз, а каждая из
угловых скобок – только один раз. Почему именно так? Потому что оператор
write('Да-')
выполняется 5 раз, так как он находится внутри цикла, а операторы
write ('<');
и
write('>')
только один, так как они находится вне цикла.
Итак, всё что находится внутри цикла, выполняется несколько раз
подряд. Всё что вне цикла – выполняется только один раз.
Однако в Паскале нет оператора цикла "N раз", зато есть три других:
for, while и repeat (Для, Пока и Повторять).
Из них на наш цикл "N раз" больше всего похож цикл for.
7.1.
Цикл for
Формат записи оператора цикла for:
for «имя» := «от» to «до» do
«оператор»
Поначалу для наглядности операторы цикла мы будем обводить рамочкой,
но только на бумаге, на компьютере вместо рамочек используют отступы..
Если в цикле нужно указать больше одного оператора, то необходимо
использовать операторные скобки begin и end.
Познакомимся с принципом работы этого оператора на уже знакомом
примере, который заставит компьютер напечатать 10 звёздочек:
program Zvezdy ;
var i : integer ;
begin
for i := 1 to 10 do
write ('*')
end.
Этот цикл выполнится 10 раз и на экран будет выведено 10 звёздочек.
Первая строка со словом for называется заголовком цикла. В нём содержится
вся необходимая информация для организации цикла. Подробней и по-русски
этот заголовок можно пояснить так:
Евгений Волосатов
36
Turbo Pascal
Для целой переменной i, которая вначале принимает значение 1, организуем цикл.
После каждого выполнения цикла переменная i будет увеличиваться на единицу, пока
не примет конечного значения 10.
После этого цикл выполнится последний раз и больше выполняться не будет.
Начало операторов цикла
напечатать символ ('*')
Конец операторов цикла
Как видите, оператор цикла for не существует сам по себе, а
организуется специально для какой-либо целой переменной, которая
называется "переменной цикла" или "параметром цикла". Она автоматически
увеличивает своё значение после каждого выполнения операторов цикла, пока
не примет своего конечного значения. Когда это произойдёт, операторы цикла
выполнятся последний раз и выполнение цикла закончится.
Переменную цикла можно использовать внутри цикла как обычную
переменную. Однако, ей нельзя ничего присваивать, ведь не зря же для неё
организовали целый цикл! Организаторы сами следят за значением этой
переменной…
В зависимости от начального и конечного значения параметра цикла,
которые задаются в заголовке, цикл может выполнится то или иное количество
раз. Например, если начальное и конечное значения совпадают, то цикл
выполнится только один раз. Если же начальное значение превышает
конечное, то цикл не выполнится ни разу! Вот так цикл!..
А сколько раз выполнится циклы со следующими заголовками:
for
for
for
for
for
i
i
i
i
i
:=
:=
:=
:=
:=
5 to 9 do
0 to 8 do
-1 to 10 do
100 to 200 do
0 to 0 do
{ 5 раз }
Итак, ещё раз, запомните! Оператор цикла является замкнутой
структурой, поэтому все, что не входит в него, выполняется один раз!
Переменная цикла не может быть вещественным числом, но только целым
(integer, byte, word и др). Её значение в цикле всё время изменяется и
может быть использована для каких-либо целей, например:
program raz_dva_tri_cetyre_piat;
var i : integer;
begin
for i := 1 to 5 do
write (i)
end.
На экран напечатается 5 чисел без пробелов:
12345
Евгений Волосатов
37
Turbo Pascal
Каждое число – есть значение переменной цикла при очередном
выполнении тела цикла.
Можно придать этой программе некоторый практический смысл, если
выводить на экран не только целые числа, но и их квадраты – получим
таблицу квадратов первых пяти чисел. Смотрите, как изменится программа:
program Kvadraty_chisel;
var i, s : integer;
begin
for i := 1 to 5 do
begin { так как в цикле больше 1 оператора, то
используются операторные скобки }
write (i, '*', i);
s := i*i;
writeln (' = ', s)
end
end.
Значение переменной цикла может использоваться и для более полезных
действий, но ни в коем случае не может быть изменено её значение. В этом
смысле параметр цикла можно сравнить с музейной диковинкой на которой
висит табличка:
Руками не трогать!
Все могут смотреть, но никто, кроме служебных работников, трогать не может!
Существует ещё одна разновидность цикла for, в котором вместо
служебного слова to используется downto. В этом случае переменная цикла
будет каждый раз уменьшать своё значение, а не увеличивать. Например, цикл
for i := 5 downto 1 do
write (i, ’ ’);
напечатает:
5 4 3 2 1
Вначале переменная цикла была равна начальному значению, которое больше
конечного, а после каждого выполнения цикла её значение уменьшалось.
Вопрос: А надо ли ставить точку с запятой после слова do?
Ответ: Нет, ни в коем случае.
Вопрос: Почему?
Ответ: Потому что в этом месте ещё не закончен оператор цикла. После
служебного слова do нужно указать оператор, который и будет телом цикла. Если
вы поставите здесь точку с запятой, то компьютер посчитает, что телом цикла
является пустой оператор и спокойно будет выполнять его (то есть ничего не
выполнять) необходимое число раз. А то, что вы хотели записать в теле цикла,
будет выполнено как обычный оператор – только один раз. Например:
Евгений Волосатов
38
Turbo Pascal
for i := 1 to 10 do ; {Тело цикла – пустой оператор}
writeln (i);
Вместо ожидаемых 10 чисел на экран выведется только одно число – число 10 –
значение переменной i по завершению работы цикла.
Параметр цикла может быть не только числом, но и символом. В этом
случае начальные и конечные значения тоже должны быть символами, а
переменная цикла будет перебирать все значения между ними в том порядке, в
каком они указаны в таблице ASCII.
program Alfavit;
var c : char;
begin
for c := ’a’ to ’z’ do
write (c)
{ выводим буквы в строчку }
end.
На экране будет напечатан весь английский алфавит в одну строчку:
abcdefghijklmnopqrstuvwxyz
7.2.
Нахождение суммы
Циклы часто используют для обработки рядов. Например, нахождение
суммы целых чисел от 1 до 10. Можно решить эту задачу таким способом:
s := 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 ;
Но тут есть два недостатка:
1. Решение громоздко и банально.
2. Решение не поддается корректировке. Например, если мы захотим
изменить эту программу так, чтобы она находила сумму первых 100
натуральных чисел, то размер программы увеличился бы почти в 10 раз.
Поэтому такую задачу нужно решать с использованием цикла.
Решать будем по такой общей схеме:
обнулить счётчик суммы
начало цикла
прибавить к счётчику суммы очередное слагаемое
конец цикла
вывести значение счётчика суммы на экран
То есть, для нахождения суммы мы должны специально выделить
переменную, в которой эта сумма будет храниться. Пусть это будет
переменная s. Вначале её нужно обнулить:
s := 0;
Потом, уже в теле цикла, мы должны будем каждый раз увеличивать
значение переменной s на значение очередного слагаемого. Этим слагаемым
будет переменная цикла, так как именно она будет поочерёдно принимать все
интересующие нас значения:
s := s + «слагаемое»;
Евгений Волосатов
39
Turbo Pascal
Переведём всё вышесказанное на язык Pascal:
program Summa_chisel_ot1do10;
var s, i : integer;
begin
s := 0; { вначале сумма равна 0 }
for i := 1 to 10 do
s := s + i;
{ суммируем }
writeln (’Сумма чисел от 1 до 10 равна ’, s)
end.
7.3.
Нахождение произведения
Похожим образом находится произведение нескольких различных
элементов. Только начальное значение переменной, в которой будет храниться
произведение, должно быть равно не нулю, а единице. И множители надо не
прибавлять, а домножать:
program Proizvedenie_chesel_ot1do5;
var p, i : integer;
begin
p := 1; { вначале произведение равно 1 }
for i := 1 to 5 do
p := p * i;
{ находим произведение }
writeln (’Произведение чисел от 1 до 5 равно ’, p)
end.
Эта программа находит произведение первых пяти натуральных чисел.
Измените эту программу так, чтобы она находила произведение первых 10
натуральных чисел и объясните причину полученного неправильного
результата. Исправьте программу так, чтобы она давала правильный результат.
А чему равно произведение чисел от -5 до 5? Почему?
7.4.
Нахождение количества
Очень часто приходится решать задачу, в которой необходимо найти
количество чисел, которые удовлетворяют некоторым условиям. Например,
найти количество нечётных чисел в заданном интервале. Для решения этой
задачи необходимо организовать цикл, в котором будут поочерёдно
перебираться все значения из заданного интервала. В теле цикла надо будет
проверять: удовлетворяет ли параметр цикла указанному условию? Если да, то
это найденное значение надо посчитать, то есть увеличить счётчик найденных
элементов на единицу (в самом начале этот счётчик должен быть равен нулю);
если нет, то перейти к следующему элементу.
Задача: "Найти количество нечётных чисел из интервала от 30 до 50".
Для этого нам надо будет организовать цикл для переменной i, которая
будет перебирать поочерёдно значения от 30 до 50. В теле цикла мы должны
Евгений Волосатов
40
Turbo Pascal
будем проверять: является ли i нечётным числом? Помните как это делать?
Нужно сравнить остаток от деления i на 2 с нулём – чётные числа делятся на 2,
нечётные нет. Для такой проверки надо использовать условный оператор if.
Если i – число чётное, то этот остаток не равен нулю. В этом случае нужно
увеличить счётчик на единицу, то есть посчитать найденное число. В конце
программы выводим результат на экран.
Переведём теперь это всё с русского языка на Pascal:
program Skoko_nechetnyx_chisel_ot_30_do_50;
var k, i : integer;
begin
k := 0; { вначале счётчик равен 0 }
for i := 30 to 50 do
if k mod 2 <> 0
{ Если число не делится на 2, то оно нечётное … }
then k := k + 1 { … и его надо посчитать }
writeln('В интервале от 30 до 50 ', k, ' нечётных чисел')
end.
Как вы уже заметили, цикл for используют тогда, когда заранее, перед
началом его работы известно, сколько раз он должен выполниться. Однако,
порой бывает необходимо организовать такой цикл, о котором заранее не
будет известно, сколько раз его надо выполнять. Например, задача о
нахождении суммы цифр данного числа N. Если мы не знаем, сколько в этом
числе цифр, то не сможем решить эту задачу используя цикл for.
Для таких целей используют цикл while – пока!
7.5.
Цикл while
Цикл while (пока) особенен тем, что позволяет организовывать циклы,
для которых нельзя заранее сказать, сколько раз он выполнится. Цикл
выполняется до тех пор, пока верно условие в заголовке цикла, хоть вечно!
Формат записи:
while «условие выхода» do
«оператор»
Цикл работает так. Сначала проверяется «условие выхода». Если оно
верно, то выполняется «оператор». Затем «условие выхода» проверяется ещё раз, если оно опять верно, то снова выполняется «оператор». Так
продолжается до тех пор, пока «условие выхода» верно.
Если «условие выхода» с самого начала было ложно, то «оператор»
не выполнится ни разу.
Если внутри цикла больше одного оператора, то необходимо использовать
операторные скобки begin – end.
Заставим компьютер посчитать от 1 до 100, используя этот оператор цикла:
Евгений Волосатов
41
Turbo Pascal
program Schitalka;
var i : integer;
begin
i := 1;
while i <= 100 do { нам нужно перебрать первые 100 чисел }
begin
writeln (i);
i := i + 1
{ Если убрать эту строку – программа зациклится }
end
end.
Обратите внимание на строку
i := i + 1;
Благодаря этой строке программа перебирает все числа от 1 до 100, потому
что цикл while, в отличие от for, самостоятельно не изменяет никакие
переменные – в этом, кстати, и заключается его универсальность. Если вы не
позаботитесь об увеличении переменной i на единицу, то условие всегда
будет верно (i всегда равно 1, а значит всё время меньше, чем 100).
С помощью цикла while легко можно перебирать числа не подряд, а,
например, через одно. Составим, например, программу для вывода первых 10
положительных чётных чисел.
program NaborChetnyxChisel;
var i : integer;
begin
i := 2;
while i <= 20 do
begin
writeln (i);
i := i + 2
{ переход к следующему чётному числу }
end
end.
Здесь использован тот факт, что от одного чётного числа до следующего
две единицы. Если бы мы использовали для решения этого задания цикл for,
то нам пришлось бы дополнительно проверять каждое число на чётность (так
как в цикле for числа перебираются подряд; цикл while не ставит таких
ограничений: как нам надо перебирать числа, так мы и делаем).
Полезный совет: Чтобы не допустить логических ошибок при
использовании цикла while, проверьте, как будет работать цикл в первый и в
последний раз: обрабатываются ли он те числа, которые надо?
7.6.
Цикл repeat ... until
Формат записи этого цикла:
repeat
«операторы»
until «условие выхода»
Евгений Волосатов
42
Turbo Pascal
Цикл repeat (повторять) похож на цикл while. Но работает по-другому:
Сначала выполняются операторы после repeat, затем проверяется
«условие выхода» записанное после until. Если оно ложно, цикл
выполняеттся заново. Если же оно истинно, то цикл заканчивает свою работу.
То есть тело цикла repeat всегда выполнится хотя бы один раз. Потому
можно сказать, что цикл while сначала думает, а потом делает, а repeat
наоборот: сначала делает, а потом думает. Ещё раз обратите внимание, что
цикл repeat повторяется только тогда, когда условие после until ложно,
потому это условие и называется “условием выхода”.
Составим ещё раз программу счёта от 1 до 100, используя теперь цикл
repeat - until :
program Schet_ot_1_do_100;
var i : integer;
begin
i := 1 ;
repeat
writeln (i);
i := i + 1
until i > 100
end.
Сравните эту программу с аналогичной, которую мы оформляли с циклом
while. Сколько вы найдёте различий?
7.7.
Сравнение циклов
Мы познакомились с тремя циклами. Обобщим и сравним всё что узнали!
for «имя» := «от» to «до» do
«тело цикла»
Переменной цикла «имя» присваивается начальное значение «от», после
каждого выполнения тела цикла её значение увеличивается на 1, пока не
достигнет конечного значения «до». Тогда тело цикла выполнится в
последний раз. Переменную цикла нельзя изменять внутри цикла!
while «условие повторения» do
«тело цикла»
Если «условие повторения» истинно,
то выполняется тело цикла.
После чего цикл выполняется снова.
repeat
«тело цикла»
until «условие выхода»
Сначала выполняется тело цикла.
Затем проверяется «условие выхода».
Если оно ложно, цикл выполняется снова.
Семь основных различий между этими циклами:
Евгений Волосатов
1.
2.
3.
4.
5.
6.
7.
43
Turbo Pascal
Если в теле цикла больше одного оператора, то необходимо использовать
операторные скобки begin ... end. Они не нужны в цикле repeat.
Цикл for никогда не зациклится.
Цикл repeat выполняется как минимум один раз. Другие могут ни разу.
Если после слова do поставить точку с запятой, то получится пустой цикл.
Циклы while и repeat наоборот реагируют на значение условия цикла.
Любой цикл можно заменить циклом while.
Цикл for используют, когда заранее известно, сколько раз должен
выполниться цикл.
Программа нахождения
факториала числа n
тремя способами
(n! = 123…n)
for i := 1 to n do
f := f * i;
program Faktorial;
var i, n, f: integer;
begin
readln (n);
f := 1;
i := 1;
while i <= n do
begin
f := f * i;
i := i + 1
end;
i := 1;
repeat
f := f * i;
i := i + 1
until i > n;
writeln (f)
end.
Программа нахождения
суммы цифр числа
тремя способами
(k – кол-во цифр)
program SummaCifr;
var i,k,n,s: integer;
begin
readln (n);
s := 0;
k:=trunc(ln(n)/ln(10))+1;
for i := 1 to k do
begin
s:= s + n mod 10;
n:= n div 10
end;
while n <> 0 do
begin
s:= s + n mod 10;
n:= n div 10
end;
repeat
s:= s + n mod 10;
n:= n div 10
until n = 0;
writeln (s)
end.
Так как заранее не известно сколько цифр в числе, то перед
использованием цикла for приходится использовать хитрую формулу
вычисления количества цифр в числе.
7.8.
Самостоятельные задания
Выполните каждое задание тремя способами, используя сначала цикл for,
потом while, затем until.
1) Вывести на экран 22 звёздочки в ряд.
2) Дано число N. Вывести на экран N звёздочек в ряд.
3) Вывести на экран все нечетные чисел из интервала от 1 до 30.
Евгений Волосатов
4)
5)
6)
7)
8.
44
Turbo Pascal
Вывести на экран нечетные чисел от 1 до 30 в обратном порядке.
Найти сумму первых 10 чётных чисел.
Найти кол-во двузначных чисел, у которых первая цифра больше второй.
Найти произведение тех чисел от 1 до 50, которые кратны 17.
Натуральные числа
В этой главе рассматриваются действия с натуральными числами.
8.1.
Делители чисел
Решим задачу:
Дано число М, вывести на экран все его делители.
Как его решать? Для начала надо вспомнить, что является делителем
числа. Как известно, делителем числа А называют такое число В, что А
делится на В без остатка. Например, делителями 12 являются числа:
1, 2, 3, 4, 6 и 12.
В каком промежутке находятся делители любого числа M? В промежутке
от 1 до M. Значит, для поиска делителей числа М надо проверить все числа от
1 до М. И для каждого перебираемого числа проверять: делится ли на него М
без остатка? Если да, то вывести его на экран.
Для того чтобы проверить, делится ли одно число на другое без остатка,
надо найти этот остаток и сравнить его с нулём. Понятно, что если остаток
равен 0, то первое число делится на второе.
Чтобы перебрать все числа из промежутка, надо использовать цикл. Здесь
удобней всего использовать цикл for, так как нам заранее известно сколько
раз выполнится цикл (М раз).
Реализуем сказанное выше в процедуре, вставленной в программу.
program Deliteli_Chisla_M;
var M : integer;
procedure Deliteli (M : integer);
var i : integer;
begin
for i := 1 to M do
if M mod i = 0 { Если М делится на i }
then write (i, ’ ’);
writeln
end;
begin
write (’Введите число М: ’);
readln (M);
writeln (’Его делители следующие:’);
Deliteli (M)
end.
Евгений Волосатов
45
Turbo Pascal
8.1.1. Самостоятельные задания.



Замените в процедуре цикл for на while.
Найдите сумму всех делителей числа.
* измените эту программу и процедуру так, чтобы вводилось два числа, а
выводились только их общие делители, то есть такие числа, на которые
делится и первое число, и второе.
8.2.
Простые числа
Рассмотрим пример из предыдущего пункта, при М=97. Что в этом случае
выведет на экран программа? Два числа: 1 и 97. Как известно, те числа,
которые делятся только на единицу и на себя называются простыми. Поэтому
97 – простое число. Если число имеет больше двух делителей, то оно
называется составным.
Вот первые 10 простых чисел:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29.
Обратите внимание, что число 1 простым не является (и к составным его
тоже не относят). Простые числа играют в алгебре очень важную роль.
Поэтому давайте составим функцию, которая определяет, является ли
аргумент простым числом.
Как составить такую функцию? Здесь, в отличии от предыдущего
примера, нам нужно будет не выводить делители на экран, а считать их. И по
числу найденных делителей уже можно будет определить: является число
простым или нет. Как мы только что выяснили, простое число имеет всего два
делителя. Функция будет иметь результат логического типа (boolean): True –
если аргумент простое число и False в обраттном случае.
program prostye_chisla;
var M : integer;
function prostoe (p : integer) : boolean;
var i, s : integer;
begin
s := 0;
for i := 1 to M do
if p mod i = 0
then s := s + 1;
prostoe := s = 2
end;
begin
write (’Введите число М: ’);
readln (M);
if prostoe (M)
then writeln (’Это число простое.’)
else writeln (’Это число составное.’)
end.
Евгений Волосатов
46
Turbo Pascal
8.2.1. Самостоятельные задания



Если M=1, то ответ будет неверным. Исправьте программу!
Измените функцию так, чтобы она работала быстрее.
Составьте программу, которая найдет первые N простых чисел.
8.3.
Наибольший общий делитель
НОД двух чисел А и В – это максимальное число, на которое делится и А, и В.
Например:
НОД (14, 21) = 7,
НОД (16, 24) = 8.
Давайте составим процедуру, для нахождения НОД двух чисел. Как это
сделать?! Подумайте! Ещё раз внимательно прочитайте определение.
Так как найденный делитель должен быть общим, то на него должно
делиться и первое число, и второе. Кроме того, нам нужен максимальный
такой делитель. Если мы будем перебирать все общие делители в
возрастающем порядке, то интересующий нас делитель будет последним.
Переведём всё сказанное с русского языка на Pascal:
procedure NOD (a, b : integer; var rez : integer);
var i : integer;
begin
for i := 1 to a do
if (a mod i = 0) and (b mod i = 0)
then rez := i
end;
Составьте программу, которая будет использовать эту процедуру.
8.3.1. Самостоятельные задания.


Переделайте процедуру так, чтобы она находила НОД трёх чисел.
Если перебирать числа не в возрастающем порядке, а в убывающем, то
результатом будет первое найденное число (объясните почему). В этом
случае процедура может работать быстрее. Переделайте процедуру, чтобы
она искала делители в убывающем порядке! Используйте цикл while.
8.4.
Наименьшее общее кратное
НОК двух чисел А и В – минимальное натуральное число, которое делится
без остатка и на А, и на В. Исходя из определения можно искать это число
следующим образом. Начиная с числа А (или с В) перебирать натуральные
числа до тех пор, пока не найдем такое, которое будет без остатка делиться и
на А, и на В. Здесь удобней будет использовать цикл while. Цикл for не
подходит, потому что мы не знаем заранее, сколько чисел нам придётся
перебрать, пока найдём НОК.
Евгений Волосатов
47
Turbo Pascal
В заголовке цикла while надо записать такое условие, которое будет
верно до тех пор, пока мы не найдём нужное число. То есть, пока проверяемое
число не будет делиться и на А, и на В без остатка.
procedure NOK (a, b : integer; var rez : integer);
begin
rez := a;
while not ((rez mod a = 0) and (rez mod b = 0)) do
rez := rez + 1; { Увеличиваем i, пока оно не будет делиться и на а, и на b }
rez := i
end;
8.4.1. Самостоятельные задания


9.
Составьте программу для нахождения НОК с использованием формулы и
процедурой для нахождения НОД:
НОК (А, В) = (А*В) / НОД (А, В)
Как известно, НОК двух чисел всегда больше или равен большему из этих
чисел. Переделайте процедуру так, чтобы она начинала искать с
наибольшего из чисел a и b.
Массивы
9.1.
Определение и примеры
Очень часто приходится иметь дело с большим объёмом однотипных
данных. Например, изменения курсов валют за последние 3 года, или
температура внутри холодильной установки, которая измеряется каждый час и
т.п. Все эти данные надо уметь не только хранить, но и обрабатывать,
например, проводить статистические исследования.
№
Имя
Рассмотрим такой пример: список учеников в
1
Александр
группе. Это множество данных строчного типа. Их
2
Алексей
удобно записать в виде таблицы, например:
3
Валерия
Эта таблица состоит из 7 строк. В каждой строке
4
Павел
указан номер строки и соответствующее этому номеру
5
Антон
имя. То есть, по номеру строки можно однозначно найти
6
Владимир
конкретное имя. Например, номеру 4 соответствует имя
7
Николай
Павел. Получается, что мы можем говорить об имени, не
называя его конкретно, а только говоря, под каким номером оно записано.
Евгений Волосатов
48
Turbo Pascal
Таблицы бывают одномерными, как только что представленная и
многомерными. Основное их различие – количество чисел-координат для
указания элемента. В только что приведённом примере для указания имени
нужно назвать только номер. Например, номеру 3 соответствует имя Валерия.
Если же мы допишем ещё один
№
Группа 1
Группа 2
столбик, чтобы указать список учащихся
1
Александр
Николай
из двух групп, то для доступа к какому2 Алексей
Андрей
нибудь имени надо указать, во-первых,
номер строки, а во-вторых, номер группы.
3 Валерия
Александр
Это уже многомерная таблица, точнее
4 Павел
Андрей
двухмерная. Школьный журнал будет
5 Антон
Тимофей
примером 3-мерной таблицы, так как там
6 Владимир
Роман
для указания оценки необходимо выбрать
7 Николай
Даниель
название предмета, дату и имя ученика –
три координаты!
Может быть вы помните, как в начальных классах на природоведении вы
вели дневник природы. Каждый день нужно было отмечать, какая была
температура, облачность, были ли осадки, куда дул ветер. Таблица какого типа
это была? А книжка оценок сколькимерной таблицей будет?
Итак, таблицы используют для хранения каких-то однотипных данных,
будь то список учеников, цены в магазине, каталог фирм или оценки по
математике. Для хранения этих данных удобно использовать компьютер, так
как он позволяет не только хранить данные, но и быстро обрабатывать их.
Таблицу в компьютерной реализации принято называть массивом. В этом
случае все элементы массива должны содержать однотипные элементы.
Как уже говорилось, массивы могут быть многомерными. От размерности
массива зависит количество координат, которые надо указывать для доступа к
элементу. В информатике мы пока будем рассматривать только одномерные
массивы.
Чтобы начать работу с массивом, необходимо его описать. Описание
массива располагается там, где описываются все переменные в таком виде:
var A : array [1 .. 10] of integer;
Этой строкой мы описали массив (array) А, состоящий из 10 ([1..10])
элементов. Каждый элемент – это целое (integer) число. Можно сказать, что
мы определили сразу 10 переменных целого типа.
Для доступа к элементам массива используются квадратные скобки, в
которых записывают номер необходимого элемента:
A[1], A[2], A[5], A[10]
Давайте составим программу, которая задаёт массив из трех целых
элементов и находит их сумму.
program Summa_Elementov_Massiva_1;
var A : array [1 .. 3] of integer;
S : integer;
Евгений Волосатов
49
Turbo Pascal
begin
writeln (’Введите элементы массива: ’);
readln (A[1], A[2], A[3]);
S := A[1] + A[2] + A[3];
writeln (’Сумма элементов массива = ’, S)
end.
Эта программа имеет недостаток. Если вдруг придётся работать не с 3
элементами, а с 10, то эту программу придется подвергнуть значительной
модификации. Если же мы захотим ввести массив из N элементов, то общая
схема решения вообще окажется непригодной.
Поэтому все программы, которые мы составляем, должны обладать
свойством массовости, то есть работать с меняющимися данными. Должна
существовать возможность обращения не к конкретному элементу, а к
элементу, номер которого записан в виде переменной. Это делается очень
просто: в скобках вместо числа-константы записывается имя переменной (или
даже выражение). Например:
A[m], A[i], A[2*i+1], A[A[1]]
Для того, чтобы обрабатывать поочерёдно несколько элементов, надо
использовать цикл. Вот как изменится программа:
program Summa_Elementov_Massiva_2;
var A : array [1 .. 3] of integer;
S, i : integer;
begin
writeln (’Введите элементы массива: ’);
for i := 1 to 3 do
readln (A[i]);
S := 0;
{ Обнуляем сумму }
for i := 1 to 3 do
S := S + A[i];
writeln (’Сумма элементов массива = ’, S)
end.
Можно еще улучшить эту программу, объединив оба цикла в один, но мы
этого делать не будем, так как тогда вообще отпадёт необходимость в
использовании массива: сумму чисел можно подсчитать и так. Но дальше вы
увидете, что использование массивов иногда облегчает решение задач, а чаще
без них просто невозможно составить программу.
9.2.
Операции с элементами массива
Теперь вы уже можете составлять несложные программки для обработки
данных в массиве. Мы уже с вами находили сумму элементов массива.
Давайте теперь составим программу, которая
запросит массив из 10 элементов и увеличит на единицу каждый элемент.
Евгений Волосатов
50
Turbo Pascal
Как и раньше, для ввода массива мы будем использовать цикл for. Для
оптимизации программы можно сразу в этом же цикле увеличивать элементы
массива. Вот как это можно сделать:
program povyshenie_stipendii;
var A : array [1 .. 10] of integer;
i : integer;
begin
writeln (’Введите 10 элементов массива: ’);
for i := 1 to 10 do
begin
readln (A[i]);
A[i] := A[i] + 1 { увеличиваем на 1, как и просят }
end;
writeln (’После повышения получим:’);
for i := 1 to 10 do
writeln (i, ’-ый элемент равен ’, A[i])
end.
В программе можно использовать сразу несколько массивов. В одном
может храниться, например, зарплата, во втором – премия, а в третьем –
общий доход. Тогда, зная значения элементов первых двух массивов, можно
вычислить элементы третьего массива. Для массовости алгоритма запросим
количество элементов для обработки. Тогда из всех 100 элементов массива
будут задействованы только первые n элементов, где n – число
обрабатываемых элементов, оно вводится с клавиатуры. В этом случае
удобней описать массив таким образом:
var A : array [1 .. n] of integer;
Но так делать нельзя, так как компьютер перед запуском программы
должен знать сколько надо выделить ячеек памяти для хранения массива.
Переменная n же принимает значение только после запуска программы. В
результате все элементы массива с номерами больше n не будут задействованы
в программе, а будут только зря занимать память компьютера. И с этим
приходится смириться. Основная программа может быть такой:
program Tri_Massiva;
const max_n = 100;
var A, B, C : array [1 .. max_n] of integer;
i, n : integer;
begin
write(’Введите число служащих: ’);
readln (n);
if n > max_n
then begin
writeln(’Это число не может быть больше ’, max_n);
halt
{ оператор завершения работы программы }
end;
Евгений Волосатов
51
Turbo Pascal
writeln (’Введите зарплаты служащих: ’);
for i := 1 to n do
readln (A[i]);
writeln (’Введите премии служащих: ’);
for i := 1 to n do
readln (B[i]);
for i := 1 to n do
begin
C[i] := A[i] + B[i];
writeln (i, ’-ый служащий получит ’, C[i], ’ $’)
end
end.
9.3.
Анализ информации в массиве
Предположим, что у нас есть массив из 10 элементов:
7 30 4 15 32 6 18 41 6 40
И нам нужно найти максимальный элемент. Как бы вы сами нашли его?
Одного взгляда на этот ряд чисел достаточно, чтобы сказать: это число 41. Но
компьютер не может сразу взглянуть на все числа и найти нужное число. Ему
приходится перебирать числа по одному. Это можно представить так: числа
перед нами появляются по одному: сначала 7, потом 30, потом 4, затем 15...
последним мы увидим число 40. Как из них найти максимальное?
Сначала предположим, что максимальным является первое число.
Запишем где-нибудь, что 7 – это максимальное число. Когда перейдем ко
второму числу, сравним его с максимальным: 30 больше чем 7? Да! Значит,
теперь мы нашли новое максимальное число – 30. Продолжаем искать дальше.
Сравниваем следующий элемент с максимальным, то есть 4 сравниваем с 30. 4
больше 30? Нет! Со спокойной совестью переходим к следующему числу. Как
только новое число будет больше максимального, запомним его, как
наибольшее число. В конце концов мы найдем ответ: максимальное число 41.
Переведём сказанное на язык Pascal:
max := a [1];
if a [2] > max then max := a [2];
if a [3] > max then max := a [3];
if a [4] > max then max := a [4];
И так далее, до последнего элемента.
Но это не очень удачный способ, так как мы не всегда знаем заранее, сколько
элементов содержится в массиве. Поэтому лучше использовать цикл for:
max := a [1];
for i := 2 to 10 do
if a [i] > max
then max := a [i];
Чаще бывает необходимо найти не только максимальный элемент, но и его
номер. Например, если в таблице записаны стипендии студентов, то куда
Евгений Волосатов
52
Turbo Pascal
интереснее найти не только размер самой высокой стипендии, но и номер
студента, который её получает. Как это осуществить в программе? Для этого
при нахождении очередного элемента, претендующего на максимальный, надо
будет запомнить не только его значение, но и его номер.
program poisk_krutyx_studentov;
var A : array [1 .. 10] of integer;
i, max, maxNr : integer;
begin
writeln ('Введите стипендии 10 студентов!');
for i := 1 to 10 do
readln (A [i]);
max := A [1]; { в max – значение максимального элемента, }
maxNr := 1;
{ в maxNr – номер этого элемента в массиве }
for i := 2 to 10 do
if A [i] > max
then begin
max := A [i];
maxNr := i { Запоминаем номер макс. элемента }
end
writeln ('Самый богатый студент с номером ', maxNr)
end.
Попробуйте самостоятельно составить программу для нахождения
минимального элемента массива и его номера. Что произойдёт, если в массиве
будет несколько элементов с минимальными (максимальными) значениями?
10.
Рекуррентные соотношения
Найдите закономерность и продолжите следующие последовательности:
 2 4 6 8 ...
 7 10 13 16 ...
 2 4 8 16 ...
 1 3 9 27 ...
 1 1 2 3 5 8 13 ...
10.1. Последовательность Фибоначчи
Последняя последовательность задания называется последовательностью
Фибоначчи. Она начинается с двух единиц, а каждый последующей её элемент
равен сумме двух предыдущих. Следующий её элемент будет 8+13=21.
Найдем ещё несколько элементов этой последовательности:
1 1 2 3 5 8 13 21 34 55 89 144 233
Отличительной особенностью этой последовательности является то, что
для вычисления нового члена необходимо использовать значения двух
предыдущих. На языке математики это можно записать так:
Евгений Волосатов
53
Turbo Pascal
a1 = 1
a2 = 1
ai = ai-2 + ai-1 , где i > 2.
По этой схеме можно найти любой элемент последовательности
Фибоначчи, если известны значения предыдущих элементов, например:
a5 = a4 + a 3 = 2 + 3 = 5
Попробуем составить программу, которая найдет первые 10 членов
последовательности Фибоначчи. Так как для нахождения любого элемента,
начиная с третьего, надо знать значения двух предыдущих элементов, то в
этой программе удобно все элементы хранить в массиве. Так как нам надо
найти 10 элементов, то массив будет состоять из 10 целых чисел.
program Fibonacci;
var a : array [1 .. 10] of integer;
i : integer;
begin
a[1] := 1; { Первые два элемента заданы сразу }
a[2] := 1;
for i := 3 to 10 do {Ищем с 3 эл-та, так как первые два уже найдены}
a[i] := a[i-2] + a[i-1];
writeln ('Последовательность Фибоначчи: ');
for i := 1 to 10 do { Печатаем на экран }
write (a[i], ' ')
end.
10.2.
Другие рекуррентные последовательности
Рекуррентной последовательностью называется такая последовательность,
в которой новые элементы вычисляются через значения предыдущих.
Рекуррентная последовательность задаётся рекуррентным соотношением.
Рекуррентное соотношение – это формула, в которой каждый элемент
последовательности (начиная с некоторого) выражен через один или несколько
предыдущих.
Задача: Дана последовательность, заданная рекуррентным соотношением:
a1 = 1
a2 = 1
a3 = 1
an = an–3 + an–2 + an–1 , где n > 3
Найти первые m её членов, m < 100 (вводится с клавиатуры).
Программа, реализующая это задание, будет только немного отличаться
от программы поиска чисел Фибоначчи. Попробуйте сами её написать.
Задана ещё одна рекуррентная последовательность:
a1 = 3
a2 = 2
a3 = 5
an = an–3 + 2an–1, где n > 3
Вывести на экран все элементы которые, меньшие числа k.
Евгений Волосатов
54
Turbo Pascal
Если раньше мы искали вполне конкретное число элементов, то теперь
нам нужно будет искать элементы до тех пор, пока один из них не превысит
заданное число k (для строгости надо заметить, что это годится лишь для
возрастающей последовательности, такой, как эта).
Для реализации этой задачи в программе придётся отказаться от цикла
for и использовать цикл while, в заголовке которого будет проверяться: не
превышает ли последний найденный элемент числа k? Вот эта программа:
program Rekurrent_do_k;
var a : array [1 .. 100] of integer;
i, j, k : integer;
begin
write (’Введите число k: ’);
readln (k);
{ ввод начальных данных }
a[1] := 3; { Первые три элемента заданы сразу }
a[2] := 2;
a[3] := 5;
i := 3;
while a[i] < k do
begin
i := i + 1; {цикл while сам не увеличивает i }
a[i] := a[i-3] + 2 * a[i-1]
end;
writeln(’Элементы последовательности, меньшие ’,k,’:’);
for j := 1 to i-1 do { (i-1) — номер последнего найденного }
write(a[j], ’ ’)
{ элемента, который меньше k }
end.
Попробуйте запустить эту программу и в качестве начального данного
ввести число 29590. Правилен ли будет ответ? Прокомментируйте ситуацию!
10.3. Оптимизация программ
Допустим, что нам дано такое рекуррентное отношение:
a1 = 2
ai = 2ai-1 + 3, где i > 1.
Нужно найти 20 член этой последовательности. Решим её с массивом.
program Primer_1;
var a : array [1 .. 20] of integer;
i : integer;
begin
a[1] := 2;
for i := 1 to 20 do
a [i] := 2*a[i–1] + 3;
writeln (’Двадцатый элемент = ’, a[20])
end.
Евгений Волосатов
55
Turbo Pascal
Заметьте, что для вычисления 20 элемента программа находит
последовательно каждый элемент, хотя для вычисления нового используется
только последний элемент, остальные же лежат “мёртвым грузом”, так как
далее они нигде не используются. Давайте попробуем избавиться от хранения
излишней информаци. Другими словами, надо избавиться от массива. Так как
при вычислении нового элемента нам надо знать, чему равен только
предыдущий элемент, то будем его хранить в переменной pred, а новый
элемент – в переменной nov. Перед тем, как вычислять новый элемент, учтём,
что бывший новый элемент становится предыдущим, поэтому содержание
переменной pred надо будет поменять. Вот как изменится эта программа:
program Example2;
var pred, nov, i : integer;
begin
nov := 2;
for i := 1 to 20 do
begin
pred := nov; { новый стал старым }
nov := 2*pred + 3
end;
writeln (’Двадцатый элемент = ’, nov)
end.
Если вам будет всё ясно, то вы, наверное, заметите, что в этой
программе можно ещё избавиться от переменной pred, записав предложение
цикла в таком виде:
for i := 1 to 20 do
nov := 2 * nov + 3;
10.4.
Задача про интеллигентного студента
Студент решил каждую неделю ходить в театр. Чтобы накопить для
этого денег, он стал продавать газеты. Газеты он продает каждый день, с
понедельника до пятницы и зарабатывает по 5 литов в день. В театр он ходит
по субботам, покупая билет за 10 литов. Оставшиеся деньги он тратит в кафе.
Но в один прекрасный день билеты начали дорожать… Цена их неудержимо
увеличивалась на 5% каждую неделю. Сколько недель студент сможет ещё
ходить в театр на заработанные деньги (его заработок не изменяется)?
Для решения этой задачи удобно использовать рекуррентные
соотношения. Запишем рекуррентную последовательность, в которой будут
записаны цены билетов в театр на каждой неделе. Как известно, сначала билет
стоил 10 литов:
a1 = 10
По условию задачи, через неделю цена увеличилась на 5 %. Значит:
a2 = a1*1.05 = 10*1.05 = 10.5 (литов).
И так продолжается каждую неделю. Значит, можно записать в общем виде
цену билета на i-ой неделе:
Евгений Волосатов
56
Turbo Pascal
ai = ai-1 * 1.05 , где i > 1.
Так как студент каждую неделю зарабатывает по 25 литов (5 дней по 5 литов),
а оставшиеся после покупки билета деньги тратит в кафе, то задача сводится к
нахождению номера недели, когда стоимость билета превысит 25 литов.
program Teatr_i_Student_1;
const max = 100;
var bilet : array [1 .. max] of real;
i : integer;
begin
bilet [1] := 10;
i := 1; {номер недели}
while bilet [i] <= 25 do
begin
i := i + 1;
bilet [i] := bilet [i-1] * 1.05
end;
writeln (’Студенту не хватит денег на ’, i, ’-ой неделе.’)
end.
Перепишите эту программу без использования массива!
Рассмотрим теперь усложнённый вариант этой задачи, когда студент
лишние деньги не тратит, а откладывает на будущее. Тогда его капитал будет
всё время изменяться. После первой недели он заработает 25 лит:
b1 = 25
В субботу он потратит некоторую сумму на билет (ровно столько, сколько
он стоит, то есть a1) и через неделю зарабатывает опять 25 лит:
b2 = b1 – a1 + 25 = 25 – 10 + 25 = 40 (лит)
40 лит – это та сумма, которая будет у студента перед покупкой билета в
театр на второй неделе. Так продолжается каждую неделю:
bi = bi-1 – ai-1 + 25
Теперь студент сможет ходить в театр до тех пор, пока (условие после while)
не ai <= 25, а пока ai <= bi . Запишем это всё в алгоритм:
program Teatr_i_Student_2;
var bilet, stud : array [1 .. 100] of real;
i : integer;
begin
bilet [1] := 10;
stud [1] := 25;
i := 1;
while bilet [i] <= stud [i] do
begin
i := i + 1;
bilet [i] := bilet [i-1] * 1.05;
stud [i] := stud [i-1] - bilet [i-1] + 25
end;
writeln (’Студенту не хватит денег на ’, i, ’-ой неделе.’)
end.
Какие ответы даёт первая и вторая программы? Сравните их.
Евгений Волосатов
10.5.



Turbo Pascal
Самостоятельные задания
Дано натуральное число n. Найти сумму ряда:
2 + 22 + 222 + ... + 22...2 (n двоек)
Указание: каждый элемент этого ряда можно представить в виде элемента
рекуррентной последовательности. Вам нужно найти рекуррентное
соотношение и сложить первые n элементов последовательности.
Дано натуральное число n и целое чиисло s из отрезка [0, 9]. Найти сумму:
(s) + (ss) + (sss) + ... + (sss...s) (последне число состоит из n цифр s).
Найдите первые 10 элементов рекуррентной последовательности, которая
задана таким соотношением:
a1=1



57
a2=2
ai=i + ai-1 + ai-2
Найти сумму первых 10 элементов предыдущего задания.
Дано число. Проверить, является ли оно числом Фибоначчи.
Найдите первые 22 элемента последовательности, в которой первые два
элемента равны 1, каждый последующий чётный по счёту элемент – сумме
двух предыдущих, а каждый нечётный – произведению двух предыдущих.
Приложение
Здесь пойдёт речь о возможностях отладки программ в Turbo Pascal. Под
отладкой понимают процесс поиска ошибок в программе. Turbo Pascal
позволяет выполнять программу пошагово, то есть останавливаться после
выполнения каждой строчки. Это позволяет контролировать выполнение
программы. В моменты остановок можно просматривать значения переменных
и даже их изменять.
Пошаговый режим работы программы
Для запуска программы в пошаговом режиме нужно нажать клавишу F8
или выбрать команду Step over (шаг через) из меню Run (запуск). Программа
откомпилируется и на экране появится выделенная голубым цветом строка –
так помечен оператор, который будет выполнен следующим. Для его
выполнения надо нажать F8 или F7 (Trace into). F7 используют в том случае,
если выполнение оператора требует вызова какой-нибудь подпрограммы,
которую тоже нужно выполнить пошагово.
Можно временно прекратить пошаговый режим. Для этого переместите
курсор в то место, до которого вы хотите прервать пошаговое выполнение и
нажмите F4 (команда Go to cursor из меню Run). Компьютер выполнит
автоматически все операторы до строки указанной курсором. Эту клавишу
удобно использовать, если в программе есть какие-либо циклы, которые
выполняются много раз подряд.
Евгений Волосатов
58
Turbo Pascal
Ещё одна возможность указать место перехода из автоматического режима
к пошаговому – это установить Break point (точка останова) комбинацией
клавиш Ctrl-F8. В том месте, где находится курсор появится красная строка.
Теперь при любом запуске программы компьютер всегда остановится на
отмеченной строке, если, конечно, эта строка будет выполняться. Далее всё
как обычно – F7 или F8, либо Ctrl-F9 (Run) для продолжения работы
программы в автоматическом режиме. Для удаления точки останова нужно
перейти к отмеченной строке и опять нажать Ctrl-F8.
Учтите, что во время пошагового режима в программу нельзя вносить
никаких изменений! Если вы попытаетесь это сделать, то перед выполнением
следующего шага компьютер предупредит вас, что программа был изменена.
Для того чтобы прервать режим пошагового выполнения, нажмите Ctrl-F2
(команда Program reset из меню Run).
Просмотр/изменение переменных
В пошаговом режиме можно просматривать значения переменных. Для
этого надо нажать Ctrl-F4 (команда Evaluate/modify из меню Debug). В
появившемся окне ввести имя переменной и нажать Enter. Чуть ниже в поле
Result (результат) появится её текущее значение. В случае необходимости в
дальнейшем поле New value (новое значение) можно ввести новое значение,
которое немедленно будет присвоено указанной переменной.
Это окно можно использовать и не только в пошаговом режиме, но и в
обычном режиме ввода текста, как простой калькулятор. В поле Expression
(выражение) введите арифметическое выражение и нажмите Enter. Компьютер
подсчитает его значение и выдаст результат в поле Result.
Окно Watch
Можно сделать так, чтобы значение некоторых переменных всё время
было на экране. Для этого надо открыть окно Watch (следить), выбрав
комманду Watch из меню Debug.
В появившееся окно можно добавлять новые переменные (клавиша Insert),
удалять имеющиеся (Delete) и изменять существующие (Enter).
Если вас не устраивают размеры и расположение окон, вы всегда можете
это всё поменять. Поэксперементируйте сами с меню Window!
Евгений Волосатов
59
Turbo Pascal
Работа с текстовыми файлами
Для обработки текстовых файлов необходимо:
во-первых, описать файловую переменную,
во-вторых, связать её с конкретным файлом,
в-третьих, открыть файл для чтения или для записи,
а в-последних, после работы с файлом, закрыть его.
Напишем программу, которая найдёт сумму чисел из файла data.txt
(на каждой строке будет по одному числу) и запишет её в файл sum.txt.
program Summa_chisel_iz_faila;
var f1, f2 : text;
{ f1 и f2 файловые переменные
}
a, sum : integer;
{ для работы с текстовыми файлами }
begin
assign (f1, 'data.txt'); { связать f1 c файлом data.txt
}
reset (f1);
{ открыть файл для чтения
}
sum := 0;
while not eof (f1) do
{ пока не конец файла ...
}
begin
readln (f1, a);
{ считать одно число со строки
}
sum := sum + a
{ и прибавить его к сумме
}
end;
close (f1);
{ закрыть файл с данными
}
assign (f2, 'sum.txt'); { связать f2 с файлом sum.txt
}
rewrite (f2);
{ создать и открыть его для записи}
writeln (f2, sum);
{ записать сумму в файл f2
}
close (f2)
{ закрыть этот файл
}
end.
Перед запуском этой программы нужно создать файл data.txt на
каждой строчке которого записать по одному числу. После запуска появится
новый файл sum.txt, в котором будет сумма чисел из первого файла.
Процедура reset открывает файл для чтения. Читать из него данные
можно обычным оператором readln (f, …), как если бы всё что есть в
файле было бы введено с клавиатуры, f показывает, что читать надо из файла.
Функция eof (end of file) проверяет, дошли ли мы до конца файла.
Для проверки конца строки можно использовать функцию eoln (end of line).
Процедура rewrite создаёт новый файл с именем, который был указан в
assign. Если такой файл уже был, то он затирается и создаётся заново.
После работы с файлом его надо обязательно закрыть процедурой close.
Напишите программу, которая скопирует все числа из файла data.txt в
файл copy.txt.
Замечания, вопросы и пожелания пишите автору:
pascal@dkd.lt
Download