Параметры. Глобальные и локальные описания
При введении в программу подпрограммы возникает разделение данных и их типов на глобальные и локальные. Глобальными по отношению к данному блоку являются объекты верхнего уровня, описанные до появления данного блока. Локальные объекты – объекты, существующие внутри данного блока. Объявлены либо в списке параметров (только переменные), либо в разделах CONST, VAR, TYPE, внутри подпрограммы. Для программистов, использующих обращение к блоку, блок представляется как «черный ящик», в котором реализуется тот или иной алгоритм. В примере, рассмотренном нами, из основной программы можно обратиться к процедурам А, В, С, но нельзя вызвать А1, А2, В1, В2. Образно говоря, блок как бы окружен полупрозрачными стенками, снаружи не видно, что делается внутри, но попав в блок можно увидеть, что делается вне его, но только «сверху», а не «снизу». Так, из блока В21 можно обратиться к В2 , В1, В, а, к основной программе. При совпадении глобальных и локальных имен сильнее оказывается локальное имя, и именно оно используется внутри подпрограммы. Существует неписанное правило: если блок содержит цикл FOR, то параметры должны быть описаны как локальные переменные. Это предотвратит неразбериху при циклическом вызове процедур. Процедуры Процедура состоит из заголовка и тела. Заголовок: PROCEDURE (ИМЯ) [(список формальных параметров)] (имя – имя процедуры (правильный идентификатор) (список формальных параметров) - список формальных параметров (может отсутствовать) Затем идут те же разделы, что и в основной программе. Завершается «;». Пример. Процедура ввода N целых чисел. Пусть в основной программе определен TYPE и VAR TYPE arr:=array[1…10]of integer; VAR m:arr; k:integer; Процедура может иметь вид: {заголовок} PROCEDURE INPINT (var mas :arr; n: integer); Var i:integer; (локальный параметр процедуры) Begin Writeln (‘Введите’, n:3,‘целых чисел’); For i:=1 to n do read (mas[i]) End; Синтаксис вызова процедур прост: выполнение активизируется указанием ее имени и списком var или значений, подставляемых на место формальных параметров (фактические параметры): <имя процедуры> (параметр 1, параметр 2,…….); K:=40; Inpint (m,k); или inpint (m,40); Вызывается процедура input для ввода 40 целых чисел в массив М. Параметры, описываемые в заголовке подпрограммы, являются по сути локальными переменными. Но, кроме того, они обеспечивают обмен значениями между вызывающими и вызываемыми программами. Описываемые в заголовке параметры называются формальными, а те которые подставляются на их место при вызове – фактическими, т.к. замещают все вхождения в подпрограмму своих формальных «двойников». Между формальными и фактическими параметрами должно быть полное соответствие: - одинаковое количество; - один и тот же порядок следования; - тип фактических параметров должен совпадать с типом формальных параметров. Пример. Программа подсчитывает количество точек (.) в первой вводимой с терминала строке, а во второй строке – количество букв «А». Program A; Const Point=‘.’; Var S:=integer; Procedure P (simb:char; var kol:integer); Var C:char; begin Kol:=0; Writeln (‘Введите строку’); Repeat Read (c); If c=simb then inc(kol); Until eoln end; Begin P(point,s); Writeln (‘Количество точек=’,s:3); P(‘A’,s); Writeln (‘Количество букв «А»=’,s:3); end. Процедура имеет два формальных параметра: · simb - входной параметр (параметр-значение), определяет символ, который подсчитывается в строке; · kol – выходной параметр (параметр-переменная), через который передается в программу количество подсчитанных символов. Таким образом мы столкнулись с двумя видами параметров: · параметр-переменная; · параметр-значение. Параметры-значения – локальные переменные подпрограммы, стартовые значения которых задаются при вызове подпрограммы из внешних блоков. Параметры значения могут изменять свои значения, как и другие переменные, но эти изменения никак не передаются в вызывающую программу. Для того, чтобы подпрограмма изменяла значение переданной переменной, нужно объявлять соответствующие параметры, как параметры-переменные, вставляя слово var перед описанием в заголовке. Рассмотрим внутренний механизм передачи параметров в подпрограмму. При вызове процедуры или функции каждой локальной переменной, описанной внутри подпрограммы, и каждому параметру значения отводится место для хранения данных в специальной области памяти, именуемой стеком. Эти места принадлежат переменным ровно столько времени, сколько выполняется подпрограмма. Ячейки для переменных-значений заполняются сразу содержимым. По-другому организуются параметры-переменные. Вместо копий значения подпрограмма получает разрешение работать с тем местом, где постоянно (т.е. во время работы самого вызывающего блока ) хранится значение переменной, указанной в вызове. Все действия с параметром-переменной в подпрограмме на самом деле являются действиями над поставленной в вызове переменной. В этом заключается причина того, что на место параметров-значений можно подставлять непосредственно значения, а на местах параметров переменных могут быть только идентификаторы переменных. Процедура Р может передавать результат своей работы через глобальную переменную S: Procedure P(simb:char); If c=simb then s:=s+1; S:=0; P(point); ………………………………. S:=0; P(‘A’);
Однако, в сложных программных комплексах не рекомендуется использование глобальных переменных. Функции Описание функции в основном аналогично описанию процедуры. Однако, имеются два отличия. Первое - результатом работы функции является одно скалярное значение или одно значение ссылочного типа. Тип результата задается в заголовке функции. Второе отличие заключается в том, что теле функции хотя бы раз имени функции должно быть присвоено значение. Общий вид: Function <имя> [(список фактических параметров)] :<тип>; < тип> тип возвращаемого функцией результата. Пример. Функция принимает любое число и возвращает его квадрат. Если значение квалрата больше 100, то оно считается равным 100. При этом устанавливается глобальный «флаг». Var glflag:boolen: {глобальный флаг} Function getsqr (x:real):real; Const sqrmax=100; {локальная const} begin X:=x*x; {вычисление квадрата} Glflag := (x>sqrmax); {результат сравнения в глобальный флаг] If glflag then x:= sqrmax {ограничение x} Getsqr :=x {возвращает значение} end; Begin {основной вызывающий блок} Writeln (getsqr (6):7:2, ‘флаг:’, glflag) End. При объявлении формальных параметров в <списке формальных параметров>, тип любого параметра может быть только стандартным или ранее объявленным, потому, что нельзя объявить: Procedure S(a:array[1…10] of real); Проблема решается так: Type Atype = array [1..10] of real Procedure S (a:atype) В блок передается весь массив. Процедура EXIT GOTO нельзя использовать для досрочного выхода из подпрограммы. В Т-П для этой цели используется процедура EXIT. Пример. Функция, определяющее первое отрицательное число в массиве. Type Arr_=array [1..100] of real; Var Ar:arr_ Function minus (var mas:arr_; N:integer):real; Var I:integer; Begin Minus :=0; For i:=1 to n do If mas[i]<0 then Begin Minus:=mas[i]; Exit End; End; Begin Writeln (‘Первое отрицательное число в массиве=’, minus(ar,50):7:2); End. Рекурсия Использование рекурсии – преимущество Т-П. Под рекурсией понимается вызов функции (процедуры) из тела самой функции (процедуры) Эта возможность связана с тем, что при каждом новом обращении параметры, которые она использует, заносятся в стек, причем параметры предыдущего обращения сохраняются. В ряде случаев рекурсивное оформление более компактно и эффективно. Пример. Вариант функции вычисляющей факториал числа N. Function fact (n:integer):longint; Begin If n in[0..1] then fact:=1 else fact :=n*fact (n-1) End; Если в функцию передается n>0, то происходит следующее: · запоминаются известные значения членов выражения; · для вычисления неизвестных вызываются те же функции, но с «предшествующими» аргументами. Так происходит до тех пор, пока выражение не станет полностью определенным (ветвь then). После чего алгоритм начинает «раскручиваться» в другую сторону, изымая из памяти «отложенные значения. При этом на каждом очередном шаге все члены выражения будут известны через n обратных шагов, получили результат. Рекурсия заставляет программы расходовать больше памяти, но сами программы более изящны. Директивы подпрограмм Директивы дают дополнительную информацию, в частности, о размещении подпрограмм. Директива FORWARD Если одна подпрограмма использует другую, а та в свою очередь первую, то возникает проблема размещения таких подпрограмм в программе. Текст программы транслируется последовательно сверху вниз. При этом const, type, var должны быть определены до того, как начнутся их упоминания в операторах. В противном случае компилятор объявит их неизвестными. Проблема решается следующим образом: Procedure <имя процедуры> (параметры); forward; Function <имя функции> (параметры) : тип значения; forward; Procedure <имя процедуры> ; {только имя} {Тело процедуры} Function <имя функции>; {только имя} {Тело функции} Открытые массивы В Т-П имеется возможность передавать в подпрограмму массивы, размер которых не фиксируется в объявлении подпрограммы. Function sum1 (var a:array of byte):byte; Это единственное исключение из правила, согласно которому типы формальных параметров в заголовке подпрограммы могут задаваться только посредством идентификаторов. Подпрограмма, содержащая открытый массив в списке своих формальных параметров, может быть вызвана с массивом любого размера (типы фактических параметров должны совпадать).
Популярное: Почему люди поддаются рекламе?: Только не надо искать ответы в качестве или количестве рекламы... Генезис конфликтологии как науки в древней Греции: Для уяснения предыстории конфликтологии существенное значение имеет обращение к античной... Почему человек чувствует себя несчастным?: Для начала определим, что такое несчастье. Несчастьем мы будем считать психологическое состояние... Как построить свою речь (словесное оформление):
При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (2178)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |