Модераторы: volvo877, Snowy, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Процедурный тип данных, Что это такое и с чем его едят 
:(
    Опции темы
SPrograMMer
  Дата 16.4.2005, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: нет
Всего: 6



Вот есчо один "наболевший" вопрос.

Процедурный тип данных. Что это такое и с чем его едят.

Подпрограмы в языке паскаль бывют двух типов: процедуры - подпрограммы (чаще всего) не возвращающие никакого результата, и функции, возвращающие какое-то значение.
Давайте представим, что нам нужно произвести какие-то действия с каким-то объектом, например с числом. Например, нам надо вычислить корень кубический этого числа, или возвести в 5-ую степень, или посчитать сумму чисел от 1 до этого числа или ....... Как можно реализовать всё это дело? Можно написать ряд подпрограммок , например с именами SQRT3, SQR5, Symma ... а в решающий момент (когда надо результат получить) мы просто будем вызывать нужную нам из перечисленных функций. Вот наверное первое, что приходит в голову для решения вышеуказанное задачи.
Хорошо мы с вами придумали 3 дествия с числом: корень, возведение в степень и сумму. Функций не много, реализовать не сложно, примерно так:
Код

function SQRT3(x:Real):Real;
Begin
....
End;
function SQR5(X:Real):Real;
Begin
.....
End;
function Symma(X:Integer):Integer;
Begin
....
End;
....
Begin
  ....
  Case чего-то of
      1: Result:=SQRT3(X);
      2: Result:=SQR5(X);
      3: Result:=Symma(X);
  End;
  // пользуемся значением Result в нужных целях далее
  ....
End;

Как я уже сказал функций не много, реализовать не сложно. Теперь смотрите, если мы такую программку составим, сдадим в пользование и через некоторое время нам скажут: "А вот если бы с числом можно было бы производить еще ряд операций" и выдадут нам список из еще 50 наименований функций. smile
Что будем делать, если текст общей программы большой, найти нужный кусок оччччччень затруднительно.
А вот здесь к нам напомощь и пришёл бы (просто прискакал бы) процедурный тип данных.
идея следующая: функции нам, хочешь - нехочешь, пришлось бы реализовывать в виде отдельных подпрограмм функций. а вот на вызове нужной мы с экономим: станим вызывать не саму функцию, а ссылку на неё.
Это очень напоминает работу с указателями и динамическими переменными, где по ссылке мы можем получить само значение. На самом деле так оно и получается, в машинных кодах и подпрограммы и пееменные имеют свои адреса, к ним (подпрограммам) и происходит обращение по адресу.
Для такой реализации в паскале надо обявить прототип функции, (с появлением .Net их стали называть делегатами) т е её объявление в общем виде: тип подпрограммы (процедура или функция), список параметров, с указанием типов данных и тип возвращаемого значения, если это функция.
Пример:
Код

Type
  TFunct=Function(X:Real):Real;
  TMyProc=Procedure(A,B,C:Integer;Var S:String);

Здесь обявлены два типа: TFunct - это функция, в качестве параметра которой выступает переменная X вещественного типа, результат - тоже вещественное число; TMyProc - подпрограмма, имеющая три параметра с именами A, B и C целого типа и параметра S строкового типа, который возвращает эта подпрограма. Как видите имена подпрограмм в общем виде не задаются.
TFunct и TMyProc теперь равноправные типы данных паскаля, такие как Integer, Real, Char, MyRecord, MyBigArray .... И соответственно можно объявлять переменные этих типов:
Код

Var
   F:TFunct;
   P:TMyProc;

Добавлено @ 20:32
На самом деле переменные F и P - указатели. Но к этим указателям нельзя применять адресную арифметику, к ним применяются только операции присваения и сравнения. В них может содержаться "пустой" укзатель, т е Nil.
Так как переменная F имеет тип данных TFunct, который обявлен как Function(X:Real):Real, то в эту переменную может быть занесена только функция, не подпрограмма!, у каоторой только один параметр, типа Real. Но и это не все функция должна возвращать значение тоже типа Real, если у функции один пааметр типа Real, но она возвращает значение типа Char или String или Integer или ...., то такую функцию в переменную F занести нельзя!

Что нам это дает? Неужели нельзя было обойтись простым case ... of (из первого примера)?
Впринципе можно было в случае добавления списка из новых функций, расширить код case of, и перечислить еще тридцать значений....
Но использование процедурных переменных, позволило бы нам занести в переменную, допустим F имя нужной функции, а затем использовать выражение следующего вида:
Код

  Result:=F(X);
Тогда как на самом деле функции F мы не объявляли, т е у нет кода
Код

Function F(...);
.....

Но у нас есть тип данных
Код

Type
  TFunct=Function(X:Real):Real;

и Переменная
Код

Var
  F:TFunct;

Которые не смотря на отсутствие функции F позволяют выполнить строку Result:=F(X);
Если перед этой строкой в F будет ссылка на функцию, извлекающую корень, то эта строка будет эквивалентна Result:=SQRT3(X); как будто вместо F стоит идентификатор SQRT3. А сохранять в переменной процедурного типа даных ссылку на процедуру очень просто - простым присваиванием:
Код

Type
   TFunct=Function(Var X:String):Real;
Function XYZ(Var X:String):Real;
Begin
...
End;
Var
   Ft:TFunct;
Begin 
  ....
  Ft:=XYZ;  // просто идентификатор функции, без скобок и параметров!!!
  ...


Теперь нескоко слов о специфике реализации таких функций:
все процедурыи функции, имена которых присваиваются процедурным переменным, необходимо компилировать с ключом компиляции $F+. Вложенные процедуры и функции с процедурными переменными использовать нельзя. Ну и самое обидное, это то что в качестве ссылок НЕМОГУТ быть использованы СТАНДАРТНЫЕ процедуры и функции типа sin, cos и т п. Последнее правда можно легко обойти: просто создать функцию, которая будет в качестве своей реализации использовать стандартную. Например, так может быть реализованы ссылки на тригонометрические функции:
Код

{$F+}  // включаем специальный режим компиляции
Function MySin(X:Real):Real;
Begin
  MySin:=Sin(X);
End;
Function MyCos(X:Real):Real;
Begin
  MyCos:=Cos(X);
End;
{$F-}  // выключаем...
Type
   TTrigFunct=Function(X:Real):Real;
Var
   F:TTrigFunct;
...
  F:=MyCos;
...
  Res:=F(0.5); // эквивалентно MyCos(0.5) или еще проще просто cos(0.5)
....


Добавлено @ 20:33
Ну есчо раз повторю, что процедурный тип данных ничем не отличается от других типов данных. После обявления соответствующего типа, можно использовать кроме переменных еще и константы процедурного типа (естно сама процедура должна быть описана "выше" чем объявлена константа).

Ну и теперь подитожу. Если в нашей первоначальной задаче, которую наверное уже все забыли, использовать процедурный тип данных, то вызов функции (это вся конструкция case of), будет заменена на строчку вида:
Result:=F(X);
и в случае добавления еще нескольких функций, мы лишь добавляем реализацию этих функций, ну и добавляем есчо определение, какую же функцию мы хотим вызвать и все. вышеуказанная строка, остаются и все будет работать.

Да замечу, что при использовании массива, эл-ты которого яв-ся переменными процедурного типа, вызов функции, которая назначана I-ому элементу будет выглядеть следующим образом:
Proc[I](X,Y,z)
Запись, которая может сбить с толку на первый взгляд. Но при боле внимательном рассмотрении все становится на свои места: Proc[I] - вызов эл-та массива Proc, имеющего номер I, а то что стоит дальше - скобки и параметры - это дальнейший вызов нужной нам функции, ведь элемент массива Proc[I] можно заменить обычной, не индексированной переменной, например A, тогда запись более понятна:
A(X,Y,Z)

И есчо, кто-то может сказать, что в случае использования этих самых процедурных переменных, программа только услажняется: надо описывать новый тп данных, использовать промежуточные переменные... Все же можно было написать аккуратно, и даже в нашей задаче, при добавлении новых возможностей легко можно было бы найти нужное место в программе и просто расширить список case of....
На такое я отвечаю тем, что массивы и записи, тоже тогда можно было бы отменить.... Написать просто 150 наименований разных переменных, вместо одного массива из 150 элементов, и радоваться жизни....

PS: а в некотрых случаях "системного" программирования без переменных процедурного типа просто не обойтись, ведь если решать задачу в общем виде, то скорее всего вы не знаете сразу как будет вычислять функция F(X,Y), а реализация этой функции будет известна только в прикладной программе. Так что если бы не было бы возможности ссылаться на другие, в том числе и внешние подпрограммы, наверное, невозможно было бы в системе windows, использование библиотек (в том числе и DLL), с доработаными или добавленными возможностями.
Все для начала я думаю хватит, а то меня дальше понесёт smile smile


PS: ЛЮДИ!!! откликнитесь насчет усвояемости и легкочитаемости...
ОЧЕНЬ НАДО!


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
Hidrag
Дата 16.4.2005, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 877
Регистрация: 9.4.2005
Где: JDK

Репутация: нет
Всего: 25



SPrograMMer
Супер, учу паскаль но этим пользоваться не приходилось, даже когда нужно было!!!
Тебе учебники писать нужно! smile)) кстати про использованиее этого в DLLках в качестве второго примера можно чуть подробнее smile это более практичный и наглядный пример.


