Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Informatika_2-y_semestr

.pdf
Скачиваний:
18
Добавлен:
11.04.2015
Размер:
1.98 Mб
Скачать

Информатика 2012г.

51

B:=-675.9; SumS(A, B, SA, SB);

writeln(‘SA-‘, SA, ‘SB-‘, SB); end.

Вычисление значения функции

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

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

Пример: Определение максимума двух целых чисел program examplf;

function Max(A, B:integer;):integer; begin

if A>B then Max:=A else Max:=B;

end;

var g, k:integer; g:=98.9; k:=765.7;

writeln(‘max_rez –‘, Max(g, k)); end.

Функция может быть использована в выражении, например M:=Max(A, F)+2*Max(A-F,G); Работа функции и процедуры завершается по определению после выполнения последнего оператора ее тела.

Параметры-процедуры и параметры-функции

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

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

Пример: вычислить Ui , где Ui=f(i)

Информатика 2012г.

52

function Sum(M, N:integer; function F(x:integer):real):real; var I:integer;

S:real; begin S:=0;

for I:=M to N do S:=S+F(I);

Sum:=S; end; (* SUM*)

function F(L:integer):real; begin

F:=L/(L+1.); end;(* F*)

вызов функции

U:=Sum(1, 100, F);

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

Рекурсия

Втеле подпрограммы доступны все объекты, описанные в объемлющем блоке, в том числе и имя самой подпрограммы. Таким образом, возможен вызов подпрограммой самой подпрограммы. Использование подпрограммой самой себя называется рекурсией. Допускается косвенная рекурсия: процедура А вызывает процедуру В, а та вызывает А. Рекурсия применяется для решения задач комбинаторики.

Например: вычисление факториала function Fact(N:integer;):integer; begin

if N=1 then Fact:=1

else Fact:=N*Fact(N-1);

end;

Вязыке Pascal нет никаких ограничений на рекурсивные функции. Каждый очередной рекурсивный вызов приводит к образованию новой копии локальных объектов подпрограммы, и все эти копии существуют независимо друг от друга. Необходимо предусмотреть завершение рекурсивной задачи, в нашем случае это N=1.

Предварительное и внешнее описание подпрограмм

Информатика 2012г.

53

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

procedure John(x, y:real); begin

………..

Jack(1, 2);

………..

end;

procedure Jack( a, b:real); begin

……….

John(0.5, 0.8);

……….

end;

При трансляции процедуры John не известна процедура Jack. Если поменять местами процедуры, то проблема остается. Во избежание этой проблемы существует предварительное описание процедур.

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

procedure John(x, y:real); forward; procedure Jack( a, b:real); forward;

…………..

procedure John; begin

…………..

Jack(1, 2);

………..

end; procedure Jack; begin

……….

John(0.5, 0.8);

……….

end;

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

Информатика 2012г.

54

Внешнее описание используется когда подпрограмма или группа подпрограмм разрабатывается вне системы языка Pascal, на другом языке, и необходимо подключить ее к данной Pascal - программе. В Pascal – программе необходимо указать заголовок подключаемой подпрограммы, после которого (вместо тела подпрограммы) должны следовать служебное слово external или fortran и т.п. Подключение происходит на уровне объектных файлов (***.obj). Детальное описание механизма подключения можно найти в фирменной документации по системе.

Например:

Procedure SqRoot(F, JK:real); external; Procedure CbTUT(Hl, Hb, Sk:integer) fortran;

Модули. Общая структура модуля

Модуль – отдельно хранимая и независимо компилируемая единица. Модуль содержит совокупность (коллекцию) программных ресурсов, предназначенных для использования другими модулями и программами. Модуль не является выполняемой программой – его объекты используются другими программными единицами.

Модуль имеет заголовок и две основные части: интерфейс и реализацию. Структура модуля:

unit UnitName; interface

implementation

begin

end.

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

unit CmplVals; interface

type

Complex=record {способ представления комплексных чисел} Re, Im: real;

