Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекції для 3ОТ1.doc
Скачиваний:
10
Добавлен:
21.02.2016
Размер:
16.31 Mб
Скачать

Контрольні питання

  1. Навести поняття та характеристику типізованих констант Delphi

  2. Охарактеризувати принципи застосування типізованих констант

САМОСТІЙНА РОБОТА СТУДЕНТА

Змістовий модуль 4: файлові структури даних. Динамічні структури даних

Тема 4.2: динамічні структури

Самостійне заняття №25 - Підпрограми

План заняття

  1. Поняття структури підпрограми

  2. Поняття заголовку підпрограми

  3. Передача параметрів по назві та значенню

  4. Параметри константи

  5. Параметри результати

Структура подпрограммы

Описание подпрограммы состоит из трех частей: заголовка подпрограммы, локаль¬ного описания и тела подпрограммы. Заголовок используется, чтобы явно ввести в программу новую подпрограмму и обозначить начало ее описания. Локальные опи¬сания представляют собой набор описаний типов, переменных, констант и других подпрограмм, которые действуют только в рамках данной подпрограммы. Тело под-программы — это логический блок begin/end, содержащий операторы и команды Паскаля и реализующий нужную логику работы.

Заголовок Заголовок подпрограммы состоит из трех частей: ключевого слова, характеризую¬щего тип подпрограммы (процедура — procedure, или функция — function), списка параметров, перечисленных через точку с запятой и взятых в круглые скобки, и (только для функций) типа возвращаемого значения, указываемого вслед за двоеточием.

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

procedure Compute(X: Integer; S: String);  function Compare(Al, A2: Byte; Stroka: String): Real;  procedure ShowMap;  function GameOver: Boolean; Список параметров может быть опущен. Для некоторых параметров могут быть заданы значения по умолчанию (все параметры с такими значениями должны располагаться вместе и после параметров, для которых не задано значений по умолчанию). procedure МуРгос ( I: integer; il: integer = 1; i2: integer = 2 ); В подобных случаях заключительные параметры при вызове процедуры можно опускать — они получат значения по умолчанию. МуРгос( 1, 2 ); Реально процедура вызывается с тремя параметрами, как если бы использовался следующий оператор. МуРгос( 1, 2, 2 );

Передача параметров по имени и по значению Когда происходит обращение к подпрограмме, переменным, указанным в списке параметров в описании (формальные параметры), присваиваются значения, ука¬занные в списке параметров в момент вызова (фактические параметры), после чего выполняются необходимые вычисления. Это называется передачей параметров по значению: в подпрограмму передаются значения нужных типов. Формальные пере-менные играют роль локальных переменных. В списке параметров перед любой переменной разрешается указывать ключевое слово var. Тогда считается, что данный параметр будет передаваться по имени: то есть копирования значения не происходит, а вместо формального параметра под¬ставляется имя переменной — фактического параметра. (Отсюда следует, что в качестве фактических параметров, подставляемых вместо формальных параметров с ключевым словом var, можно применять только имена переменных.) Например: procedure MyProc( X: Byte; var Y: Byte ); 

Параметр X будет передаваться по значению, параметр Y — по имени. При вызове MyProc( 2+2 , N ) ; операторы в теле процедуры MyProc будут обрабатывать локальную переменную X, имеющую значение 4 (2+2), и переменную Y, которая на самом деле является пере¬менной N из другой части программы. На «физическом» уровне произойдет просто подстановка адреса переменной N. Использование слова var в списке параметров по способу действия аналогично использованию указателя.

При этом, если в теле процедуры значение переменной X будет меняться, то по окончании работы MyProc эта локальная переменная будет удалена из памяти (до следующего вызова процедуры), а вот если произойдет изменение значения пере¬менной Y, то изменится и значение переменной N.

Это потенциально чревато ошибками, так как разработчик может не рассчитывать на то, что во время работы подпрограммы произойдет изменение значения одного из ее параметров. В данном случае переменная Y является не чем иным, как указателем на переменную N, только описан он немного иначе: не с помощью опера¬ции Л, а как обычная переменная.

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

type TBigArray = array [1..100000] of string[50];

то передавать переменную этого типа по значению очень неэффективно, особенно если вызов подпрограммы происходит часто, потому что при этом требуется копи¬ровать большие объемы данных. То есть описание procedure Sum( A: TBigArray );