--------------------
user posted image
PM WWW ICQ   Вверх
SPrograMMer
Дата 16.4.2005, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: нет
Всего: 6



Цитата(Hidrag @ 16.4.2005, 21:24)
Тебе учебники писать нужно

А то! Программа обучения студентов "начала программирования в среде Delphi" моя работа, которую видел узкий круг человек (10-15) и прослушило этот курс всего-навсего 8 чел smile

Цитата(Hidrag @ 16.4.2005, 21:24)
кстати про использованиее этого в DLLках в качестве второго примера можно чуть подробнее  это более практичный и наглядный пример

буд сделано, тока чутка попозже, может даже к завтраму...


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
Fedor
Дата 16.4.2005, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Днепрянин
****


Профиль
Группа: Участник
Сообщений: 2090
Регистрация: 8.2.2003
Где: Великий

Репутация: нет
Всего: 32



Добавлено в FAQ. Еще раз огромное спасибо SPrograMMer! Так держать!
http://vingrad.ru/DELPHI-FAQ-002490


--------------------
Мы - Днепряне. Мы всех сильней.
PM ICQ   Вверх
Fantasist
Дата 16.4.2005, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: нет
Всего: 41



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

Цитата(SPrograMMer @ 16.4.2005, 19:33)
прототип функции, (с появлением .Net их стали называть делегатами)


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

