Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Delphi,Описание процедуры (http://forum.oszone.net/showthread.php?t=30632)

Roman Go 29-01-2003 19:08 209420

Как описать процедуру, чтобы в ней были такие параметры, которые можно было бы не задавать при вызове данной процедуры или функции?:help:

[s]Исправлено: Roman Go, 19:12 29-01-2003[/s]

vasketsov 29-01-2003 20:07 209421

Roman Go
function x(Dummy:Integer=0):Boolean; - покатит?

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

fLANkeR 07-02-2003 18:38 209422

Roman Go
нужно делать несколько функций которые будет прекрывать друг друга

Хотя наверное можно и по другому :)

[s]Исправлено: fLANkeR, 18:40 7-02-2003[/s]

Crew 11-02-2003 00:23 209423

#include <stdio.h>
#include <stdarg.h>

/* calculate sum of a 0 terminated list */
void sum(char *msg, ...)
{
  int total = 0;
  va_list ap;
  int arg;
  va_start(ap, msg);
  while ((arg = va_arg(ap,int)) != 0) {
     total += arg;
  }
  printf(msg, total);
  va_end(ap);
}

int main(void) {
  sum("The total of 1+2+3+4 is %d\n", 1,2,3,4,0);
  return 0;
}

Пример из Borlandc 3.1

Dread Knight 20-02-2003 05:54 209424

Crew
человек же ведь ясно сказал - Delphi, а значит Паскаль
так фига ты ему С суешь? А вообще vasketsov правильно сказал

Ork Yason 20-02-2003 10:15 209425

vasketsov
я так понял ему нужна перегрузка...
что було:
Цитата:

function x(Dummy : Integer=0):Boolean;
и function x():Boolean;
и function x(Dummy : Integer; Dummy2 : Integer):Boolean;
Roman Go
юзай перегрузку...
overload тебе надо... после опредления процедуры пишется... посмотри в справке...
будет типа того:
function x(Dummy : Integer=0):Boolean;
и function x():Boolean; overload;
и function x(Dummy : Integer; Dummy2 : Integer):Boolean; overload;
за ответ точно не уверен, ибо у нас по другому и проще ;)

Guest 20-02-2003 17:38 209426

Ork Yason
Перегрузка к опциональным параметрам отношения не имеет.

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

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

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

vasketsov

Ork Yason 21-02-2003 09:41 209427

Guest
Цитата:

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

А у вас по другому и проще - это где? Ибо и в сях
в них самых...
это я тоже про перегрузку...

Roman Go 21-02-2003 17:55 209428

Цитата:

я понял товарищу нужна перегрузка...
он придет и скажет нам, что ему из вышесказанного нужно...
Ну блин
Вообще я попробовал и overload и как Васкетсов сказал, для меня более удобной кажется перегрузка и для решения моей задачи она более всего подходит. Хотя и при том и при другом способе можно не задавать какие-то переменные (о чем я и спрашивал)

Код:

procedure summm2(var m:real; a,b,c:integer; d:integer=0; f:integer=0);
...
procedure Tform1.summm2(var m:real; a,b,c,d,f:integer);
 *begin
 * *m:=(a+b+c+d)*f;
 *end;

Дело в том что если не указать переменную f, то она примет значение равное нулю и при любых значениях a,b,c,d ответ будет ноль, что может быть не всегда правильно, учесть этот недостаток можно с помощью перезагрузки, проще говоря пищется несколько процедур с одинаковым именем, но с разным содержанием, а какая будет выполняться определяется по заданным параметрам, и если я допустим f же не задам то я могу выполнять другое арифметическое действие, которое описанно в соответствующей процедуре.

Код:

procedure summm(a,b,c:integer; var m:integer); overload;
 *private
 * *{ Private declarations }
 * *procedure summm(a,b:integer; var m:integer); overload;
...

impletation
{$R *.DFM}

procedure tform1.summm(a,b:integer; var m:integer);
 *begin
 * *m:=a+b;
 *end;
procedure tform1.summm(a,b,c:integer; var m:integer);
 *begin
 * *m:=a+b+c;
 *end;

procedure TForm1.Button1Click(Sender: TObject);
 * *var q:integer;
begin
 *summm(5,5,5,q); *{q=15}
 *summm(5,5,q); *{q=10}
end;

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

Хотя здесь тоже есть свое недостатки, допустим у меня есть процедура, выходными данными которыми является несколько переменных (a,b,c) если мне нужно чтобы присутствовала только одна переменная допустим "с", "b" или "a", то тут может появиться проблема, как указать так чтобы находилась именно нужная мне Короче говоря в некоторых случаях проще не париться а написать еще одну процедуру просто с другим именем и все, проще говоря каждому самому решать каким путем идти
ну блин

[s]Исправлено: Roman Go, 17:57 21-02-2003[/s]

Crew 23-02-2003 01:16 209429

Dread Knight
Цитата:

Crew
человек же ведь ясно сказал - Delphi, а значит Паскаль
так фига ты ему С суешь? А вообще vasketsov правильно сказал
Действительно, но можно было и поспокойней ответить.

А вот меня раньше очень вопрос донимал, но потом я забыл про него -  Можно ли написать dll на С++ с функцией, аналогичной той, что я привел, а потом вызывать ее из Delphi и чтобы она продолжала работать с переменным количеством аргуиментов?

vasketsov 23-02-2003 09:05 209430

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

В случае __cdecl, как в твоем случае, имхо нереально. Но выход есть: передать первым параметром число последующих и описать функцию как __stdcall.

Crew 23-02-2003 22:18 209431

Цитата:

В случае __cdecl, как в твоем случае, имхо нереально. Но выход есть: передать первым параметром число последующих и описать функцию как __stdcall.
Несмотря на обилие прочитанной литературы, единственное, что я знаю, что есть вызов Аля Паскаль и Аля Си, которые отличаются друг от друга порядком передачи своих параметров
Если не сложно в двух словах что это за __cdecl и чем __stdcall лучше в данном случае.


А без указания точного количества параметров значит не получится :down:, а жаль.

Ork Yason 24-02-2003 09:04 209432

vasketsov
Crew
я тогда чего-то не догоняю...
получается что делфя не полностью совместима с винАпи?

vasketsov 24-02-2003 11:52 209433

Crew
Способов передачи параметров много, более того, не все имеют названия.

1) Стек может очищаться как вызывающей функцией (__cdecl), так и вызываемой (_stdcall). Если функция вызывается часто, выгоднее, чтоб она сама очищала стек (почти весь WINAPI такой). Естественно, стек может очищать только та сторона, которая знает о размере переданных параметров.

2) Параметры могут передаваться в стеке в прямом и в обратном порядке.

3) Переметры могут передаваться не только через стек, но и через регистры (один и более, часто EAX или EAX/EDX). Сюда относится __fastcall и обычные паскалевские функции с небольшим числом стандартных аргументов.

4) Есть еще очень интересный способ передачи параметров, используемый при переходе в NT-системах в режим ядра. Все параметры передаются через один регистр, а именно, в него кладется указатель на первый параметр __stdcall-овской функции. Но без знания языка ассемблера такое самому руками, естественно, не написать, по крайней мере, мне не известен компилятор, понимающий такую модель вызова.

На самом деле Delphi Compiler знает много методов вызовов, так что попробую про них почитать во встроенной справке.

Ork Yason
Цитата:

получается что делфя не полностью совместима с винАпи?
Нифига подобного.

RIKO 09-03-2003 00:04 209434

А ни как если не использовать
встроенный ASM.


Время: 04:45.

Время: 04:45.
© OSzone.net 2001-