Главная    Почта    Новости    Каталог    Одноклассники    Погода    Работа    Игры     Рефераты     Карты
  
по Казнету new!
по каталогу
в рефератах

Программа на Delphi

ord(var Source, Dest; Count: Integer); external;
procedure FillWord(var Dest; Data: Integer; Count: Integer); external;
Этот пример показывает, что при компиляции коды процедур MoveWord и
FillWord следует искать в объектном коде BLOCK.OBJ.
 
4. Директива OverLoad позволяет использовать одно имя для нескольких
подпрограмм, например:
function Divide(X, Y: Real): Real; overload;
begin
Result := X/Y;
end;
function Divide(X, Y: Integer): Integer; overload;
begin
Result := X div Y;
end;
В этом примере описаны две функции с одним именем Divide. При обращении к
функции с таким именем вызвана будет та функция, фактические параметры
которой соответствуют формальным параметрам. Так, при обращении в виде
Divide (6.8, 3.2) будет вызвана первая функция, т. к. ее формальные
параметры также вещественны, а при обращении Divide(6, 8) будет вызвана
вторая функция.
Директива Overload разрешена для подпрограмм, в которых могут различаться
только типы параметров, поэтому недопустимы описания вида
           function Cap(S: string): string; overload;
           procedure Cap(var Str: string); overload;
                                       
                           15.5. Процедурные типы
Процедурные типы допускают использование процедур и функций в виде
значений, которые могут быть присвоены переменным или переданы в другие
процедуры или функции. Например, в нижеследующем примере определена функция
Calc с двумя целочисленными формальными параметрами X, Y, возвращающая
целый тип:
function Calc(X,Y: Integer): Integer;
Эта функция может быть определена как тип для переменной F:
           var F: function(X,Y: Integer): Integer;
и связана с этой переменной оператором присваивания:
                 F := Calc;
Точно так же можно определить любой другой новый процедурный тип и
переменную:
      Type {объявление процедурных типов}
      TIntegerFunction = function: Integer;
      TProcedure = procedure;
      TStrProc = procedure(const S: string);
      TMathFunc = function(X: Double): Double;
      Var {объявление процедурных переменных}
      F: TIntegerFunction; {F функция без параметров, возвращающая целое}
      Proc: TProcedure; {Proc – процедура без параметров}
      SP: TStrProc;
      M: TMathFunc;
При использовании операторов над процедурными типами и процедурами или
функциями необходимо различать связывание процедурной переменной и
обращение к процедуре или функции. Так в нижеследующем примере объявляются
переменная F типа функции, а переменная I – простого целочисленного типа,
затем следует текст процедуры SomeFunction:
F: function(X: Integer): Integer;
I: Integer;
 
function SomeFunction(X: Integer): Integer;
...
В операторной части первый оператор связывает F с конкретной функцией, не
производя над ней никаких действий:
F := SomeFunction;
напротив, оператор
I := F(4);
вызывает эту функцию (запускает ее алгоритм) и после обработки возвращает
результат вычислений переменной I.
 
                  15.6. Формальные и фактические параметры
В Object Pascal есть понятия формального и фактического параметров.
Формальным называется параметр, который содержится в заголовке описания
подпрограммы, а фактическим – параметр в обращении к подпрограмме. Так, в
вышеприведенном примере параметр X является формальным, а значение 4 –
фактическим.
При вызове подпрограмм необходимо иметь в виду следующее:
    . фактические значения или константы должны быть совместимы по типу с
      объявленными формальными параметрами;
    . фактические var или out-параметры должны быть идентичны по типу
      объявленным формальным параметрам, исключением являются только
      нетипизированные параметры;
    . формальным параметрам без типа не могут соответствовать такие
      фактические параметры, как числовые значения и нетипизированные число-
      вые константы.
Приведем еще один пример, демонстрирующий способы обращения к
подпрограммам.
      Const
      IntCount = 1200;
      Type
      TFunc12 = Function(c1, c2: Integer): Integer;
      Function Func12_1(k1, k2: Integer): Integer;
      Begin
      Result:= k1 + k2;
      End;
      Function Func12_2(g1, g2: Integer): Integer;
      Begin
      Result:= g1 - g2;
      End;
Procedure AnyPro(u1: Real; Var u2: Real; Var u3; Const u4: Integer; F:
tFunc12);
      Begin
      u2:= u1 + u4 + F(u4, Round(u4 * 3.14));

      u3:= u1 - u4 - F(u4, Round(u4 * 3.14));
      End;
           Var
           k: Integer;

           v1, v2: Real;

           ss: String;

           …
      {примеры обращения к процедуре AnyPro:}
           AnyPro(v1, v2, v1, v2, Func12_1);

           AnyPro(v1, v2, ss, v1, Func12_2);

           AnyPro(k, v1, ss, v2, Func12_1);

           AnyPro(k + 8, v2, ss, IntCount, Func12_1);

           AnyPro(8, v2, ss, v1+6.7, Func12_2);