Цитата(SPrograMMer @ 16.4.2005, 17:31)
необходимо компилировать с ключом компиляции $F+


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


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


Добавлено @ 23:10
P.S. и удалите дубль пожалуйста.




--------------------
Волны гасят ветер...
PM MAIL   Вверх
SPrograMMer
Дата 17.4.2005, 08:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: нет
Всего: 6



Цитата(Fantasist @ 16.4.2005, 23:08)
Если упоминается деректива компилятора, то неплохо было бы указать, что она делает. Я например такой никогда не пользовался и не видел, в Delphi7 я так же не смог отыскать ее в хелпе. Подозреваю, что ее больше не существует.

Ну раздел хоть и называется "Delphi/Паскаль", подраздел то ведь - "Паскаль", поэтому я ориентировался на старые Dos - компиляторы, в том числе и на Borland Pascal 7.0...
Там все это есть.
Цитата

Режим компиляции $F+ включает компиляцию с расчетом на дальнюю модель вызова подпрограмм (дальная модель памяти). $F- соответственно выключает. Дирректива  Far указанная сразу после объявления подпрограммы так же компилирует подпрограмму с расчетом на дальнюю память

Да ты прав в Delphi (даже наверное с 1-ой) такого режима нет, там все сразу компилируется с расчетом на дальную модель памяти...