неудачно в плане эффективности (хотя компилятор может самостоятельно выпол¬нить передачу параметра по имени в процессе автоматической оптимизации кода).

Правильнее написать так:

procedure Sum( var A: TBigArray );

При этом надо проследить, чтобы изменения элементов массива А внутри проце¬дуры Sum не происходило (если этого не требует логика ее работы). Параметры-константы Если некоторый параметр будет использоваться в теле подпрограммы только для считывания данных (фактически, как константа), лучше не рассчитывать на воз-можности компилятора, а подсказать ему об этом явно. В этом случае присваива¬ние данному параметру нового значения станет недопустимым. Подобная «подсказка» осуществляется указанием зарезервированного слова const в списке параметров, что позволяет организовать эффективную обработку соот-ветствующего параметра, не беспокоясь о возможных изменениях его значения. procedure Sum( const A: TBigArray );

Менять значение элементов переменной А в теле процедуры Sum теперь нельзя: компилятор сообщит об ошибке.

Параметры-результаты В Паскале имеется еще одна возможность передачи параметра по имени — с помо¬щью зарезервированного слова out. Такой параметр может использоваться внутри тела подпрограммы только для присваивания значения (но не для считывания дан¬ных). По смыслу использование слова out противоположно использованию слова const.

Если заголовок процедуры описан так:

procedure Sum( out A: TBigArray ); 

то в теле процедуры Sum можно указывать операторы присваивания А[10000]-:= 'num172855'; 

но нельзя считывать значения элементов массива 

А: х := А[2] * 2; // нельзя!

Преобразования сложных типов

Ранее рассматривалась возможность явного преобразования типов путем использо-вания названия нужного типа как функции (Byte(300)). Паскаль допускает подоб¬ный способ преобразования не только для базовых, но и для любых других типов, определенных разработчиком. Потребность в этом хоть и редко, но все же возникает. Например: type Tl = array[1..2] of Byte;

var Al: Tl;

A2: array[1..2] of Byte; Переменные Al и A2 относятся к разным типам, хотя физически (в оперативной памяти) они представлены одинаково. Поэтому переменную А2, обычный массив, можно преобразовать (привести) к типу Tl:Tl(А2) Такая запись аналогична простому обращению к имени массива А2, только при этом считается, что он имеет новый тип Tl. К элементам массива нового типа можно обращаться, как и раньше, с помощью квадратных скобок: ТКА2) [1]

Параметры без типов

Паскаль позволяет указывать в заголовке подпрограммы параметры без типов (но с предшествующим словом const, var или out). procedure Sum( const A );

Переменная А в таком случае считается не имеющей никакого типа, и ее нельзя использовать ни в каких выражениях или операторах, не выполнив предварительно преобразование — приведение к нужному типу. Например, в теле процедуры Sum переменную А можно использовать так: X := Т1(А)[5] * 2;

Передача строк фиксированной длины

Строки можно описывать, как уже говорилось ранее, двумя способами: просто как тип string, или как тип string с конкретной длиной строки в квадратных скобках. Однако указывать строки фиксированной длины в качестве параметров подпро¬грамм нельзя. Их сначала надо описать как новый тип. procedure Sum( S: string[50] ); // неверно!

Правильно написать так:

type string50 = string[50]; 

procedure Sum( S: string50 );

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

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

В Паскале разрешается указывать в качестве параметров массив с неопределенными границами.

procedure Sum( A: array of Byte );

Теперь массив, описанный как var Ar: array [1..25] of Byte; можно без проблем передавать в процедуру Sum: Sum(Ar); При этом внутри тела подпрограммы действуют следующие правила: >> Нумерация элементов массива начинается с нуля (число элементов можно определить с помощью стандартной функции SizeOf); >> Функция High возвращает верхнюю границу массива (равную Size0f()-1); >> Копирование массива одним оператором присваивания не разрешается; >> Вместо массива в подпрограмму может быть передана обычная переменная соответствующего типа. Внутри подпрограммы она будет представлена в виде массива из одного элемента (с индексом 0).

Передача значений как массива

Зместо указания в параметрах при обращении к подпрограмме имени переменной-ассива можно указать непосредственно содержимое этого массива: список значе-ий через запятую в квадратных скобках. Sum( [1, 5, X, a+b*2] );

Передача массива вариантного типа

Массив, описанный как array [1..MaxNum] of Variant; может быть передан в качестве параметра в подпрограмму, если этот параметр описан как array of const:procedure Sum( A: array of const ),

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]