Опубликован: 03.09.2010 | Доступ: свободный | Студентов: 3417 / 749 | Оценка: 4.11 / 3.69 | Длительность: 10:38:00
Лекция 4:

Модульное программирование

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >

Глобальные и локальные переменные

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

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

ПРИМЕЧАНИЕ Если переменная внутри подпрограммы определена в разделе описания констант, - начальное значение ей присваивается один раз до начала работы программы. Время жизни такой переменной — вся программа, то есть значение этой переменной сохраняется между вызовами подпрограммы. Область действия переменной — подпрограмма, в которой она описана.

Глобальные переменные доступны в любом месте программы или подпрограммы, кроме тех подпрограмм, в которых описаны локальные переменные с такими же именами. Локальные переменные могут использоваться только в подпрограмме, в которой они описаны, и всех вложенных в нее.

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

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

ВНИМАНИЕ Подпрограмму надо писать таким образом, чтобы вся необходимая для ее использования информация содержалась в ее заголовке.

Виды параметров подпрограмм

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

В заголовке подпрограммы нельзя вводить описание нового типа — там должны использоваться либо имена стандартных типов, либо имена типов, описанных программистом ранее в разделе type.

В Паскале существует четыре вида параметров: значения, переменные, константы и нетипизированные параметры.

Кроме того, по другим критериям можно выделить особые виды параметров:

  • открытые массивы и строки;
  • процедурные и функциональные параметры;
  • объекты.

Параметры-значения

Параметр-значение описывается в заголовке подпрограммы следующим образом:

имя : тип;

Например, передача величины целого типа в процедуру Р записывается так:

procedure P(x : integer);

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

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

При вызове подпрограммы на месте параметра, передаваемого по значению, может находиться выражение (а также, конечно, его частные случаи — переменная или константа). Тип выражения должен быть совместим по присваиванию с типом параметра.

Например, если в вызывающей программе описаны переменные

var x : integer; c : byte; y : longint;

то следующие вызовы подпрограммы Р, заголовок которой описан выше, будут синтаксически правильными:

P(x); P(c); P(y); P(200); P(x div 4 + 1);

Недостатками передачи по значению являются затраты времени на копирование параметра, затраты памяти в стеке и опасность его переполнения, когда речь идет о параметрах, занимающих много места, например массивах большого размера.

Параметры-переменные

Признаком параметра-переменной является ключевое слово var перед описанием параметра:

var имя : тип;

Например, параметр-переменная целого типа в процедуре Р записывается так:

procedure P(var x : integer);

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

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

Проиллюстрируем передачу параметров-значений и параметров-переменных на примере ( пример 4.3).

var a, b, c, d, e : word;
procedure X(a, b, c : word; var d : word);
    var e : word;
begin  
    c := a + b; d := c; e := c;
    writeln ('Значения переменных в подпрограмме:');
    writeln ('c = ', c, ' d = ', d, ' e = ', e);
end;
begin  
    a := 3; b := 5; 
    x(a, b, c, d);
    writeln ('Значения переменных в главной программе:');
    writeln ('c = ', c, ' d = ', d, ' e = ', e);
end.
Листинг 4.3. Параметры-значения и параметры-переменные

Результаты работы этой программы приведены ниже.

Значения переменных в подпрограмме:
c = 8 d = 8 e = 8
Значения переменных в главной программе:
c = 0 d = 8 e = 0

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

Параметры-константы

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

const имя : тип;

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

Например, параметр-константа целого типа в процедуре Р записывается так:

procedure P(const x : integer);

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

Параметры составных типов (массивы, записи, строки) предпочтительнее передавать как константы, потому что при этом не расходуется время на копирование и место в стеке (размер стека не может превышать 64 Кбайт, а по умолчанию устанавливается равным 16 Кбайт).

Результаты работы процедуры следует передавать через параметры-переменные, результат функции — через ее имя.

СОВЕТ В списке параметров записывайте сначала все входные параметры, затем — все выходные. Давайте параметрам имена, по которым можно получить представление об их назначении.

Открытые массивы и строки

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

procedure P(a : array of real);

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

Его элементы нумеруются с нуля. Номер максимального элемента в массиве можно определить с помощью функции High.. Рассмотрите пример ( пример 4.4).

function max_el(const mas : array of integer) : integer;
var i, max : integer;
begin
    max := mas[0];
    for i := 0 to High(mas) do
        if mas[i] > max then max := mas[i];
    max_el := max;
end;
Листинг 4.4. Максимальный элемент любого целочисленного массива

Для передачи в подпрограмму по адресу строк любой длины используется либо специальный тип OpenString, называемый открытой строкой, либо тип string при включенном режиме {$P+} (по умолчанию этот режим выключен).

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

Пример передачи строк в подпрограмму:

type s20 = string[20];
var s1 : string[40]; 
    s2 : string[10];
procedure P(const x : s20; y : string; var z : openstring);
...
begin
    ...     P(s2, s1, s1); ...
end.
< Лекция 3 || Лекция 4: 1234 || Лекция 5 >
София Шишова
София Шишова

Я завершила экзамен 90 баллов на 5. Сертификат не заказала. Сейчас пытаюсь найти как его заказать. у меня указано экзамен пройден баллы оценка видно, а чтоб заказать сертификат нигде не видно.