Параметры u1, u2, u3, u4, F в заголовке процедуры AnyPro, являются
формальными параметрами: u1 – константа типа Real; u2 – переменная типа
Real; u3 – переменная без типа; u4 – константа типа Integer; F – параметр-
функция типа TFunc12, который объявлен выше в секции Type.
Параметры, заключенные в скобки в примерах обращения к процедуре AnyPro,
являются фактическими параметрами. Такие параметры могут быть значениями
(8), константами (IntCount), переменными (v1), выражениями (k + 8), именами
процедур или функций (Func12_1) и др.
 
                         15.7. Область действия имен
В подпрограммах часть параметров может быть объявлена прямо в заголовке или
ее теле. Такие параметры действуют только внутри этой подпрограммы и
поэтому называются локальными параметрами. В то же время в подпрограмме
можно использовать параметры, которые описаны за пределами подпрограммы.
Такие параметры называются глобальными параметрами.
Глобальные параметры могут быть описаны в том же модуле, который содержит
использующую их подпрограмму, или в другом модуле, на который имеется
ссылка в списке uses. Если два параметра имеют одинаковое имя и один из них
описан внутри подпрограммы, а другой – вне ее, то действует тот параметр,
который описан в подпрограмме. Аналогично определяется область доступности
параметров описанных в разных модулях. Таким образом, при описании имен
действует следующий принцип: более позднее объявление отменяет облаcть
действия ранее описанных имен. Внутри одной подпрограммы нельзя объявлять
двух и более одинаковых имен.
Поясним область действия имен на примере следующего модуля
Unit Mod4;
interface
uses Mod1, Mod2, Mod3;
….
Type
Vr = Integer; {допустимо}
…
Var
Vr: Real; {недопустимо}
…
implementation
Var Vr: Char; {недопустимо}
…
procedure Pro1; {не содержит внутреннего объявления имени Vr}
…
procedure Pro2; { содержит внутреннее объявление имени Vr}
Var
Vr: String; {допустимо}
Vr: Real; {недопустимо}
…
В приведенном тексте модуля Mod4 содержится несколько описаний имени Vr,
часть которых допустима, другая часть ошибочна. Недопустимо описание этого
имени:
в var-секции в разделе interface, так как оно уже использовано в этом же
разделе выше – в секции type;
в var-переменной в разделе implementation, так как оно уже использовано в
этом же модуле в разделе interface;
как переменной типа Real в теле процедуры Pro2, т. к. оно уже использовано
в этой же процедуре при описании String-переменной.
Более позднее объявление отменяет действие ранее описанного имени. Так,
внутри процедуры Pro2 имя Vr представляет переменную типа String, а внутри
процедуры Pro1 имя Vr действует как глобальный тип Integer, объявленный
выше – в секции type.
Если бы это имя вообще не было описано в модуле Mod4, но было бы объявлено
в одном или нескольких модулях, указанных в ссылочном списке uses, то оно
могло бы быть использовано как глобальный параметр внутри этого модуля
(Mod4). При этом действовало бы то имя, которое объявлено в разделе
interface самого последнего содержащего его модуля списка uses. Например,
если имеется описание имени Vr в модулях Mod1 и Mod2, то действовало бы
описание из Mod2. Если в списке uses поменять Mod1 и Mod2 местами, то будет
действовать описание, которое выполнено для этого имени в модуле Mod1.
Следует проявлять особую осторожность при использовании глобальных
переменных в подпрограммах. Нижеприведенный пример демонстрирует
непредсказуемое поведение программы, использующей функцию Deccy и
глобальный по отношению к ней параметр d:
Function Deccy(x: Integer) : Integer;
Begin
d:= d - x;
Deccy:= Sqr(x);
End;
…
d:= 3; a:= Deccy(3) * Deccy(d); {a= 0, d= 0}
d:= 3; a:= Deccy(d) * Deccy(3); {a= 81, d= -3}
Пример показывает, что два, казалось бы, корректных способа обраще-ния к
функции дают тем не менее разные результаты вычислений.
 
                    15.8. Рекурсивные процедуры и функции
В Object Pascal допустимо обращение подпрограммы к самой себе (рекурсивное
обращение). При таком обращении параметры, которые использует подпрограмма,
заносятся в стек и сохраняются там до конца работы подпрограммы.
Рекурсивные подпрограммы являются исключительно удобным, нередко
незаменимым инструментом построения эффективных алгоритмов. Оборотной
стороной рекурсивных процедур является опасность переполнения стека, что
часто ограничивает возможность написания таких алгоритмов.
В качестве иллюстрации приведем пример простой и чрезвычайно эффективной
процедуры сортировки (расстановки элементов в порядке неубывания) фрагмента
целочисленного одномерного массива A:
procedure QuickSortPart(var A: array of Integer; iLo, iHi: Integer);
var
Lo, Hi, Mid, T: Integer;
begin
Lo := iLo;
Hi := iHi;
Mid := A[(Lo + Hi) div 2]; {средний элемент фрагмента}
repeat {деление фрагмента на левую и правую части}
while A[Lo] < Mid do Inc(Lo);
while A[Hi] > Mid do Dec(Hi);
if Lo <= Hi then
begin
T := A[Lo];
A[Lo] := A[Hi];
A[Hi] := T;
Inc(Lo);
Dec
Пред.1112131415След.
скачать работу

Программа на Delphi

 

Отправка СМС бесплатно

На правах рекламы


ZERO.kz
 
Модератор сайта RESURS.KZ