Составитель: А

advertisement
Составитель А.М. Сулейманова
УДК 681.3
ББК 32.973.26-018.2.75
РЕАЛИЗАЦИЯ АЛГОРИТМОВ С ИСПОЛЬЗОВАНИЕМ
ПРОЦЕДУР В ИНТЕГРИРОВАННОЙ СРЕДЕ ТУРБО ПАСКАЛЬ:
Методические указания к лабораторному практикуму по курсу
«Информатика и программирование»/ Уфимск. гос. авиац. техн.
ун-т; Сост. А.М Сулейманова.- Уфа, 2003.- 22 с.
Содержатся сведения, необходимые для составления
алгоритмов и программ, приведены способы реализации программ,
содержащих процедуры. Практическое применение иллюстрируется
различными примерами. Обсуждается методика выполнения
лабораторной работы. Приведены перечни заданий на выполнение
лабораторных работ.
Библиогр.: 3 назв.
Рецензенты: Р.В.Насыров, Л.Ф.Розанова
© Уфимский государственный
авиационный технический
университет, 2003
3
СОДЕРЖАНИЕ
1. ЦЕЛЬ РАБОТЫ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2. ТЕОРЕТИЧЕСКАЯ ЧАСТЬ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1. Что такое подпрограмма . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2. Описание процедур . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3. Описание функций . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4. Сферы действия имен . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5. Параметры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6. Рекурсия . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.7. Опережающее описание . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.8. Стандартные процедуры и функции . . . . . . . . . . . . . . . . . . 18
3. ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ . . . . . . . . . . . . . . . . . . . . 19
4. ТРЕБОВАНИЯ К ОТЧЕТУ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5. КОНТРОЛЬНЫЕ ВОПРОСЫ . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
6. ВАРИАНТЫ ЗАДАНИЙ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
СПИСОК ЛИТЕРАТУРЫ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4
ЛАБОРАТОРНАЯ РАБОТА
РЕАЛИЗАЦИЯ АЛГОРИТМОВ С ИСПОЛЬЗОВАНИЕМ
ПРОЦЕДУР В ИНТЕГРИРОВАННОЙ СРЕДЕ ТУРБО ПАСКАЛЬ
1. ЦЕЛЬ РАБОТЫ
Целью настоящей работы является изучение методов
программирования алгоритмов с использованием процедур.
2. ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
Всякую сложную задачу для лучшего понимания и
облегчения ее решения полезно разделить на простые подзадачи.
Если каждая программа предназначена для решения определенной
задачи, то должен существовать способ разделения программ на
некоторые структурные единицы. Такие структурные единицы
программ известны как подпрограммы.
2.1. Что такое подпрограмма
Часто в программах возникает необходимость выполнить
несколько раз одну и ту же последовательность операторов (не
циклически). Конечно, можно соответствующий фрагмент
скопировать в программе несколько раз в нужные места, однако
при таком подходе текст программы получается обширным и
трудным для понимания. Кроме того, для объемной программы
требуется больше памяти. Поэтому для упрощения текста
программ, а также для исключения необходимости заниматься
копированием предложена концепция подпрограмм.
Функционально
самостоятельная
часть
программы,
обладающая собственным именем и набором локальных имен,
известна как подпрограмма. Вызов подпрограммы осуществляется
по ее имени из любых точек тела программы и любое количество
раз.
Помимо упрощения текстов программ и избавления от
копирования, подпрограммы - это еще средство структурирования
программ. Идея в том, чтобы программа состояла не из огромного
числа операторов, а из относительно самостоятельных частей
(подпрограмм), каждой из которых назначена отдельная,
сравнительно узкая роль. Причем подпрограммы могут включать
в себя другие подпрограммы, т.е. допускается вложенность
подпрограмм.
5
Для того чтобы понять суть структурирования программ,
рассмотрим задачу "Попасть из города А в город Б." Эту задачу
можно структурировать следующим образом.|
I. Добраться до вокзала
II. Приобрести билет
III. Сесть в поезд
IV. Доехать до города Б
Каждое из перечисленных действий также поддается
структуризации. Например:
I. Добраться до вокзала
1) выйти из дома
2) поймать такси
3) доехать до вокзала
Возможна дальнейшая детализация, и так до тех пор, пока
задача не будет разложена на самые элементарные действия как раз то, что нужно, когда требуется создать программу
решения задачи на компьютере. Если бы решение задачи
"Попасть из города А в город Б" потребовалось описать
средствами языка программирования, то отдельные действия, на
которые мы разложили эту задачу, можно было бы представить в
виде подпрограмм, вложенных одна в другую.
Структурированные
программы
более
просты
в
понимании, их легче создавать и отлаживать. Кроме того,
отдельные подпрограммы, имеющие определенное, узкое
назначение, можно использовать в различных программах
многократно.
Подпрограмма, чтобы ее можно было вызывать в
программе, должна быть объявлена в разделе описаний
программы. Объявить подпрограмму - значит указать ее
заголовок (с используемыми в ней формальными параметрами),
описать локальные переменные и, наконец, задать ее тело. В
разделе описаний подпрограммы могут быть объявлены новые
подпрограммы, которые, в свою очередь, также могут включать
подпрограммы. Иными словами, возможно множество уровней
вложения подпрограмм, как это показано на примере задачи
"Попасть из города А в город Б" выше.
В языке программирования
приняты два вида
подпрограмм: процедуры и функции.
2.2. Описание процедур
Предположим, создается программа-редактор текстов. В
этой программе должна быть предусмотрена возможность
6
отделять фрагменты редактируемых текстов один от другого
чертой, состоящей из одинаковых символов, скажем, знаков
"минус". Чтобы реализовать эту возможность, в программередакторе можно создать соответствующую процедуру.
Схематически и эта программа с процедурой выглядит так:
program editor;
…
{Разделы описания меток, констант, типов и переменных}
…
procedure line;
var symbol: integer;
begin {Начало тела процедуры}
write ('{');
for symbol:=1 to 78 do
write ('-');
writeln ('}');
end; {Конец тела процедуры}
…
begin {Начало тела программы}
…
line; {Вызов процедуры}
…
end. {Конец тела программы}
Здесь в программе Editor описана процедура Line. На схеме
программы видно, что описания процедур (это же касается и
функций) должны находиться в конце раздела описаний программы
(после описаний меток, констант, типов и переменных), перед
началом ее тела. Бросается в глаза, что структура процедуры
повторяет структуру программы - в ней также есть заголовок, раздел
описаний и тело. Начинается процедура с зарезервированного слова
PROCEDURE, за которым через пробел следует имя процедуры.
Строка заголовка обязательно должна завершаться точкой с запятой.
Затем идет раздел описаний процедуры. В рассматриваемой
процедуре описана всего лишь единственная переменная, но, как и в
программе, здесь могут быть объявлены метки, константы, типы, а
также функции и другие процедуры, вложенные в процедуру Line.
После раздела описаний процедуры следует ее тело. Тело
процедуры содержит последовательность операторов, заключенных
в
операторные
скобки
(представляющие
собой
пару
зарезервированных слов BEGIN … END). Для вызова процедуры
7
Line из тела программы достаточно указать ее имя в нужном месте.
Пример вызова нашей процедуры можно видеть в теле программы
Editor.
Данная процедура отображает на экране строку из 78
символов "минус" (-). А если возникнет необходимость, чтобы в
различных редактируемых документах
фрагменты текста
разделялись строкой других символов или чтобы длина этой строки
была иной? Тогда в теле программы, вероятно, должен быть
предусмотрен специальный оператор Read, позволяющий задать
нужную информацию (символ и длину строки), которую затем
каким-то образом следует передать в процедуру. Передача
информации из тела программы в процедуру осуществляется с
помощью механизма параметров. Соответствующим образом
модифицированная схема программы, представленная выше,
выглядит так:
program editor;
…
{Разделы описания меток, констант, типов и переменных}
…
procedure line (ch:char; ln:integer);
var symbol:integer;
begin {Начало тела процедуры}
write ('{');
for symbol:=1 to ln do
write ('ch');
writeln ('}');
end; {Конец тела процедуры}
…
begin {Начало тела программы}
…
read(a,b); {Задаются символ и длина строки}
line(a,b); {Вызов процедуры}
…
end. {Конец тела программы}
Чем вторая схема программы отличается от первой? В
описании процедуры, в заголовке после ее имени, во-первых,
заданы
формальные
параметры
(ch:char;
ln:integer),
предназначенные для передачи информации о выбранном символе
(ch) и длине строки (ln) из программы в процедуру. Кроме того,
идентификаторы указанных параметров заменили в теле
8
процедуры фиксированные значения (78 и '-'). Кстати,
формальными параметрами, представленными в описании
процедуры, можно манипулировать в теле этой процедуры так же,
как и переменными.
В теле программы также имеют место два изменения. Вопервых, явился новый оператор (Read (a,b)), позволяющий задать
произвольные символ и длину строки. Во-вторых, оператор вызова
процедуры (Line (a,b))
теперь снабжен фактическими
параметрами. Переменные А и В, значения которых вводятся (с
клавиатуры) с помощью оператора Read, а затем передаются
соответствующим формальным параметрам, указанным в
описании процедуры Line, должны быть описаны в разделе
объявления переменных программы как переменные типов Char и
Integer соответственно.
2.3. Описание функций
Помимо
процедур,
в
Turbo
Pascal
применяются
подпрограммы и иного вида - функции. Рассмотрим пример.
В Turbo Pascal не существует стандартной функции,
вычисляющей данную степень заданного числа. Однако ничто не
мешает создать такую функцию самостоятельно. Вот как может
выглядеть схема некоторой программы, в которой определена
функция вычисления степени (пусть числа, степени которых
вычисляет функция, а также показатели степеней являются
целыми):
program example;
{Разделы описания меток, констант, типов и переменных}
…
function power (num,pow:integer):integer;
var i:integer; a:real;
begin {Начало тела функции}
a:=num;
for i:=1 to pow do
a:=a*num;
power:=num
end; {Конец тела функции}
…
begin {Начало тела программы}
…
read(a,b);
x:=power(a,b)+y; {Обращение к функции}
…
9
end. {Конец тела программы}
В программе Example описана функция Power. На этой
схеме программы видно, что описания функций (как и процедур)
должны находиться в конце раздела описаний программы (после
описаний меток, констант, типов и переменных), перед началом
ее тела. Структура функции (как и процедуры) повторяет
структуру программы. Первой идет строка заголовка, которая
начинается с зарезервированного слова FUNCTION. За ним через
пробел следует имя функции; далее в скобках - перечень
формальных параметров; затем двоеточие, за которым
указывается
тип
значения,
возвращаемого
функцией.
Завершается строка заголовка точкой с запятой. Сразу под
заголовком функции расположен ее раздел описаний. В
рассматриваемой функции определены всего лишь две
переменные, но, как и в программе, здесь могут быть объявлены
метки, константы, а также другие функции и процедуры,
вложенные в функцию Power.
После раздела описаний функции следует ее тело. Тело
функции содержит последовательность операторов, заключенных
в операторные скобки. Для обращения к функции Power в теле
программы достаточно указать ее имя в нужном месте.
Кстати, в отличие от процедур, активизируемых с помощью
оператора вызова (включающего имя процедуры и, может быть,
фактические параметры), имя функции должно упоминаться в
выражении. Пример обращения к нашей функции можно видеть в
теле программы Example (здесь взято произвольное выражение).
У функций (в отличие от процедур) имеются и другие
особенности. Например, в результате использования функции
возвращается некоторое значение. Тип возвращаемого значения
указывается в описании функции (в заголовке). Если имя
процедуры используется только для ее вызова, то с именем
функции ассоциируется некоторое возвращаемое значение.
Чем еще функции отличаются от процедур? Поскольку
функция должна возвращать некоторое значение, в ее теле
обязательно должен присутствовать оператор присваивания, в
правой части которого указано имя функции.
Когда лучше использовать процедуры и когда функции?
Это зависит от конкретного случая. Если подпрограмма
вычисляет единственный результат, ее можно реализовать как
функцию. Если же от подпрограммы требуется вычислить
несколько значений, ее лучше оформить в виде процедуры.
10
2.4. Сферы действия имен
Структура
подпрограммы
повторяет
структуру
программы, и в каждой из подпрограмм можно объявлять свои
переменные,
метки,
константы,
типы
и
вложенные
подпрограммы (с собственными именами). Кроме того,
описание подпрограммы может включать список формальных
параметров, и с этими параметрами можно обращаться в данной
подпрограмме как с переменными. Однако как избежать при
этом путаницы?
Структуру программы (т.е. схему вложения в нее
подпрограмм), а также сферы действия имен лучше всего
изобразить графически. Обычно для этого используются
прямоугольники, вложенные один в другой (рис. 2.1).
На этой схеме представлена программа А, в которой
объявлены подпрограммы В (процедура) и С (функция).
Подпрограмма В, в свою очередь, содержит вложенные
подпрограммы D (функция) и Е (процедура).
Итак, какие идентификаторы доступны в той или иной
подпрограмме? Имена X, Y, Z, объявленные в программе А,
доступны во всех по; программах, существующих в этой
программе. Имена М, N, объявленные в процедуре В, кроме
самой этой подпрограммы, доступны также функции D и
процедуре Е.
Рис. 2.1. Каждое имя доступно в своей подпрограмме,
также во всех "объемлющих" подпрограммах
Имена, объявленные в подпрограммах С (Р, R, S), D(G,Н) и
Е(К,L) доступны только в пределах этих подпрограмм. Иными
словами, для любой подпрограммы доступны все имена,
объявленные в ней, а также во всех "объемлющих"
11
подпрограммах, а также в самой программе (т.е. "выше").
Однако для той же подпрограммы недоступными являются все
имена, объявленные во вложенных в нее подпрограммах (или
"ниже").
Имена, объявленные в подпрограмме (и доступные во
всех вложенных подпрограммах), будут для данной
подпрограммы локальными, а для вложенных в нее
подпрограмм - глобальными. Иными словами, понятия
"локальные" и "глобальные" часто относительны. Однако
имена, объявленные в основной программе, глобальны для
всех описанных в ней подпрограмм.
Существует еще одна проблема: что если в подпрограмме
и в основной программе были объявлены две переменные с
одинаковыми именами? В этом случае основная программа
"видит" свою переменную, а подпрограмма - свою, т.е. для
данного идентификатора всегда используется "наиболее
локальное" описание. Это одно из преимуществ языка Turbo
Pascal - возможность выбирать имена в подпрограммах, не
заботясь о том, что они могут совпасть с именами из
объемлющих подпрограмм.
2.5. Параметры
Параметры, указываемые в операторе вызова процедуры,
называются фактическими параметрами, а параметры,
перечисленные в заголовке описания процедуры, это
формальные параметры.
Таким образом, в описание подпрограммы (точнее, в ее
заголовок) может быть включен список параметров. В этом
случае заголовок подпрограммы (пусть это будет процедура)
принимает вид
procedure proc_name (a,b,c:type_l; d,e,f:type_2;..,x,y,z:type_n);
Здесь А, В, С, D, E, F, .... X, Y, Z - формальные параметры, а
Туре_1, Type_2, ..., Type_N - типы данных, которым принадлежат эти
параметры. Само собой разумеется, что групп параметров (т.е.
типов параметров) может быть любое количество, так же как любое
количество параметров может быть в той или иной группе.
Если в описании подпрограммы имеются формальные
параметры, при ее вызове непременно должны указываться
фактические параметры. При этом количество фактических и
формальных параметров и их принадлежность к определенным
типам данных должны совпадать.
12
Вот пример процедуры:
procedure proc_name (x, у:integer);
begin
x := 8;
y := 5;
writeln (x*y/2)
end;
Процедура Proc_Name описана с двумя формальными
параметрами, принадлежащими типу Integer. Этим двум
параметрам в процедуре присваиваются некоторые значения,
которые затем участвуют в каких-то вычислениях.
Теперь, предположим, вы вызвали эту процедуру из
основной программы:
number := 55;
proc_name (number, 4);
Здесь переменная Number (которой до этого было
присвоено значение 55) указывается в качестве первого
фактического параметра при вызове процедуры Proc_Name.
Какое значение будет иметь переменная Number по
возвращении управления в основную программу? Естественно,
55. Конечно, значение переменной Number было передано
формальному параметру X, которому затем в подпрограмме
было присвоено значение 8. Однако в данном случае параметр
Х на переменную Number никак не воздействует. Значение
переменной в основной программе здесь абсолютно не зависит
от того, что происходит в процедуре. Тут мы имеем дело с
параметром-значением, который просто передает значение
переменной Number в процедуру.
Существует и иной вид параметров, известный как
параметры-переменные.
Часто
результатом
работы
подпрограммы может быть не только вывод на экран (как в
процедуре Line из примера выше), но и вычисление некоторых
данных, т.е. требуется передавать значения не только из
программы в процедуру, но и обратно - из процедуры в
программу. Это осуществляется с помощью параметровпеременных. При их использовании создается (до окончания
работы подпрограммы) устойчивая связь между фактическим
и соответствующим ему формальным параметром. Когда в
13
процедуре значение формального параметра изменяется,
претерпевает изменение и значение фактического параметра.
Но каким образом отличить параметры-значения от
параметров переменных? Все очень просто. Для этого в
перечень формальных параметров в описании процедуры
вводится
зарезервированное
слово
VAR.
Параметры,
представленные в списке формальных параметров до слова
VAR,
являются
параметрами-значениями.
Параметры,
перечисленные после слова VAR, представляют собой
параметры-переменные. Заголовок процедуры, в которой
описаны как параметры-значения, так и параметрыпеременные, имеет следующий вид:
procedure proc_name (a,b,c:type_1; d,e,f:type_2; varx,y,z:type_n);
Здесь А, В, С, D, E, F - параметры-значения (поскольку перед
ними зарезервированного слова VAR нет), а Х, Y, Z -параметрыпеременные.
В качестве фактических параметров, предназначенных для
передачи
формальным
параметрам-переменным,
не
допускается использование констант, поскольку их значения
могут быть изменены в процедуре.
Вот пример описания процедуры:
procedure proc_name (x : integer; VAR у : real);
begin
у := x*5
end;
(Процедура Proc_Name описана с двумя параметрами параметром-значением X и параметром-переменной Y. Затем в
теле процедуры с этими параметрами производятся некоторые
действия.)
А вот фрагмент основной программы:
number := 1;
power := 50;
proc name(number, power);
(Здесь переменные Number и Power, которым до этого
были присвоены значения 1 и 50 соответственно, указывается
14
в качестве фактических параметров при вызове процедуры
Proc_Name.)
После завершения работы процедуры переменная Number
останется со значением 1, поскольку она передается в качестве
фактического параметра формальному параметру X, а X - это
параметр-значение. Однако переменная Power примет новое
значение - 5, поскольку она передается в качестве
фактического параметра формальному параметру А, который
представляет собой параметр-переменную.
Рис. 2.2
На рис. 2.2 представлены взятые из последнего примера
строка заголовка из описания процедуры и строка вызова этой
процедуры из тела программы. Здесь же указаны все
разновидности используемых параметров.
Параметр-значение
копирует
значение
некоторой
переменной из программы и передает его в процедуру.
Процедура каким-то образом манипулирует этой копией
значения, а затем по завершении работы процедуры эта копия
теряется. Исходное значение переменной при этом остается
неизменным. Параметр-переменная предоставляет доступ
процедуре непосредственно к самой переменной из программы.
При этом процедура манипулирует значением этой переменной
и по завершении работы процедуры переменная из программы
остается с новым значением.
Иными словами, параметр-значение - это средство
передачи данных в одном направлении: из программы в
процедуру, а параметр-переменная позволяет передавать
данные в обоих направлениях.
То, что говорилось о параметрах применительно к
процедурам, полностью относится и к функциям. Вот как могут
выглядеть строка заголовка из описания функции и обращение к
этой функции в теле программы:
function func_name (x : integer; VAR у : real):real;
15
…
с: =func_name(a,b)+d+e;
Здесь отражены особенности, присущие функциям.
Например, в заголовке описания функции указано, значение
какого типа возвращает данная функция (Real). Также при
обращении к функции в теле программы имя функции
употреблено в выражении (в нашем примере взято произвольное
выражение). Что же касается параметров, здесь все так же, как и
для процедур.
Дурным тоном считается применение зарезервированного
слова VAR в списке формальных параметров функции, хотя это и
не запрещается прямо, т.е. использование в функции параметровпеременных нежелательно: функция по определению должна
возвращать единственное значение.
2.6. Рекурсия
Что произойдет, если в теле подпрограммы окажется
оператор вызова этой же подпрограммы? Видимо, подпрограмма
вызовет саму себя и теоретически будет продолжать делать это
бесконечное количество раз, если автор программы не
предусмотрел выхода при определенных условиях из данного
замкнутого круга.
Во всех рекурсивных подпрограммах должно присутствовать
какое-то условие прекращения рекурсии. При этом единственном
условии рекурсия должна прекратиться; при всех остальных
условиях она будет продолжаться.
Итак, в Turbo Pascal допускается присутствие в теле
подпрограммы
оператора
вызова
самой
себя.
Такие
подпрограммы называются рекурсивными, а такой способ вызова
рекурсией. Рекурсия оказывается весьма удобным подходом при
решении некоторых задач, например, при вычислении
факториала. Вот как определяется факториал положительного
целого числа:
!а=1*2*...*(а-1)*а
Если а=1, то !1=1; если а=2, то !2=1*2 : если а=3, то !3=1*2*3 и
т.д. Иными словами, здесь при вычислении факториала для
каждого последующего числа используется предыдущий
результат.
А вот как может выглядеть текст описания,
соответствующий функции:
16
function fact (a:integer): integer;
begin
if a=0 then fact:=l
else fact:=a*fact(a-l)
end;
Для того чтобы обратиться к данной функции из
основной программы (и тем самым инициировать рекурсию),
в теле программы должно присутствовать выражение, в
котором фигурирует имя функции Fact (например,
write(fact(b))), где В - число, факториал которого требуется
вычислить. Кроме того, В здесь - фактический параметр,
который сдается формальному параметру А в описании
функции. В результате первого рекурсивного обращения к
функции Fact (т.е. обращения к самой себе) в памяти
компьютера создается копия этой функции (с собственными
локальными переменными), которой передается параметр со
значением В-1. В результате второго рекурсивного обращения
к функции Fact создается еще одна копия этой функции (как
бы вложенная в первую и тоже с собственными локальными
переменными), которой передается параметр со значением
В-2. Затем функция Fact будет обращаться к самой себе (и при
этом будут создаваться все новые ее копии, существующие
независимо одна от другой) до тех пор, пока она (в последней
своей копии) не возвратит значение 1 (т.е. во всех этих копиях
будет вычисляться значение параметра, каждый раз
уменьшающееся на 1). Схематически это изображено на
рис.2.3.
"Движение вглубь" продолжается до тех пор, пока
параметр, с которым в очередной раз будет иметь место
обращение к функции Fact, не окажется равным 0. К моменту
завершения рекурсии в программе будут созданы В копий
функции Fact, в последней из которых ее значение окажется
равно 1. После этого будет иметь место "движение изнутри
наружу", т.е. значение функции Fact из очередной
"внутренней" копии функции будет умножаться на значение А
из "внешней" копии и при этом "внутренняя" копия функции
будет ликвидироваться. По завершении этого процесса
окажется вычислен факториал числа В. Рассмотренная только
что функция реализует рекурсивный алгоритм вычисления
факториала. Мы уже знаем, что при этом создается множество
копий функции (каждая из которых имеет собственные
17
локальные переменные). Вся эта информация содержится в
стеке - особым образом организуемой области памяти.
Рис. 2.3. Каждый прямоугольник представляет на
этой схеме один из рекурсивных вызовов функции Fact
2.7. Опережающее описание
Помимо
непосредственной,
возможна
косвенная
рекурсия, при которой подпрограмма А вызывает подпрограмму
В, а подпрограмма В, в свою очередь, - подпрограмму A. Но как
описать две подпрограммы, вызывающие одна другую? Ведь в
описании любой из них, которое расположено первым в разделе
описаний основной программы, будет вызов подпрограммы,
описываемой дальше (т.е. в момент вызова еще неизвестной).
18
Выход из этого затруднения предоставляет так называемое
опережающее описание.
В Turbo Pascal допускается применение опережающего
описания используемой подпрограммы, которое состоит только
из ее заголовка, за которым следует зарезервированное слово
FORWARD. В этом случае полный текст подпрограммы может
быть расположен дальше в любом месте раздела описаний
процедур и функций.
Как это будет выглядеть на примере подпрограмм А и В, о
которых шла речь выше? Схема исходного текста программы, в
которой описаны указанные подпрограммы, может выглядеть
так:
program k;
var i:integer; j:real;
procedure a (x:integer); forward; {Опережающее описание}
procedure b (y:real);
begin
…
a(i) {Вызов еще не определенной процедуры}
end;
procedure a;
begin
…
b(j)
end;
Здесь для процедуры А использовано опережающее
описание. Затем идет описание процедуры В, из которой
вызывается процедура А. Однако, благодаря опережающему
описанию процедуры А, компилятор не зафиксирует это как
присутствие неизвестного идентификатора (т.е. ошибку). За
описанием процедуры В следует описание процедуры А (без
повторения списка формальных параметров, поскольку
информация о параметрах уже содержится в опережающем
описании процедуры A).
2.8. Стандартные процедуры и функции
В языке программирования Turbo Pascal, помимо
подпрограмм,
определенных
пользователем,
существует
множество стандартных (или встроенных) процедур и функций.
Так, например, стандартные процедуры Read и ReadLn (ввод с
клавиатуры), Write и WriteLn (вывод на экран), а также функции
19
Sqr (возведение в квадрат), Sqrt (извлечение квадратного корня),
Chr (преобразование кода ASCII в соответствующий символ) и Abs
(вычисление абсолютного значения).
3. ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ
Для выполнения работы необходимо:
1. Повторить правила техники безопасности при работе с
вычислительной техникой.
2. Изучить раздел "Процедуры" лекционного курса, а также
теоретическую часть настоящих методических указаний.
3. Получить у преподавателя вариант задания (варианты
заданий приведены в разделе 6 настоящих методических указаний).
4. Написать программу на Турбо Паскале (при необходимости
используя предварительно разработанный алгоритм).
5. Ввести программу в компьютер, отладить и результаты
выполнения показать преподавателю.
6. В соответствии с требованиями, приведенными в разделе 4,
оформить отчет по лабораторной работе.
7. Защитить лабораторную работу, продемонстрировав
преподавателю:
отчет по лабораторной работе;
умение решать аналогичные задачи;
теоретические знания.
При подготовке к защите для самопроверки рекомендуется
ответить на контрольные вопросы, приведенные в разделе 5.
4. ТРЕБОВАНИЯ К ОТЧЕТУ
Отчет по выполненной лабораторной
содержать:
титульный лист;
условие задания;
текст программы на языке Турбо Паскаль.
работе
должен
5. КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Что такое подпрограмма?
2. Чем отличаются процедуры от функций?
3. Что такое глобальные и локальные имена?
4. Что такое параметры и как они описываются?
5. Что такое рекурсия?
6. Что такое косвенная рекурсия и опережающее описание?
7. Что такое стандартные процедуры и функции?
20
6. ВАРИАНТЫ ЗАДАНИЙ
Вариант I
.
1.Даны
действительные
числа
а1,...,аn,
b1,...,bm.
В
последовательности а1,...,аn и в последовательности b1,...,bm все
члены, следующие за членом с наибольшим значением (за первым
по порядку, если их несколько), заменить на 0,5.
2. Даны натуральное число n, целые числа a1,...,an. Рассмотреть
отрезки последовательности a1,...,an (последовательности идущих
подряд членов), состоящие из полных квадратов. Получить
наибольшую из длин рассматриваемых отрезков.
Вариант 2
1. Даны целые числа а1,...,аn, b1,...,bm, k. Если в
последовательности а1,...,аn нет ни одного члена со значением k, то
первый по порядку член этой последовательности, не меньший всех
остальных членов, заменить на значение k. По такому же правилу
преобразовать последовательность b1,...,bm применительно к значению
10.
2. Даны натуральное число n, целые числа а1,...,аn. Рассмотреть
отрезки последовательности а1,...,аn (последовательности идущих
подряд членов), состоящие из степеней пятерки. Получить
наибольшую из длин рассматриваемых отрезков.
Вариант 3
1. Дано натуральное число n. Среди чисел 1,2,...,n найти все те,
которые можно представить в виде суммы квадратов двух
натуральных чисел. (Определить процедуру, позволяющую
распознавать полные квадраты).
2. Даны натуральное число n, целые числа а1,...,аn. Рассмотреть
отрезки последовательности а1,...,аn (последовательности идущих
подряд членов), состоящие из простых чисел. Получить наибольшую
из длин рассматриваемых отрезков.
Вариант 4
1. Даны действительные числа x1, у1, х2, y2,..., x10, y10. Найти
периметр
десятиугольника,
вершины
которого
имеют
соответственно координаты (x1,y1), (x2,y2),…,(х10,y10). (Определить
процедуру вычисления расстояния между двумя точками, заданными
своими координатами).
2. Дано четное число n>2; проверить для этого числа гипотезу
Гольдбаха. Эта гипотеза заключается в том, что каждое четное n,
21
большее двух, представляется в виде суммы двух простых чисел.
(Определить процедуру, позволяющую распознавать простые числа).
Вариант 5
1. Дано натуральное число n. Выяснить, имеются ли среди
чисел n, n+1,...,2n близнецы, т.е. простые числа, разность между
которыми равна двум. (Определить процедуру, позволяющую
распознавать простые числа).
2. Даны натуральное число n, целые числа a1,...,an. Рассмотреть
отрезки последовательности a1,…,an (последовательности идущих
подряд членов), состоящие из совершенных чисел.
Вариант 6
1. Даны отрезки a, b, c и d. Для каждой тройки этих отрезков,
из которых можно построить треугольник напечатать площадь
данного треугольника. Определить процедуру, печатающую
площадь треугольника со сторонами x, y и z , если такой треугольник
существует.
2. Два простых числа называются «близнецами», если они
отличаются друг от друга на 2 (таковы, например, числа 41 и 43).
Напечатать все пары близнецов из отрезка [n,2n], где n – заданное
целое число, большее 2.
Вариант 7
1. Даны три натуральных числа. Определить их наибольший
общий делитель.
2. Даны координаты вершин треугольника и координаты
некоторой точки внутри него. Найти расстояние от данной точки до
ближайшей стороны треугольника. (При определении расстояний
учесть, что площадь треугольника вычисляется и через три его
стороны, и через основание и высоту).
Вариант 8
1. Даны две квадратные вещественные матрицы 10-го порядка.
Напечатать квадрат той из них, в которой наименьший след (сумма
диагональных элементов), считая, что такая матрица одна.
2. Даны координаты вершин двух треугольников. Определить,
какой из них имеет большую площадь.
Вариант 9
1. Даны три слова, в каждом из которых от 1 до 6 строчных
латинских букв и за каждым из которых следует пробел. Напечатать
эти слова в алфавитном порядке.
22
2. Два натуральных числа называются “дружественными”,
если каждое из них равно сумме всех делителей другого, за
исключением его самого (таковы, например, числа 220 и 284).
Напечатать все пары «дружественных» чисел, не превосходящих
заданного натурального числа.
Вариант 10
1. Даны три вещественные матрицы 4-го порядка. Напечатать
ту из них, норма которой наименьшая (считать, что такая матрица
одна). В качестве нормы матрицы взять максимум абсолютных
величин ее элементов.
2. Найти наименьшее общее кратное четырех заданных
натуральных чисел.
СПИСОК ЛИТЕРАТУРЫ
1. Меженный О.А. Turbo Pascal: учитесь программировать. –
М.: Издательский дом «Вильямс». 2001.- 448 с.: ил.
2. Милов А.В. Основы программирования в задачах и
примерах.- Харьков: Фолио. 2002.- 397 с.: ил.
3. Климова Л.М. Pascal 7.0: практическое программирование.
Решение типовых задач.- М.: Кудиц-Образ, 2000.- 425 с.: ил.
Download