Синтаксис описания и вызова процедуры
С другой стороны, описание всех формальных параметров как параметров-переменных нежелательно по двум причинам. Во-первых, это исключает возможность вызова подпрограммы с фактическими параметрами в виде выражений, что делает программу менее компактной. Во-вторых, и главных, в подпрограмме возможно случайное использование формального параметра, например, для временного хранения промежуточного… Читать ещё >
Синтаксис описания и вызова процедуры (реферат, курсовая, диплом, контрольная)
Синтаксис описания и вызова процедуры
Курсовая работа Выполнил Дзотцоев Лев Казгериевич Северо-Кавказский Горно-Металлургический Институт (СКГТУ) Кафедра промышленной электроники Факультет электронной техники, ПЭ-04−1.
Владикавказ 2004 год.
Задание
Приведите синтаксис описания и вызова процедуры. Опишите виды, назначение формальных и фактических параметров. Приведите пример описания процедуры, её вызова и поясните его.
Даны целые m и n. Составить программу вычисления
x = (m! +n!)/(m+n)!, где k=1x2x3x4x.xK.
В программе предусмотреть:
Ввод m и n.
Описание процедуры-функции для вычисления значения факториала: f (k) = k! = 1x2x3x.xK.
Отображение на экране дисплея значения Х Комментарии в основных местах программы.
2.1 Отладить и провести счет по программе.
2.2 Привести в пояснительной записке:
Текст программы с пояснениями Исходные данные и результаты счета.
Синтаксис описания и вызова процедуры.
Программа объемом до 10 000 операторов считается малой, до 100 000 операторов — средней. Понятно, что строить такие программы непосредственно из элементарных операции практически невозможно. Для упрощения разработки программ в Pascal-е можно использовать подпрограммы — процедуры и функции. Они представляют собой инструмент, с помощью которого любая программа может быть разбита на ряд в известной степени независимых друг от друга частей. Такое разбиение необходимо по двум причинам.
Во-первых, это средство экономии памяти: каждая подпрограмма существует в программе в единственном экземпляре, в то время как обращаться к ней можно многократно из разных точек программы. При вызове подпрограммы активизируется последовательность образующих ее операторов, а с помощью передаваемых подпрограмме параметров нужным образом модифицируется реализуемый в ней алгоритм.
Вторая причина заключается в применении современных методов нисходящего проектирования программ. В результате применение этих методов алгоритм представляется в виде последовательности относительно крупных подпрограмм, реализующих более или менее самостоятельные смысловые части алгоритма. Подпрограммы в свою очередь могут разбиваться на менее крупные подпрограммы, те — на подпрограммы нижнего уровня и т. д. Последовательное структурирование программы продолжается до тех пор, пока реализуемые подпрограммами алгоритмы не станут настолько простыми, чтобы их можно было легко запрограммировать.
Pascal даже в сравнении с промышленными системами программирования обладает очень мощными средствами работы с подпрограммами.
Процедуры и функции, как уже отмечалось, представляют собой относительно самостоятельные фрагменты программы, оформленные особым образом и снабженные именем. Упоминание этого имени в тексте программы называется вызовом процедуры (функции). Отличие функции от процедуры заключается в том, что результатом исполнения операторов, образующих тело функции, всегда является некоторое единственное значение простого, строкового типа или указателя, поэтому обращение к функции можно использовать в соответствующих выражениях наряду с переменными и константами.
В структуре Pascal программ существует специальный раздел для описания процедур и функций. Как известно, любое имя в программе должно быть обязательно описано перед тем, как оно появится среди исполняемых операторов. Не делается исключения и в отношении процедур: каждую необходимо описать в разделе описаний.
Описать подпрограмму — это значит указать ее заголовок и тело. В заголовке объявляются имя процедуры и формальные параметры, если они есть. За заголовком следует тело подпрограммы, которое состоит из раздела описаний и раздела исполняемых операторов. В разделе описаний процедур могут встретиться описания процедур низшего уровня, в тех — описания других подпрограмм и т. д.
Синтаксис и вызов (в общем) процедур:
Procedure.
Uses.
Label.
Const.
Type.
Var.
Begin.
End;
Для выполнения процедуры необходим её вызов. Вызов осуществляется по имени данной процедуры в теле программы. Имя процедуры воспринимается как оператор. При его выполнении выполняется вся подпрограмма.
Описание подпрограммы состоит из заголовка и тела подпрограммы.
Заголовок Заголовок процедуры имеет вид:
PROCEDURE ();
Здесь — имя подпрограммы — список формальных параметров;
{Сразу за заголовком подпрограммы может следовать одна из стандартных директив ASSEMBLER, EXTERNAL, FAR, FORWARD, INLINE, INTERRUPT, NEAR}.
Параметры Параметры бывают формальные и фактические. Параметры, которые записываются в скобках после имени процедуры, называются формальными параметрами. Они указывают на то, что для выполнения данной процедуры необходимы дополнительные данные — фактические параметры.
Список формальных параметров необязателен и может отсутствовать. {Использование процедур без параметров оправданно только в том случае, если в них не используется обращение к глобальным переменным. Использование таких процедур ограниченно той программой, для которой они написаны и затруднено для других программ}.
Если же он есть, то в нем должны быть перечислены имена формальных параметров и их тип, например:
Procedure YZ (a: real; b: integer: с: char).
Как видно из примера, параметры в списке отделяются друг от друга точками с запятой. Несколько следующих подряд однотипных параметров можно объединять в подсписки, например, вместо.
Procedure Z (а: integer; b: integer).
можно написать проще:
Procedure Z (a, b: integer)
Операторы тела подпрограммы рассматривают список формальных параметров как своеобразное расширение раздела описаний: все переменные из этого списка могут использоваться в любых выражениях внутри подпрограммы. Таким способом осуществляется настройка алгоритма подпрограммы на конкретную задачу.
Первый формальный параметр заменяется первым фактическим, второй-вторым и т. д.
Механизм замены формальных параметров на фактические позволяет нужным образом настроить алгоритм, реализованный в подпрограмме. Турбо Паскаль следит за тем, чтобы количество и тип формальны параметров строго соответствовали количеству и типам фактических параметров в момент обращения к подпрограмме. Напомним: смысл используемых фактических параметров зависит от того, в каком порядке они перечислены при вызове подпрограммы. Пользователь должен сам следить за правильным порядком перечисления фактических параметров при обращении к подпрограмме. Приведем пример. рассмотрим интересующую нас часть программы (не самой удачной, но это пока неважно) для вычисления x = (5! + 2!)/(5+2)!
Program factorial (input, output);
…
{далее нас интересует описание процедуры:}.
Procedure FL (L:integer, var z: integer); {объявление процедуры, её имя, список формальных параметров}.
Begin.
Z:=1;
While L>1 do.
Begin.
Z:=ZxL;{тело процедуры, которая также предусматривает, что 0! и 1! =1}.
L:=l-1;
end;
end;
…
begin.
…
{теперь рассмотрим вызов процедуры}.
FL (5,a);
FL (2,b);
FL (2+5,c);
…
end.
В данном случае l, z формальные параметры. К слову, их не надо описывать в разделе глобальных переменных.
Фактические параметры: 5, а, 2, b, 2+5, c. В «основном» разделе VAR должны быть описаны а, b, c.
При первом вызове процедуры фактический параметр 5 заменит формальный L, фактический a заменит формальный z, во втором 2 заменит L, b заменит z.
В третьем соответственно 2+5 заменит L, c заменит z. Для того, чтобы окончательно разобраться в программе, необходимо пояснить, какими бывают виды формальных и фактических параметров, их назначение.
Виды параметров.
По способу передачи данных параметры можно разделить на несколько категорий.
Любой из формальных параметров подпрограммы может быть либо параметром-значением, либо параметром-переменной, либо параметром-константой. Если параметры определяются как параметры-переменные, перед ними необходимо ставить зарезервированное слово VAR, например:
Procedure tide (var a: real) Здесь параметр, А — параметр-переменная. Заголовок процедуры может быть устроен так, что некоторые группы формальных параметров не содержат слова VAR. Например:
Procedure qwerty (a, b, c:real; var s: real);
Формальные параметры, которые входят в группы, не содержащие слова VAR, называются формальными параметрами-значениями.
Определение формального параметра тем или иным способом существенно только для вызывающей программы: если формальный параметр объявлен как параметр-переменная, то при вызове подпрограммы ему должен соответствовать фактический параметр в виде переменной определенного типа; если формальный параметр объявлен как параметр-значение, то при вызове ему может соответствовать произвольное выражение. Контроль за неукоснительным соблюдением этого правила осуществляет компилятором Турбо Паскаля.
Для того чтобы понять, в каких случаях использовать параметры значения, а в каких — параметры-переменные, рассмотрим, как осуществляется замена формальных параметров на фактические в момент обращения к подпрограмме.
Если параметр определен как параметр-значение, то перед вызовом подпрограммы это значение вычисляется, полученный результат копируется во временную память и передается подпрограмме. Важно учесть, что даже если в качестве фактического параметра указано простейшее выражение в виде переменной или константы, все равно подпрограмме будет передана лишь копия переменной (константы). Таким образом, назначение параметра-значения — передача данных из программы в подпрограмму. Если же параметр определен как параметр-переменная, то при вызове подпрограммы передается сама переменная, а не ее копия. Любые возможные изменения в подпрограмме параметра-значения никак не воспринимаются вызывающей программой, так как в этом случае изменяется копия фактического параметра, в то время как изменение параметра-переменной приводит к изменению самого фактического параметра в вызывающей программе. Параметр-константа схож с параметром-переменной: в подпрограмму передается сама константа, но изменение её невозможно. Назначение такого параметра совпадает с назначением параметра-значения. Формальные параметры-константы указываются в заголовке программы после служебного слова const. Его действие распространяется до ближайшей точки с запятой.
Поясним изложенное.
…
var.
a, b: integer;
…
procedure squar (a: integer; var b: integer);
begin.
a:=sqr (a);
b:=sqr (b);
writeln (‘в квадрате они выглядят так: ', a,', ', b);
end;
…
begin.
a:=4; b:=6;
writeln (‘внимательно посмотрите на эти числа: ', a,', ', b);
squar (a, b);
writeln (‘а так, а не в квадрате: ', a, ', ', b);
end.
Результаты выглядят так: внимательно посмотрите на эти числа: 4, 6
в квадрате они выглядят так: 16, 36
а так, а не в квадрате: 4, 36.
Этот пример может служить еще и иллюстрацией механизма «закрывания» глобальной переменной, а одноименной локальной: хотя переменная объявлена как глобальная (она описана в вызывающей программе перед описанием процедуры), в теле процедуры ее «закрыла» локальная переменная а, объявленная как параметр-значение.
Итак, параметры-переменные используются как средство связи алгоритма, реализованного в подпрограмме, с «внешним миром»: с помощью этих параметров подпрограмма может передавать результаты своей работы вызывающей программе. Разумеется, в распоряжении программиста всегда есть и другой способ передачи результатов — через глобальные переменные. Однако злоупотребление глобальными связями делает программу, как правило, запутанной, трудной в понимании и сложной в отладке. В соответствии с требованиями хорошего стиля программирования рекомендуется там, где это возможно, использовать передачу результатов через фактические параметры-переменные.
С другой стороны, описание всех формальных параметров как параметров-переменных нежелательно по двум причинам. Во-первых, это исключает возможность вызова подпрограммы с фактическими параметрами в виде выражений, что делает программу менее компактной. Во-вторых, и главных, в подпрограмме возможно случайное использование формального параметра, например, для временного хранения промежуточного результата, т. е. всегда существует опасность непреднамеренно «испортить» фактическую переменную. Вот почему параметры-переменные следует объявлять только те, через которые подпрограмма в действительности передает результаты вызывающей программе. Чем меньше параметров объявлено параметрами-переменными и чем меньше в подпрограмме используется глобальных переменных, тем меньше опасность получения непредусмотренных программистом побочных эффектов, связанных с вызовом подпрограммы, тем проще программа в понимании и отладке.
Существует одно обстоятельство, которое следует учитывать при выборе вида формальных параметров. Как уже говорилось, при объявлении параметра-значения осуществляется копирование фактического параметра во временную память. Если этим параметром будет массив большой размерности, то существенные затраты времени и памяти на копирование при многократных обращениях к подпрограмме могут стать peшающим доводом в пользу объявления такого параметра параметром-переменной или передачи его в качестве глобальной переменной.
Параметры массивы и параметры строки
Может сложиться впечатление, что объявление переменных в списке формальных параметров подпрограммы ничем не отличается от объявления их в разделе описания переменных. Действительно, в обоих случаях много общего, но есть одно существенное различие: типом любого параметра в списке формальных параметров может быть только стандартный или ранее объявленный тип. Поэтому нельзя, например, объявить следующую процедуру:
Procedure S (а: array (1.10] of real);
так как в списке формальных параметров фактически объявляется тип — диапазон, указывающий границы индексов массива.
Если мы хотим передать какой-то элемент массива, то проблем, как правило, не возникает, но если в подпрограмму передается весь массив, то следует первоначально описать его тип. Например:
…
type.
mas = array [1.10] of real;
…
PROCEDURE S (a: mas);
…
Поскольку строка является фактически своеобразным массивом, ее передача в.
подпрограмму осуществляется аналогичным образом:
…
type.
intype =string[15];
outype = string[30];
FUNCTION St (i: intype): outype:
Требование описать любой тип-массив или тип-строку перед объявлением подпрограммы на первый взгляд кажется несущественным. Действительно, в рамках простейших вычислительных задач обычно заранее известна структура всех используемых в программе данных, поэтому статическое описание массивов не вызывает проблем. Однако разработка программных средств универсального назначения связана со значительными трудностями. По существу, речь идет о том, что в Турбо Паскале невозможно использовать в подпрограммах массивы с «плавающими» границами изменения индексов. Например, если разработана программа, обрабатывающая матрицу из 10×10 элементов, то для обработки матрицы из 9×11 элементов необходимо переопределить тип, т. е. перекомпилировать всю программу. Этот недостаток, как и отсутствие в языке средств обработки исключительных ситуаций (прерываний), унаследован из стандартного Паскаля и представляет собой объект постоянной и вполне заслуженной его критики. Разработчики Турбо Паскаля не рискнули кардинально изменить свойства базового языка, но, тем не менее, включили в него некоторые средства, позволяющие в известной степени смягчить отмеченные недостатки.
Прежде всего, в среде Турбо Паскаля можно установить режим компиляции, при котором отключается контроль над совпадением длины фактического и формального параметра-строки. Это позволяет легко решить вопрос о передаче подпрограмме строки произвольной длины. При передаче строки меньшего размера формальный параметр будет иметь ту же длину, что и параметр обращения; передача строки большего размера приведет к ее усечению до максимального размера формального параметра. Следует сказать, что контроль включается только при передаче строки, объявленной как формальный параметр-переменная. Если соответствующий параметр объявлен параметром-значением, эта опция игнорируется и длина не контролируется.
Значительно сложнее обстоит дело с передачей массивов произвольной длины. Решить эту проблему при помощи не типизированных параметров.
Процедурные типы
Процедурные типы — это нововведение фирмы Borland (в стандартном Паскале таких типов нет). Основное назначение этих типов — дать программисту гибкие средства передачи функций и процедур в качестве фактических параметров обращения к другим процедурам и функциям.
Для объявления процедурного типа используется заголовок процедур, в котором опускается ее имя, например:
type.
Proc = Procedure (a, b, с: real; Var d: real);
Proc2 = Procedure (var a, b);
РгосЗ = Procedure;
В программе могут быть объявлены переменные процедурных типов, например, так:
var.
р1: Proc;
ар: array [1.N] of Proc2;
Переменным процедурных типов допускается присваивать в качестве значений имена соответствующих подпрограмм. После такого присваивания имя переменной становится синонимом имени подпрограммы.
В отличие от стандартного Паскаля, в Турбо Паскале разрешается использовать в передаваемой процедуре как параметры-значения, так и параметры-переменные.
Нетипизированные параметры-переменные
Еще одно и очень полезное нововведение фирмы Borland — возможность использования нетипизированных параметров. Параметр считается нетипизированным, если тип формального параметра-переменной в заголовке подпрограммы не указан, при этом соответствующий ему фактический параметр может быть переменной любого типа. Заметим, нетипизированными могут быть только параметры-переменные.
Нетипизированные параметры обычно используются в случае, когда тип данных несущественен. Такие ситуации чаще всего возникают разного рода копированиях одной области памяти в другую. Нетипизированные параметры очень удобно использовать для передачи подпрограмме одномерных массивов переменной длины.
Параметрысложные типы данных
Рассмотрены прежде категории параметров не исчерпывают всех вопросов передачи информации в Pascal-e. Использование в качестве параметров сложных типов данных имеет свои особенности.
Рассмотрим массивы и строки открытого типа. Открытый массив (строка) — массив (строка) без указания типа индекса (размера массива (строки)).
Пример:
Procedure getfive (var massiv: array of real);
В данном случае вместо формального параметра может использоваться любой массив с элементами типа real. Индексация элементов открытого массива всегда начинается с нуля. Такие массивы введены для того, чтобы подпрограмма могла обрабатывать массивы любого размера.
Программа вычисления x=(m!+n!)/(m+n)!, где m, n целые (неотрицательные).
program factorial_(input, output); {название программы}.
label 0; {описываем метку}.
var.
rez:real;
m, n: longint; {описали глобальные переменные, используемые в программе}.
function fact (z: longint): real; {заголовок функции с формальным параметром-значением, типом}.
var.
y: real; {описали локальную переменную}.
begin.
y:=1; {для получения результата необходимо присвоить у значение 1. также при помощи этого реализуется вычисление 0! и 1!}.
while z>1 do {запускаем цикл в обратную сторону, для упрощения опустим множитель 1}.
begin.
y:=y*z;
z:=z-1.
end;
fact:=y{вычисляем факториал, присваиваем его значение функции}.
end; {конец функции}.
begin{начало тела программы}.
writeln («введите неотрицательные числа »); {для удобства пользователя просим ввести числа}.
0:readln (m, n); {в память вводятся числа}.
if m or n 1 do запускаем цикл в обратную сторону, т. к. результат получается один и тот же, но при этом не приходится описывать дополнительную локальную переменную для запуска цикла с параметром. 1 исключаем из вычисления факториала по вышеуказанным причинам.
begin.
y:=y*z;
z:=z-1.
end;
fact:=y этим оператором присваиваем функции значение факториала.
Точку с запятой перед end можно не ставить.
end; конец функции.
begin начало тела программы.
writeln («введите неотрицательные числа »); данный оператор выводит на экран текст, заключенный между ‘', помогает понять, чего же требует программа.
0:readln (m, n); при помощи этого оператора ввода информации исходные данные заносятся в ячейки памяти.
if m or n.