Информатика 2012г.

55

{Заголовки процедур, реализующих операции над комплексными числами} procedure InitC(C:Complex; R, I:real;);

procedure AddC(C1, C2:Complex; var R: Complex;); procedure MultC(C1, C2:Complex; var R: Complex;); procedure DivC(C1, C2:Complex; var R: Complex;);

procedure WriteC(C:Complex;);

implementation

{полное описание процедур с сокращенным заголовком} procedure InitC;

begin

with C do begin Re:=R; Im:=I; end;

end;

procedure AddC; begin {операторы;} end;

procedure MultC; begin {операторы;} end;

procedure DivC; begin {операторы;} end;

procedure WriteC; begin {операторы;} end;

end.

Модуль компилируется как обычная программа, но в результате образуется файл с расширением .tpu . Для доступа к интерфейсным объектам необходимо указать имя нужного tpu файла. Спецификация имеет вид:

uses U1, U2, U3;

uses – служебное слово; U1, U2, U3 – идентификаторы используемых модулей. Пример использования модуля CmplVals:

program UseCmplVals; uses CmplVals;

var C1, C2, C3: Complex; begin

Информатика 2012г.

56

InitC(1, 2, C1); InitC(3, 4, C2); MultC(C1, C2, C3); WriteC(C3);

end.

Видимость переменных в программе в случае описания

Uses A, B;

будет иметь вид:

Указатели или ссылочные типы

Указатели или ссылочные типы занимают промежуточное положение между простыми и составными типами: с одной стороны, значения этого типа являются неразделимыми, с другой стороны эти типы определяются через другие (в том числе составные) типы. Реально значения ссылочных типов содержат адреса расположения в памяти конкретных значений базового типа. Указатели реализуют для разыменнованого (без использования идентификатора) доступа к объектам так как хранят адреса памяти по которым расположены объекты.

Содержательно любой ссылочный тип определяет множество значений, которые являются УКАЗАТЕЛЯМИ на значения некоторого определенного типа. Для описания ссылочных типов используется символ ^ и идентификатор типа, например:

type p=^integer;

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

Явное описание указателей: var P1, P2:P;

Синтаксис: Ссылочный тип

Для того, чтобы присвоить переменной ссылочного типа некоторое значение (адрес памяти), необходимо воспользоваться унарной операцией

Информатика 2012г.

57

взятия указателя, которая состоит из знака этой операции – символа @ (амперсант) и одного операнда – переменной того типа на который ссылается этот указатель. Например:

var i:integer; p1:^integer;

p1:=@i; то р1 получит в качестве своего нового значения указатель на переменную i (или, попросту говоря, адрес переменной i).

Операция взятия указателя допустима для любых переменных, в том числе для элементов массива, полей записей и т.д. Например:

Var A:array[1..10] of integer; Pt:^integer;

Pt:=@A[i];

Допустимо определение вида “указатель на указатель” так как ссылочные типы можно образовывать от ЛЮБЫХ типов

var P1, P2:^integer; i:integer;

P1:=@i;

P2:=@P1;

Возникшие в результате связи можно изобразить следующей схемой:

Среди указателей есть один специальный указатель который “никуда не указывает” это пустой указатель, который обозначается служебным словом nil. Указатель nil считается константой, совместимой с любым ссылочным типом.

Над значениями ссылочных типов допускаются две операции сравнения на равенство и неравенство; эти операции проверяют, ссылаются ли два указателя на одно и тоже место памяти, и обозначаются знаками ‘=’ и ‘<>’ например:

var bt: boolean; p1, p2: ^real;

…………….

bt:=p1=p2;

Информатика 2012г.

58

if p1<>p2 then …..

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

Например var i:integer;

pt:^integer; begin pt:=@i;

i:=i+2;//первый способ увеличения i на 2

pt^:=pt+2;// второй способ увеличения i на 2

Приведенные выше два оператора эквиваленты.

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

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