Цитата(Fantasist @ 16.4.2005, 23:08)
Сам пример, на мой взгляд, не очень удачный - сразу приходит в голову вопрос, что где-то теперь в другом месте есть case, который присваевает процедурной ссылке нужную процедуру, что естесственно не дает никаких удобств или преимуществ. Для демонстрации подобных вещей лучше использовать концепцию callback функций.

smile я сам понимал, что неуданый а другого ничего не шло в голову. Спасибо подсказал. Учтём.... smile

Цитата(Fantasist @ 16.4.2005, 23:08)
Еще неплохо было бы здесь же рассмотреть указатель на метод

Ну это уже ООП, как мне кажется совершенно другая темя...

Это сообщение отредактировал(а) SPrograMMer - 17.4.2005, 08:06


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
Fantasist
Дата 17.4.2005, 08:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: нет
Всего: 41





Цитата(SPrograMMer @ 17.4.2005, 05:03)
Ну это уже ООП, как мне кажется совершенно другая темя...


Хорошо, согласен.


Цитата(SPrograMMer @ 17.4.2005, 05:03)
Режим компиляции $F+ включает компиляцию


Ах вон оно что. Ну тогда для всех компиляторов для Win32 это не нужно. В Win32 вся память Flat и 32 разрядная (то есть Far). Точно так же, как и модификатор Far.

smile

C уважением.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
SPrograMMer
Дата 17.4.2005, 08:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: нет
Всего: 6



Значит счас примерчиков по на саставлю:
Цитата(Hidrag @ 16.4.2005, 21:24)
про использованиее этого в DLLках

Цитата(Fantasist @ 16.4.2005, 23:08)
лучше использовать концепцию callback функций

и можно фак обнавлять. Кстати это делать моно, или там усе железно: раз и все ни каких редактирований более?


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
Fedor
Дата 17.4.2005, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Днепрянин
****


Профиль
Группа: Участник
Сообщений: 2090
Регистрация: 8.2.2003
Где: Великий

Репутация: нет
Всего: 32



Цитата(SPrograMMer @ 17.4.2005, 08:24)
Кстати это делать моно

Можно.


--------------------
Мы - Днепряне. Мы всех сильней.
PM ICQ   Вверх
SPrograMMer
Дата 17.4.2005, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: нет
Всего: 6



В качестве примера рассмотрю изобретение велосипеда. smile
Допустим сочиняем мы контейнер для чего-то. Ну т е коллекцию, в Delphi уже есть готовые классы-коллекции, в Turbo Vision то ж есть такое счастье. ООП рассматривать здесь не буду, т к это уже другая тема.
Так вот пусть наша коллекция будет хранить любые объекты, это значит что нам по большому счету надо будет хранить указатель на объект. Объект у меня это не термин ООП, а даные, т е в качестве объекта может рассматриваться массив, целое число, строка, запись, другой тип данный. Кто говорит что для обозначения любого, что здесь перечислено, нельзя приментть слово "объект" пусть кинет в меня камень!
А сама коллекция будут организована в виде очереди (основанной на динамических переменных). И пусть мы все чего на создадим поместим в библиотеку (может даже и в DLL). И после будем использовать наши труды в других програмах, и даже другим програмистам дадим воспользоваться.
Ну так вот для реализации очереди я предлагаю использовать следующую структуру:
Код

Type
   PItem=^TItem;
   TItem=Record
     Data:Pointer;
     Next,Pred:PItem;  // пусть очередь у нас будет двунаправленная
  End;
Var
  First,Last:PItem;

