рефераты конспекты курсовые дипломные лекции шпоры

Реферат Курсовая Конспект

Процедуры и функции. Сфера действия описаний

Процедуры и функции. Сфера действия описаний - раздел Транспорт, От автора В Языке Паскаль (Как Вы Уже Поняли Из Предыдущего Материала) Существуют Понят...

В языке Паскаль (как вы уже поняли из предыдущего материала) существуют понятия процедуры и функции. Процедуры и функции можно определить как замкнутые программные единицы, реализующие некоторый алгоритм. Фактически процедура или функция - это почти программа, почти - потому что она не может выполняться самостоятельно, а всегда вызывается какой-то другой процедурой или функцией. Программы, которые мы до сих пор писали, тоже были процедурами, правда, несколько особенными - главными процедурами. Программа может содержать любое количество процедур и функций, но она всегда содержит одну и только одну главную процедуру, с которой начинается выполнение программы.

Структура процедуры или функции очень похожа на структуру главной процедуры, она также содержит раздел описаний и раздел операторов; раздел операторов начинается с Begin и заканчивается End; (но не End., как у главной процедуры). Единственным новым оператором для вас будет оператор заголовка, с которого начинается всякая процедура и функция. Все процедуры и функции записываются в разделе описаний какой-либо другой процедуры или функции, в т.ч. и главной процедуры. Оператор заголовка процедуры имеет вид:

Procedure имя ( список параметров ) ;

Здесь имя - имя процедуры (любой идентификатор), список параметров может отсутствовать, но, если он есть, записывается в круглых скобках и имеет вид :

[Var] имя, ... имя : тип ; ... ; [Var] имя , ... имя : тип

Здесь имя - имя параметра, каждый параметр может использоваться внутри процедуры как обычная переменная соответствующего типа, тип - имя типа, но не описание пользовательского типа. Так, скажем, описание параметра в виде x:1..5 неверно, но, если выше описан соответствующий тип Type MyType=1..5, то параметр можно описать в видеx:MyType. Ключевое слово Var перед описанием параметров означает в данном случае, что все параметры до “;” или до “)” - параметры-переменные, если же Var отсутствует, то параметры являются параметрами-значениями. Смысл этих понятий мы рассмотрим несколько позже.

Процедуры вызываются в других процедурах и функциях с помощью уже известного вам оператора вызова:

имя (список аргументов );

Список аргументов задается в том и только в том случае, когда в заголовке процедуры задан список параметров. Аргументы в списке разделяются запятыми и могут быть любыми выражениями, если соответствующий параметр есть параметр- значение, или только именами переменных, если соответствующий параметр есть параметр-переменная. Количество аргументов всегда должно совпадать с количеством параметров, и тип аргумента должен быть таким же, как тип параметра. При вызове процедуры значение соответствующих аргументов передается параметрам, и, таким образом, процедура получает информацию из вызывающей процедуры или функции. Запишем программу, использующую процедуру, которая будет аккуратно выводить значение переменной:

 

Procedure OutVar(x:Real; Name:Char);

Begin

WriteLn('Переменная ',Name,' равна ',x);

End;

 

Var a,b,c,d : Real;

Begin

Write('Введите переменные a,b,c,d '); Read(a,b,c,d);

OutVar(a,'a'); OutVar(b,'b'); OutVar(c,'c'); OutVar(d,'d');

End.

 

Наша процедура OutVar получает из главной процедуры вещественное число x и символ Name, но ничего не передает обратно. Теперь попробуем написать процедуру, которая в заданном целом числе находит наименьшую и наибольшую десятичные цифры:

 

Procedure Min_Max(x:LongInt; Min,Max:Byte);

Begin

x:=Abs(x);

Min:=10;

Max:=0;

While x>0 Do Begin

If Min>x Mod 10 Then Min:=x Mod 10;

If Max<x Mod 10 Then Max:=x Mod 10;

x:=x Div 10;

End;

End;

 

Var

n :LongInt;

mi,ma :Byte;

Begin

n:=-2713;

Min_Max(-2713,mi,ma);

WriteLn(‘Наименьшая цифра числа ‘,n,’ ‘,mi,’,а наибольшая ‘,ma);

End.

 

