Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Как передать в функцию переменную любого типа?

Автор: kramolnic 16.03.2007 2:20

Возникла необходимость написать процедурку, которая будет выводить текст с форматированием относительно окна (по центру, справа, слева и т.п...)... Стандартная процедура ReadLn или WriteLn да и куча им подобных может принимать в качестве параметра переменную любого типа и работать с ней.. можно распечатать и String и Integer... а как объявить свою процедуру, чтобы она могла делать так же?? то есть как не привязывать параметр к определенному типу??
P.S. параметр должен передаваться по ссылке (со словом var).

Автор: volvo 16.03.2007 2:30

Цитата
Стандартная процедура ReadLn или WriteLn
Ошибка... ReadLn/WriteLn - это макросы, ничего общего с процедурами не имеющие... А чтобы передать любой параметр, передавай его вообще без типа:

Procedure p(Var X);
begin
end;

(только тогда ты должен будешь привести внутри процедуры переменную X к нужному типу)...

Вообще, разговор получается беспредметный. Приведи пример, ЧТО именно ты хочешь делать в процедуре, и КАК вызывать ее, посмотрим, что для этого можно сделать... Общий случай здесь не пойдет...

Автор: kramolnic 16.03.2007 2:38

Цитата(volvo @ 15.03.2007 22:30) *

Ошибка... ReadLn/WriteLn - это макросы, ничего общего с процедурами не имеющие... А чтобы передать любой параметр, передавай его вообще без типа:


О как! а я то думал, что процедура, объявленная где нить в дебрях паскаля... sad.gif
ну скажем, хочу я вывести число по центру, а ниже строку, юзая свою процедуру или что там... Вызываем это дело, например, так...:

Код
var
  k: integer;
  s: string;
begin
  k:= 2345;
  s:= 'This is my text';
  WriteCenter(k);
  writeln('');
  WriteCenter(s);
end;
вот как эту WriteCenter описать, чтобы она обе переменные нормально приняла (тип-то разный), вычислила координаты X, Y, куда выводить строку (видимо, все равно придется к Stringу привести, чтобы число символов посчитать), сделала GoToXY и потом Write(param), где param - параметр, передаваемый процедуре...

Автор: volvo 16.03.2007 3:27

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

Спойлер (Показать/Скрыть)

Автор: мисс_граффити 16.03.2007 4:17

Цитата
Возникла необходимость написать процедурку

Возникла для сугубо практических целей? Или должно быть написано именно на паскале?

Автор: kramolnic 16.03.2007 4:41

Цитата(мисс_граффити @ 16.03.2007 0:17) *

Возникла для сугубо практических целей? Или должно быть написано именно на паскале?


Именно для практических целей... и именно на Паскале. Но на самом деле было больше интересно, как это в паскале реализуется такая вещь. Я-то думал, что read и write процедурами являются. dry.gif
Думаю, проще просто текстовое значение в качестве параметра принимать и его выводить. Придется только преобразовывать типы в String... эх... прям как в старые добрые времена в Delphi nea.gif там достали эти преобразования, так теперь еще и здесь...

Автор: мисс_граффити 16.03.2007 4:56

Ясно. Я просто хотела предложить посмотреть в сторону java... Там это несложно реализовать.
*задумалась, считать ли это свое сообщение нарушением правил.

Автор: volvo 16.03.2007 5:16

Цитата
на самом деле было больше интересно, как это в паскале реализуется такая вещь.
На самом то деле в Паскале такое реализуется ГОРАЗДО проще, чем ты можешь себе предстаить, только вот почему-то у многих выработался рефлекс: как только видят в программе слово Object - дальше программа не читается... А зря... Смотри:

type
pT = ^T;
T = object
constructor create;
procedure Print; virtual;
end;

pTstring = ^Tstring;
Tstring = object(T)
data: string;
constructor create(s: string);
procedure Print; virtual;
end;

pTinteger = ^Tinteger;
Tinteger = object(T)
data: integer;
constructor create(i: integer);
procedure Print; virtual;
end;

constructor T.create;
begin end;
procedure T.print;
begin end;

constructor Tstring.create(s: string);
begin
inherited Create;
data := s;
end;
procedure Tstring.Print;
begin
writeln('<' + data + '>')
end;

constructor Tinteger.create(i: integer);
begin
inherited Create;
data := i;
end;
procedure Tinteger.Print;
begin
writeln(data:10);
end;

procedure WriteCenter(Obj: pT);
begin
Obj^.Print;
end;

begin
WriteCenter(new(pTinteger, create(2345)));
writeln('');
WriteCenter(new(pTstring, create('This is my text')));
end.

Что, ЭТО не Паскаль? Почему же вы выбрасываете из языка ее самую мощную часть?


Автор: Bokul 16.03.2007 5:22

Вопрос: для чего при наследовании ты используешь inherited, вместо простого перекрытия?

Автор: volvo 16.03.2007 5:35

Привычка... Я всегда инициализирую всю цепочку (третий инициализируется вторым, который в свою очередь инициализируется первым)... Возможно, мне понадобится добавить еще один тип МЕЖДУ уже описанными (скажем, перед Tstring), тогда Inherited спасает меня от лазания по коду, как если бы я написал:

constructor Tstring.create(s: string);
begin
T.Create;
data := s;
end;
а представляешь, если у тебя иерархия из десятка уровней, и нескольких десятков классов? Где-то надо менять, где-то не надо... Веселуха...