Далее мы реализуем подпрограммки по работе с этой бедой, например, добавление элементов, удаление элементов, поиск элементов, упорядочивание элементов...
Насчет добавления и удаления я думаю ничего сложного нет - подпрограммки простые!
Вот как реализовать поиск?
Ну что начинаем с простого - пусть в нашей коллекции (и точка!), будут храниться только целые числа (точнее указатели на них). Тогда мы могли бы написать что-то вроде:
Код

Function Find(Chislo:Integer):PItem;  // возвращаться будет элемент коллекции или Nil если нет такового
  Var
    CurItem:PItem;
Begin
  CurItem:=First;
  While CurItem<>Nil Do Begin
     If Integer(CurItem^.Data^)=Chislo Then Begin  
        Find:=CurItem;
        Exit
     End;
     CurItem:=CurItem^.Next
  End;
  Find:=Nil
End;

Несложно! Условие, в котором производится приведение значения,хранимого по указателю Data к целому типу я думаю понятно.
А что будет, если у нас в коллекции будут строки? Нужно изменить тип входного параметра, и приводить нужно к другому типу данных.
А если другой программист или мы в программке, использующей эти коллекции, создадим ... ну например запись, и хранить в Data будем указатель на эту запись. Тогда для сравнения, мы должны будем не только привести data^ к типу апись, но и выбрать из этой записи поле по которому будем сравнивать. Например, у нас будет сисок работников, и искать мы будем по имени, то есть по полю FIO в одном случае, а в другом - по окладу..........................
А если.... А что .....
типов данных может быть бесчисленное множество. И как сравнивать текущий элемент с эталоном?
Вот тута мы и воспользуемся ссылкой на подпрограмму, которую кстати сами и напишем в каждом конкретном случае, а в подпрограмму Find будем передовать как эталон, так функцию, которая будет вычислять равны ли два значения, или не равны...
Так как в коллекции может храниться все, что угодно, то тип эталона я думаю ясен - это ссылка (указатель) на эталон, т е Pointer. Значит заголовок нашей процедурки будет следующий:
Код

Function Find(Etalon:Pointer;FunctForCompare:[b]тип_функции[/b]):PItem;
...

В реализации мало, что измениться, разве что поменяется немного вид сравнения....
Давайте подумаем, что это за тип_функции нам нужен (это и будет параметр процедурного типа). Ну во-первых это будет функция, кроме того она будет возвращать логическое знаяение: True - если элементы одинаковы, и False - в противном случае. В функции будет сравниваться два значения: эталон и текущие данные. Тип их (я уже не обясняю) Pointer.
Вот и получили следующий процедурный тип:
Код

Type
   TFunctForCompare=Function(Item1,Item2:Pointer):Boolean;

ну и объявление подпрограмки (если кто еще не понял):
Код

Function Find(Etalon:Pointer;FunctForCompare:FunctForCompare):PItem;
...
begin
  ...
       If FunctForCompare(Etalon,CurItem^.Data) Then     // Элементы равны?
  ...
End;

Как видите в этом случае мы вместо конкретно сравнения (например двух целых чисел), перешли к более общему: теперь процедуру сравнения мы оставляем на совести основной программы, которая будет использовать нашу коллекцию.
Согласитесь, что в каждой программе реализовывать свою коллекцию, с особыми подпрограммами сравнения, в первом случае для целых чисел, в другом для записи, в третьем ...
трудоёмко. Проще реализовать общий подход, а в главной программе только ссылаться на то что уже есть чуть-чуть "доработав" этот общий подход к конкретному случаю, например, для сравнения строк.
Добавлено @ 14:36
Если кто не понял, то в основной программе мы с вами написали что-то типа:
Код

{$F+}
Function CompInteger(Item1,Item2:Pointer):Boolean;  // сравнение двух целых чисел
Begin
   CompInteger:=Integer(Item1^)=Integer(Item2^)