Запустим эту программу и вместо правильного результата 1 и 7 получим в лучшем случае нули! Дело в том, что через параметры-значения (а Min и Max описаны в нашей процедуре как параметры-значения) невозможно передать информацию из процедуры, но лишь в процедуру. Чтобы правильно решить нашу задачу, следует Min и Maxописать в заголовке как параметры-переменные: Procedure Min_Max(x:LongInt; Var Min, Max :Byte);. Таким образом, входные параметры процедуры могут быть и параметрами-значениями, и параметрами-переменными, а выходные параметры - только параметрами-переменными. Однако описать и параметр x как параметр-переменную в этой процедуре было бы ошибкой, тогда после ее выполнения значение аргумента будет равно нулю. Для того чтобы глубже понять это правило, выясним, что же происходит с параметрами и аргументами при вызове процедуры. В момент вызова для каждого параметра-значения в специальной области памяти, называемой стеком, создается его копия - переменная соответствующего типа, которой присваивается значение аргумента. В дальнейшем процедура работает с этой копией, и при выходе из процедуры копия уничтожается. Таким образом, никакие изменения параметра-значения не могут быть известны за пределами процедуры. По-другому обрабатываются параметры-переменные: в процедуру передается не значение аргумента, а его адрес, и она работает с аргументом (теперь понятно, почему аргумент, соответствующий параметру-переменной, должен быть только именем переменной: он должен иметь адрес). Так что все изменения параметра на самом деле происходят с аргументом и известны в вызывающей процедуре.

Функция, в отличие от процедуры, всегда вычисляет некоторое значение скалярного типа, которое внутри функции должно быть присвоено имени функции. Заголовок функции имеет вид:

Functionимя( список параметров ) : тип ;

В остальном функции аналогичны процедурам. Обращение к функции осуществляется с помощью указателя функции:

имя ( список параметров )

Указатель функции может использоваться, как и любое другое выражение того же типа, но это не оператор - в отличие от оператора вызова. Запишем пример функции:

 

Function Sum_of_Digits(x:LongInt):Byte;

{ функция вычисляет сумму десятичных цифр числа x }

Var s : Byte;

Begin

s:=0;

x:=Abs(x);

While x>0 Do Begin

Inc(s,x Mod 10);

x:=x Mod 10;

End;

Sum_of_Digits:=s;

End;

 

Var L:LongInt;

Begin

Write('Введите целое число ');

Read(L);

Write('Сумма цифр числа ',L,’ равна ‘,Sum_of_Digits(L));

End.

 

В любой процедуре и функции можно использовать черезвычайно полезную стандартную процедуру Exit без параметров для немедленного выхода в вызывающую процедуру.

Все процедуры и функции Паскаля являются рекурсивными, то есть могут вызывать сами себя, никаких усилий со стороны программиста для этого не требуется. В качестве примера запишем функцию, вычисляющую n!

 

Function Factorial(n:Byte):Real;

Begin

If n<=1 Then Factorial:=1

Else Factorial:=n*Factorial(n-1);

End;

 

Но это, конечно, очень плохая функция, гораздо лучше записать этот алгоритм так:

 

Function Factorial(n:Byte):Real;

Var i:Byte;

f:Real;

Begin

f:=1;

For i:=2 To n Do f:=f*i;

Factorial:=f;

End;

 

Итак, мы знаем, что программа может содержать много подпрограмм (процедур и функций), и в каждой из них могут быть описаны типы, константы и переменные. Но не все из них могут быть использованы в любом месте программы, каждое описание имеет строго определенную сферу действия. Пусть подпрограмма А находится внутри подпрограммы В - условимся называть подпрограмму А внутренней по отношению к В, а подпрограмму В - объемлющей по отношению к А. Если же ни подпрограмма А не находится внутри В, ни Вне находится внутри А, то эти подпрограммы - внешние по отношению друг к другу. Сфера действия описания любого объекта включает ту подпрограмму, где он описан (начиная с места описания), и все внутренние подпрограммы, если там данный идентификатор не описан. В принципе, это дает возможность передавать информацию в процедуры и функции, минуя параметры, то есть пользоваться во внутренней подпрограмме переменными, описанными в объемлющей процедуре, но такой стиль программирования считается ненадежным. Старайтесь, если это возможно, все переменные, используемые в подпрограмме, описывать в этой подпрограмме.

