Автор работы: Пользователь скрыл имя, 08 Июля 2014 в 19:22, курсовая работа
Цель: рассмотреть возможности реализации метода структурного программирования средствами языка программирования Паскаль.
Задачи:
• Изучить методы и типизацию структурного программирования;
• Использовать возможности реализации подпрограмм языка программирования Паскаль на примере функций и процедур;
• Рассмотреть технологию обработки информации с помощью различных функций.
ВВЕДЕНИЕ 2
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА 4
ЗАКЛЮЧЕНИЕ 19
ЛИТЕРАТУРА 20
FUNCTION<имя> [(<сп.ф.п.»] : <тип>;
Здесь <имя> - имя подпрограммы (правильный идентификатор);
<сп. ф. п. >- список формальных параметров;
<тип> - тип возвращаемого функцией результата.
Сразу за заголовком подпрограммы может следовать одна из стандартных директивASSEMBLER, EXTERNAL, FAR, FORWARD, INLINE, INTERRUPT, NEAR.
Эти директивы уточняют действия компилятора и распространяются на всю подпрограмму и только на нее, т.е. если за подпрограммой следует другая подпрограмма, стандартная директива, указанная за заголовком первой, не распространяется на вторую.
ASSEMBLER - эта директива отменяет стандартную последовательность машинных инструкций, вырабатываемых при входе в процедуру и перед выходом из нее. Тело подпрограммы в этом случае должно реализоваться с помощью команд встроенного ассемблера.
EXTERNAL - с помощью этой директивы объявляется внешняя подпрограмма.
FAR - компилятор должен создавать код подпрограммы, рассчитанный на дальнюю модель вызова.
ДирективаNEAR заставит компилятор создать код, рассчитанный на ближнюю модель памяти. По умолчанию все подпрограммы, объявленные в интерфейсной части модулей, генерируются с расчетом на дальнюю модель вызова, а все остальные подпрограммы - на ближнюю модель.
В соответствии с архитектурой микропроцессора ПК, в программах могут использоваться две модели памяти: ближняя и дальняя.
Модель памяти определяет возможность вызова процедуры из различных частей программы:
если используется ближняя модель, вызов возможен только в пределах 64 Кбайт (в пределах одного сегмента кода, который выделяется основной программе и каждому используемому в ней модулю);
при дальней модели вызов возможен из любого сегмента.
Ближняя модель экономит один байт и несколько микросекунд на каждом вызове подпрограммы, поэтому стандартный режим компиляции предполагает эту модель памяти.
Однако при передаче процедурных параметров, а также в оверлейных модулях соответствующие подпрограммы должны компилироваться с расчетом на универсальную - дальнюю - модель памяти, одинаково пригодную при любом расположении процедуры и вызывающей ее программы в памяти.
Явное объявление модели памяти стандартными директивами имеет более высокий приоритет по сравнению с опциями настройки среды Паскаля.
FORWARD - используется при опережающем описании для сообщения компилятору, что описание подпрограммы следует где-то дальше по тексту программы (но в пределах текущего программного модуля).
INLINE - указывает на то, что тело подпрограммы реализуется с помощью встроенных машинных инструкций.
INTERRUPT - используется при создании процедур обработки прерываний.
Параметры
Список формальных параметров необязателен и может отсутствовать. Если же он есть, то в нем должны быть перечислены имена формальных параметров и их типы, например:
Procedure SB(a: Real; b: Integer; c: Char) ;
Как видно из примера, параметры в списке отделяются друг от друга точками с запятой. Несколько следующих подряд однотипных параметров можно объединять в подсписки, например, вместо
Function F(a: Real; b: Real): Real;
можно написать проще:
Function F(a,b: Real): Real;
Операторы тела подпрограммы рассматривают список формальных параметров как своеобразное расширение раздела описаний: все переменные из этого списка могут использоваться в любых выражениях внутри подпрограммы.
Таким способом осуществляется настройка алгоритма подпрограммы на конкретную задачу.
Рассмотрим следующий пример. В языке Паскаль нет операции возведения в степень, однако с помощью встроенных функций LN(X) и ЕХР(Х) нетрудно реализовать новую функцию с именем, например, POWER, осуществляющую возведение любого вещественного числа в любую вещественную степень. В программе вводится пара чисел X и Y и выводится на экран дисплея результат возведения Х сначала в степень +Y, а затем - в степень -Y.
Для выхода из программы нужно ввести Ctrl-Z и Enter.
Пример
var
х,у: Real;
{------------------------}
Function Power(a,b ; Real): Real;
begin {Power}
if a > 0 then
Power := exp(b * ln(a))
else if a < 0 then
Power := exp(b * ln(abs(a)))
else if b = 0 then
Power := 1
else
Power := 0
end {Power};
{--------------------------}
begin {main}
repeat
readin(x,y) ;
writein(Power(x,y):12:10, Power(x,-y):15:10)
untilEOF
end {main}.
Для вызова функции POWER мы просто указали ее в качестве параметра при обращении к встроенной процедуре WRITELN.
Параметры xиyв момент обращения к функции - это фактические параметры.
Они подставляются вместо формальных параметров А и В в заголовке функции и затем над ними осуществляются нужные действия.
Полученный результат присваивается идентификатору функции - именно он и будет возвращен как значение функции при выходе из нее.
В программе функция POWER вызывается дважды - сначала с параметрами Х и Y, а затем X и -Y, поэтому будут получены два разных результата.
Механизм замены формальных параметров на фактические позволяет нужным образом настроить алгоритм, реализованный в подпрограмме.
Паскаль следит за тем, чтобы количество и тип формальных параметров строго соответствовали количеству и типам фактических параметров в момент обращения к подпрограмме.
Смысл используемых фактических параметров зависит от того, в каком порядке они перечислены при вызове подпрограммы.
В примере первый по порядку фактический параметр будет возводиться в степень, задаваемую вторым параметром, а не наоборот.
Пользователь должен сам
следить за правильным
Любой из формальных параметров подпрограммы может быть либо параметром-значением, либо параметром-переменной, либо, наконец, параметром-константой.
В предыдущем примере параметры А и В определены как параметры-значения.
Если параметры определяются как параметры-переменные, перед ними необходимо ставить зарезервированное слово VAR, а если это параметры-константы,- словоCONST, например:
Procedure MyProcedure (var a: Real; b: Real; const c: String);
Здесь А - параметр-переменная, В -параметр-значение, а С - параметр-константа.
Определение формального параметра тем или иным способом существенно, в основном, только для вызывающей программы:
если формальный параметр объявлен как параметр-переменная, то при вызове подпрограммы ему должен соответствовать фактический параметр в виде переменной нужного типа;
если формальный параметр
объявлен как параметр-
Контроль за неукоснительным соблюдением этого правила осуществляется компилятором Паскаля.
Если бы для предыдущего примера был использован такой заголовок функции:
Function Power (var a, b : Real) : Real;
то при втором обращении к функции компилятор указал бы на несоответствие типа фактических и формальных параметров (параметр -Y есть выражение, в то время как соответствующий ему формальный параметр описан как параметр-переменная).
Для того чтобы понять, в каких случаях использовать тот или иной тип параметров, рассмотрим, как осуществляется замена формальных параметров на фактические в момент обращения к подпрограмме.
Если параметр определен как параметр-значение, то перед вызовом подпрограммы это значение вычисляется, полученный результат копируется во временную память и передается подпрограмме.
Важно учесть, что даже если в качестве фактического параметра указано простейшее выражение в виде переменной или константы, все равно подпрограмме будет передана лишь копия переменной (константы).
Любые возможные, изменения в подпрограмме параметра-значения никак не воспринимаются вызывающей программой, так как в этом случае изменяется копия фактического параметра.
Если параметр определен как параметр-переменная, то при вызове подпрограммы передается сама переменная, а не ее копия (фактически в этом случае подпрограмме передается адрес переменной).
Изменение параметра-переменной приводит к изменению самого фактического параметра в вызывающей программе.
В случае параметра-константы в подпрограмму также передается адрес области памяти, в которой располагается переменная или вычисленное значение. Однако компилятор блокирует любые присваивания параметру-константе нового значения в теле подпрограммы.
Представленный ниже пример 8.2 поясняет изложенное. В программе задаются два целых числа 5 и 7, эти числа передаются процедуре INC2, в которой они удваиваются.
Один из параметров передается как параметр-переменная, другой - как параметр-значение. Значения параметров до и после вызова процедуры, а также результат их удвоения выводятся на экран.
Пример
const
а : Integer = 5;
b : Integer =7;
{--------------------}
Procedure Inc2 (var c: Integer; b: Integer);
begin {Inc2}
с := с + c;
b := b + b;
WriteLn ('удвоенные :',c:5,b:5)
end{inc2};
{---------------------}
begin{main}
WriteLn ('исходные :', a:5, b:5);
WriteLn('результат :', a:5, b:5)
end{main}.
В результате прогона программы будет выведено:
исходные :57
удвоенные :1014
результат :107
Как видно из примера, удвоение второго формального параметра в процедуре INC2 не вызвало изменения фактической переменной В, так как этот параметр описан в заголовке процедуры как параметр-значение.
Этот пример может служить еще и иллюстрацией механизма «накрывания» глобальной переменной одноименной локальной: хотя переменная В объявлена как глобальная (она описана в вызывающей программе перед описанием процедуры), в теле процедуры ее «закрыла» локальная переменная В, объявленная как параметр-значение.
Итак, параметры-переменные используются как средство связи алгоритма, реализованного в подпрограмме, с внешним миром: с помощью этих параметров подпрограмма может передавать результаты своей работы вызывающей программе.
Разумеется, в распоряжении программиста всегда есть и другой способ передачи результатов - через глобальные переменные.
Однако злоупотребление глобальными связями делает программу , как правило, запутанной, трудной в понимании и сложной в отладке.
В соответствии с требованиями хорошего стиля программирования рекомендуется там, где это возможно, использовать передачу результатов через фактические параметры-переменные.
С другой стороны, описание всех формальных параметров как параметров-переменных нежелательно по двум причинам.
Во-первых, это исключает возможность вызова подпрограммы с фактическими параметрами в виде выражений, что делает программу менее компактной.
Во-вторых, и главных, в подпрограмме возможно случайное использование формального параметра, например, для временного хранения промежуточного результата, т.е. всегда существует опасность непреднамеренно испортить фактическую переменную.
Вот почему параметрами-переменными следует объявлять только те, через которые подпрограмма в действительности передает результаты вызывающей программе.
Чем меньше параметров объявлено параметрами-переменными и чем меньше в подпрограмме используется глобальных переменных, тем меньше опасность получения непредусмотренных программистом побочных эффектов, связанных с вызовом подпрограммы, тем проще программа в понимании и отладке.
По той же причине не рекомендуется использовать параметры-переменные в заголовке функции:
если результатом работы функции не может быть единственное значение, то логичнее использовать процедуру или нужным образом декомпозировать алгоритм на несколько подпрограмм.
Существует еще одно обстоятельство, которое следует учитывать при выборе вида формальных параметров.
Как уже говорилось, при объявлении параметра-значения осуществляется копирование фактического параметра во временную память. Если этим параметром будет массив большой размерности, то существенные затраты времени и памяти на копирование при многократных обращениях к подпрограмме можно минимизировать, объявив этот параметр параметром-константой.
Параметр-константа не копируется во временную область памяти, что сокращает затраты времени на вызов подпрограммы, однако любые его изменения в теле подпрограммы невозможны - заэтим строго следит компилятор.
Процедурные типы. Параметры-функции и параметры-процедуры
Процедурные типы - это нововведение фирмы Borland (в стандартном Паскале таких типов нет).
Основное назначение этих типов - дать программисту гибкие средства передачи функций и процедур в качестве фактических параметров обращения к другим процедурам и функциям.
Для объявления процедурного типа используется заголовок процедуры (функции), в котором опускается ее имя, например:
type
Proc1 = Procedure (a, b, c: Real; var d: Real) ;
Proc2 = Procedure (var a, b);
РгосЗ = Procedure;
Func1 = Function: String;
Func2 = Function (var s: String): Real;
Как видно из приведенных примеров, существует два процедурных типа: тип-процедура и тип-функция.
Пример иллюстрирует механизм передачи процедур в качестве фактических параметров вызова. Программа выводит на экран таблицу двух функций:
sinl(x) = (sin(x) +1) * ехр(-х)
и
cosl (х) = (cos(x) +1) * ехр(-х)
Вычисление и печать значений этих функций реализуются в процедуре PRINTFUNC, которой в качестве параметров передаются номер позиции N на экране, куда будет выводиться очередной результат (с помощью этого параметра реализуется вывод в две колонки), и имя нужной функции.
Пример
Uses CRT;
type
Func = Function (x: Real): Real;
{------------------------}
Procedure PrintFunc(XPos: Byte; F:Func);
Информация о работе Использование функций в структурном программировании