End;
Function CompString(Item1,Item2:Pointer):Boolean;  // двух строк
Begin
   CompString:=String(Item1^)=String(Item2^)
End;
Function CompMyRecord(Item1,Item2:Pointer):Boolean; // двух записей "только что придуманых"
Begin
   CompMyRecord:=MyRecord(Item1^).Pole1=MyRecord(Item2^).Pole1
End;
{$F-}

А в критический момент использовать это все так:
Код

EtalonStr^:='Строка';
If  Find(EtalonStr,CompString)<>Nil Then 
   // в коллекции есть элемент "Строка"!!!

или так:
Код

EtalonInt^:=33;
If  Find(EtalonIntr,CompInteger)<>Nil Then 
   // в коллекции есть элемент со значением 33

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


Теперь подпрограмма упорядочивания.
Собсно ничего сложного опять нет, составляем общий алгоритм (пусть будет пузырёк):
Код

Procedure Sort;
  Var
    CurItem1,CurItem2:PItem;
  Procedure SWAP; // обмен двух элементов местами...
  Begin                    // реализация - задание читающему  :) 
    ....
  End;
Begin
  CurItem1:=First;
  While CurItem1^.Next<>Nil Do Begin
    CurItem2:=CurItem1^.Next;
    While CurItem2<>Nil Do Begin
        If Элемент1 < Элемент2 Then      // вот тут и будем использовать процедурный тип данных
          Swap;    // обмен                        //
        CurItem2:=CurItem2^.next
    End;
    CurItem1:=CurItem1^.Next
  End
End;

Теперь Нам надо выяснить как относятся друг к другу два элемента:
-они равны;
-первый больше вторго;
-первый меньше второго.
задача непосредственного сравнения остаётся за основной подпрограммой, и в каждом конкретном случае будет своя.
Нам остаётся определить обявление функции - какие параметры, какого типа, что ф-ция будет возвращать. Сравниваем мы опять два элемента, поэтому с входными параметрами ясно. Результатов сравнения у нас три - использовать логический тип данных в принципе можно, но не желательно, давайте будет разнообразновать свою жизнь. smile
Поэтому пусть наша ф-ция возвращает целые числа:
0 - равные элементы;
-1 - первый больше вторго;
+1 - первый меньше второго.
соответственно тип такой функции следующий:
Код

Type
  TFunctForSort=Function(Item1,Item2:Pointer):Integer;

А дальше.... а дальше так же как и с подпрограммой поиска....
Добавлено @ 14:41
Таким образом можно придумать есчо кучу подпрограмм для работы с коллекцией, и со ссылками на другие подпрограммы.



ЗЫ: Опять целая статья получилась smile


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
Romtek
Дата 18.4.2005, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 7.12.2004
Где: Холон

Репутация: нет
Всего: 4



Хочу добавить (извините, если я повторяюсь), что:
если есть функции, у которых разные типы входных и возвращаемых переменных, то нельзя их объединять одним функциональным типом.
То есть, если
function SQRT3(x:Real):Real;
function SQR5(X:Real):Real;
function Symma(X:Real):Integer;

то можно объявить переменную
Var
F:TFunct;
для передачи её в качестве параметра для функций SQRT3 и SQR5, но она не подойдёт для Symma, т.к. возвращаемый тип отличается от типа TFunct.

И, вообще, нельзя реализовать шаблон в Турбо Паскале как в языке Си, когда можно определять функции с разными входными и возвращаемыми типами переменных (хотя в некоторых 32-разрядных копиляторах Паскаля это возможно).
--------------------
Romiras HomeLab - материалы и статьи по разработке ПО, моделирование алгоритмов, обработка и анализ информации, нейронные сети, машинное зрение и пр.
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi"
THandle
Rrader
volvo877

Запрещается!

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

2. Публиковать ссылки на варез

3. Оффтопить

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, THandle, Rrader, volvo877.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Object Pascal: кроссплатформенные технологии | Следующая тема »


 




[ Время генерации скрипта: 0.0982 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.