Все параметры-значения, а также все объекты, описанные внутри процедуры или функции, размещаются в специальной области памяти, которая называется стек. Размер стека регулируется опцией компилятора {$M}, но не может превышать 65520 байт. Память в стеке отводится в момент вызова подпрограммы и освобождается при ее завершении; если одновременно активны несколько подпрограмм, то стек используется для каждой из них. В случае, когда размера стека не хватает, происходит аварийное завершение программы с ошибкой Stack overflow error, в этом случае следует либо увеличить размер стека (по умолчанию он занимает 16К байт), либо постараться минимизировать объем памяти, необходимый подпрограммам, в частности, не следует описывать в подпрограммах большие массивы и передавать большие массивы как параметры-значения. Особенно серьезные проблемы со стеком возникают при вызове внешних подпрограмм и программировании рекурсивных алгоритмов.

Для чего нужны процедуры и функции, когда и как их следует применять? Многие начинающие программисты избегают подпрограмм, утверждая, что “без них проще”. На самом деле обойтись без функций и процедур легко только в самых тривиальных программах. Сколько-нибудь сложная программа, записанная “одним куском”, требует при отладке от программиста огромных усилий, которые зачастую все равно пропадают даром. Обязательно используйте в своих программах процедуры и функции. Хорошая программа должна содержать, главным образом, обращения к процедурам и функциям. Конечно, не существует никаких жестких правил, определяющих, когда использовать функции, а когда нет, но автор этой книжки может предложить несколько нестрогих, но полезных рецептов:

- выделяйте в подпрограмму небольшой логически завершенный фрагмент алгоритма;

- не смешивайте в одной подпрограмме ввод-вывод данных и вычислительные алгоритмы;

- называйте свои подпрограммы осмысленными именами;

- если алгоритм, который вы решили выделить в подпрограмму, все еще слишком сложен, оформите фрагмент этого алгоритма в другой подпрограмме;

- если алгоритм должен вычислить одно скалярное значение, пусть это будет функция, а не процедура;

- если в вашей программе встречаются многократно вложенные циклы или “многоэтажные” условные операторы - это верный признак, что вам нужны подпрограммы;

- если текст вашей программы не умещается на одном экране - подумайте о подпрограммах;

- используйте в подпрограммах Exit;

- располагайте параметры в списке параметров подпрограммы в последовательности “входные - модифицируемые - выходные”;

- давайте параметрам как можно более осмысленные имена, в случае необходимости включайте в списки параметров поясняющие комментарии;

- никогда не используйте параметры как рабочие переменные внутри подпрограммы, назначение параметров - передавать информацию в подпрограмму и из подпрограммы;

- старайтесь делать свои подпрограммы как можно более универсальными, даже если в данный момент это не нужно, хорошо написанная подпрограмма пригодится вам в других программах;

- старайтесь, чтобы размеры ваших подпрограмм не превышали 100-200 строк.

 

– Конец работы –

Эта тема принадлежит разделу:

От автора

B r... Теперь мы можем присвоить переменным их значения...

Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Процедуры и функции. Сфера действия описаний

Что будем делать с полученным материалом:

Если этот материал оказался полезным ля Вас, Вы можете сохранить его на свою страничку в социальных сетях:

Все темы данного раздела:

От автора
Первое издание этой книги вышло в свет в 1997 году и довольно быстро стало библиографической редкостью. Автор несколько неожиданно для себя обнаружил, что книга пользуется черезвычайно высоким спро

Round(x) - округленное до целого вещественное число, преобразованное к типуLongInt
6. Sqr(x) - квадрат числа 7. Sqrt(x) - квадратный корень 8. Exp(x) - экспонента 9. Ln

Символьный тип данных
Для хранения символьной информации в Паскале предусмотрен специальный тип данных Char. Допустимы переменные, нетипизированные и типизированные константы такого типа. Данные типа

Caseвыражение Of
список значений : оператор/блок .................................. список значений: оператор/блок

Открытые массивы и нетипизированные параметры
Из предыдущего раздела мы узнали, что параметры подпрограмм описываются как [Var] имя : имя типа , это правда, но не вся правда - существует еще два

Множества
Понятие множества в Паскале очень близко к математическому определению: множество - это совокупность однотипных неиндексированных объектов. Множества

Графические средства языка Паскаль
Монитор персонального компьютера может работать в двух режимах - текстовом и графическом. Все, что мы делали до сих пор, мы делали в текстовом режиме. Текстовый экран содержит 2000 знако

