Понятие глобальных и локальных переменных введено в языке Паскаль из-за наличия в нем понятия блочной структуры. Любая программа, процедура и функция представляют собой блок со своей областью описаний и могут содержать внутри этого блока описания других процедур и функций, а также обращения к ним. Программа и совокупность описанных в ней процедур и функций образует блочную структуру. Блок, содержащий в своем разделе описаний другой блок (процедуру и функцию), называется внешним по отношению к нему. Блок, содержащийся в разделе описаний некоторого блока, называется внутренним или подблоком. Объекты, описанные внутри какого-либо подблока, являются по отношению к нему локальными и недоступны внешним блокам, т.е. на них можно ссылаться только внутри блока, в котором они описаны. В примере 2.1 локальной переменной является переменная I.
Второй вариант короче. Выигрыш будет более значителен, если надо выводить несколько таблиц разных размеров. Тогда изменяем и значения.
Для того чтобы процедура могла выполнить не одну строго определенную последовательность действий, а целое семейство аналогичных действий, но с разными параметрами, необходимо дополнить процедуру этими параметрами. В нашем случае целесообразно предусмотреть два параметра: параметр, определяющий длину строки, и параметр для выбора символа, которым предполагается прочертить строку.
Тогда программа, включающая в себя процедуру, будет иметь вид, представленный ниже.
Пример 2.2.
Program shapka3_procedura; {Заголовок основной программы}
{ Описание переменных основной программы }
{....... }
Procedure Lin(Len:integer;Ch:Char); {Процедура линии}
{Формальные параметры:длина - Len,символ - Ch}
Var I:lnteger;
Begin {Начало текста процедуры}
FOR l:=1 ТО Len DO write(Ch);
writeln;
End; {Конец процедуры}
BEGIN {начало главной программы}
writeIn ('Таблица 2.1');
Lin(40,’=’); {Вызов процедуры вычерчивания линии}
{....... }
{..вывод текста шапки }
{....... }
Lin(40,’=’); {..вывод номеров граф}
Lin(40,’-’); {Обращение к подпрограмме вычер. линий}
{Продолжение текста программы}
END. {Конец главной программы}
В скобках после имени процедуры описываются имена и типы формальных параметров. Вызов такой процедуры происходит с указанием значений фактических параметров так:
Lin(40,’=’),
где 40 - длина линии, ‘=’ - используемый символ.
Значения, стоящие в круглых скобках, называются аргументами, т.е. теми значениями фактических параметров, которые подставляются при вызове процедуры. Параметру LEN будет присвоено значение 40, параметру Ch значение ‘=’ типа Char. В общем случае аргумент и параметр должны относиться к совместимым типам, т.е. значение аргумента должно быть таким, чтобы его можно было назначить параметру.
Формальные параметры также являются локальными в пределах процедуры (в примере 2.2 это I). Объекты, описанные в некотором внешнем блоке (или программе), доступны и могут быть использованы в любом его подблоке, т.е. они являются глобальными по отношению к этим подблокам. Таким образом, объекты, локальные для некоторого блока, являются глобальными для всех его подблоков. Под этими объектами подразумевают метки и имена констант, типов, переменных, процедур и функций. На рис. 2.1 приведена схема, иллюстрирующая данное положение.
Переменные I, J, К являются локальными по отношению к блоку 3 и недоступны в блоках 1,2. Переменные X, Y, Z доступны в блоках 2,3 и недоступны в блоке 1, по отношению к блоку 3 они являются глобальными. Переменные А, В, С доступны во всей программе и являются глобальными в блоках 2,3. На рис. 2.2 приведена более сложная структура из четырех блоков. На этом рисунке переменная L и локальная, и глобальная, но это разные переменные!
Переменная действительного типа L, определенная в блоке 1, является глобальной в блоке 2, но переопределена в блоке 3, где имеет силу уже новая связь между именем и типом. Глобальная переменная с именем L в блоках 3, 4 недоступна, изменение значения локальной переменной L в блоках 3, 4 никакого влияния на глобальную переменную не оказывает (ее значение не изменится). Чтобы не возникали ошибки, связанные с путаницей имен, не следует использовать одни и те же переменные как глобальные и как локальные. Также целесообразно избегать совпадения имен формальных и фактических параметров. Различные имена делают программу более наглядной.
С помощью параметров можно передавать данные не только в вызываемую процедуру, т.е. осуществлять прямую передачу информации, но и из вызываемой процедуры в вызывающую. Делается это с помощью атрибута VAR (параметры-переменные, см. подраздел 2.6).
Рассмотрим следующим пример. Предположим, необходимо вычислить по заданному числу десятичный логарифм. Так как такой функции в Турбо Паскале нет, то для вычисления используем соотношение
Y = 0.4343*Ln(X).
Для перевода можно использовать следующую процедуру.
Пример 2.3.
Procedure LOG10(Argument:Real;Var LOG:Real);
Begin
LOG:= 0.4343 * LN(X)
End;
Вызов процедуры происходит так: LOG10 (X,Y);
В качестве Y в вызывающую программу будет возвращено значение десятичного логарифма от аргумента X. Это возможно только благодаря тому, что в списке параметров для переменной LOG использован атрибут VAR. Наличие у параметра атрибута VAR свидетельствует о том, что используется передача по адресу. В этом случае одна и та же ячейка памяти используется для хранения значений и параметра, и аргумента.
Функция
Подпрограмма-функция предназначена для вычисления какого-либо параметра. Функция состоит из заголовка и тела функции.
Заголовок функции имеет вид:
FUNCTION <ИМЯ> (СПИСОК ФОРМАЛЬНЫХ ПАРАМЕТРОВ):<ТИП>;
где FUNCTION - служебное слово; ИМЯ - имя процедуры, определяемое в соответствии с общими правилами построения идентификаторов; СПИСОК ФОРМАЛЬНЫХ ПАРАМЕТРОВ - перечень имен для обозначения исходных данных и результатов работы процедуры с указанием их типов.
Допускается описание функции, не содержащее <СПИСКА ФОРМАЛЬНЫХ ПАРАМЕТРОВ>:
PROCEDURE < ИМЯ >:<ТИП>;
в этом случае параметры в функцию передаются через систему глобальных параметров.
У этой подпрограммы два основных отличия от процедуры. Первое отличие - заголовок. Он состоит из слова Function, за которым следует имя функции, затем в круглых скобках - список формальных параметров, затем через двоеточие записывается тип функции, т.е. тип возвращаемого параметра. Функция может возвращать типы вещественные, порядковые, строкового и любого указателя.
Второе отличие в том, что процедура может иметь несколько выходных параметров-результатов, а функция только одно значение, передаваемое через ее имя. Именно этим объясняется то, что в теле функции хотя бы один раз имени функции должно присваиваться вычисленное значение.
Структура функции такая же, как и процедуры.
Пример 2.4. Функция вычисления тангенса tan(x) от аргумента х.
Function Tan(х: real): real;
Var tangens: real;
BEGIN
tangens:= Sin(x)/Cos(x); tan:= tangens;
END;
Для вызова функции из основной программы или другой подпрограммы следует в выражении, где необходимо использовать значение функции, указать имя функции со списком фактических параметров, которые должны совпадать по количеству и типам с формальными параметрами функции. Например, надо вычислить, оператор присваивания будет
Y:=Tan(x)/(1+Sqr(Tan(x));