Особенности вещественных вычислений
В отличие от целочисленных выражений, которые всегда вычисляются точно, вещественные выражения дают приближенный результат и вещественные переменные содержат приближенные значения. Это обстоятельст

Case тип Of
константа 1 : (описание поля); константа 2 : (описание поля); .....................

Модуль Crt
Crt - еще один стандартный модуль Паскаля, в котором содержатся разнообразные средства консольного ввода-вывода (то есть ввода с клавиатуры и вывода на текстовый экран). Процедуры

Var TextAttr : Byte
В ней содержится текущий цвет фона и цвет символов, используемые при выводе на экран процедурами Write иWriteLn. Изменив эту переменную, вы задаете новый

Другие средства обработки файлов и модуль DOS
Для того чтобы определить, есть ли на диске файл с заданным именем, удобно использовать уже известную нам стандартную функцию IOResult , которая возвращает ноль при успешном завершении последней оп

Type SearchRec=Record
Fill : Array[1..21] of Byte; Attr : Byte; Time : LongInt; Size : LongInt; Name : Stri

Процедурные типы
Язык Паскаль позволяет использовать в программе данные типа “процедура” или типа “функция”. Такие данные можно передавать как аргументы подпрограмм, можно описывать и использовать массивы процедур

Указатели и динамическая память
Указателями называются переменные и константы, значениями которых являются адреса. Различаются два вида указателей - обобщенные указатели и

Динамические структуры: списки, деревья
Примеры программ, использующих динамические массивы, приведенные в предыдущей главе, все еще были плохими. Для того чтобы использовать динамические массивы таким образом, мы должны заранее знать ра

Открытые строки
  Открытыми строками, или длинными строками, или C-строками, называются символьные последовательности длиной до 65535 символов, ограниченные справа нуль-символ

Использование командной строки и вызов внешних программ
Паскаль позволяет передавать информацию в программу при ее запуске через командную строку. Для этого служат две стандартные функции -ParamCount и ParamStr.

Обработка программных прерываний
Программное прерывание - это ситуация, возникающая, когда дальнейшее выполнение программы невозможно. Например, деление на ноль, переполнение, ошибка Range check error, обращение по неверному адрес

Объекты
Объектом в языке Паскаль называется совокупность данных и подпрограмм, обрабатывающих эти данные. Программирование с использованием объектов называется объектно-о

Type имя типа=Object
описание полей описание методов End; Поля объектов описываются так же, как поля записей, а описание метода - это заголовок процедуры или функции. Сами методы распол

Рекурсия и динамическое программирование
В этом и всех последующих разделах речь пойдет уже не о языке программирования Паскаль, а о задачах, которые вы можете решать с помощью этого языка, о наиболее интересных и полезных алгоритмах и пр

Рекурсия и стек отложенных заданий
Рекурсивные алгоритмы далеко не всегда неэффективны, как можно подумать, прочитав предыдущий раздел. Во многих задачах рекурсивные процедуры и функции очень полезны, кроме того, они исключительно п

Стеки и очереди
Значение стека как структуры данных в программировании не исчерпывается лишь стеком отложенных заданий. В этом разделе мы решим с помощью стека задачу о вычислении значения арифметического выражени

Комбинаторные алгоритмы
В этом разделе мы рассмотрим три наиболее важные задачи комбинаторики: нахождение всех подмножеств множества из n элементов; нахождение всех выборок по m элементов из n элементов и нахождение всех

Бинарные деревья
В этом разделе мы рассмотрим различные алгоритмы обхода бинарного дерева. К алгоритмам создания бинарного дерева мы обратимся несколько позже, а пока будем считать, что дере

Упорядоченные бинарные деревья и приоритетные очереди
Упорядоченным бинарным деревом, или бинарным деревом поиска, называют дерево, в любой части которого элементы левого поддерева меньше корневого элеме

Алгоритмы сортировки
В этом разделе мы рассмотрим различные алгоритмы решения задачи сортировки. Задача сортировки ставится следующим образом: дана последовательность записей R1,R

Хотите получать на электронную почту самые свежие новости?
Education Insider Sample
Подпишитесь на Нашу рассылку
Наша политика приватности обеспечивает 100% безопасность и анонимность Ваших E-Mail
Реклама
Соответствующий теме материал
  • Похожее
  • Популярное
  • Облако тегов
  • Здесь
  • Временно
  • Пусто
Теги