Rekord jako parametr funkcji?

Rekord jako parametr funkcji?
MR
  • Rejestracja:prawie 7 lat
  • Ostatnio:8 dni
  • Postów:118
0

Mam rekord składający się z kilkunastu pól różnych typów.
I potrzebuję ten rekord użyć w kliku miejscach.
Więc pomyślałem, czy da się do procedury wysłać adres aktualnego rekordu i tam go wypełnić i zwracać tam gdzie potrzeba.

Tylko że chciałbym aby ten rekord (znaczy jego struktura) był zadeklarowany wewnątrz tej tej jednej centralnej funkcji która będzie wypełniać

Kopiuj
procedure WypełnijDane(var rec : )  <-- jaki typ tutaj? TPracodawca tutaj nie istnieje więc może Pointer?
type  TPracodawca = record
      imie      : string[100];
      nazwisko  : string[100];
      nazwa     : string[200];
      NIP       : string[20];
      REGON     : string[20];
      PESEL     : string[20];
  end;

var Pracodawca : TPracodawca 
begin

//jeśli na wejściu typ Pointer to pewnie trzeba go jakoś rzutować na typ TPracodawca??

//tutaj wypełniamy
end

A tam gdzie potrzebuję tego rekordu, już mogę go utworzyć i dać jako parametr do procedury

Możecie też zaproponować inne sposoby (byle nie podawać 20 parametrów do jednej procedury)

edytowany 1x, ostatnio: flowCRANE
spartanPAGE
  • Rejestracja:około 12 lat
  • Ostatnio:dzień
4

Nie deklaruj tego jako lokalnego dla tej procedury typu.

Kopiuj
type  TPracodawca = record
      imie      : string[100];
      nazwisko  : string[100];
      nazwa     : string[200];
      NIP       : string[20];
      REGON     : string[20];
      PESEL     : string[20];
  end;
  
procedure WypelnijDane(var rec: TPracodawca); 
var Pracodawca : TPracodawca;
begin
end;

w takiej formie śmiga https://ideone.com/yTrIak

Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
2

Tylko że chciałbym aby ten rekord (znaczy jego struktura) był zadeklarowany wewnątrz tej tej jednej centralnej funkcji która będzie wypełniać

Dlaczego?


MR
  • Rejestracja:prawie 7 lat
  • Ostatnio:8 dni
  • Postów:118
0

Bo musiałbym ten rekord zadeklarować na początku unitu, a wygodniej się czyta, kiedy wszystkie używane zmienne są w jednym miejscu.

flowCRANE
I tak powinieneś zrobić, czyli zadeklarować typ danych w miejscu, w którym będzie widoczny, aby dało się normalnie z niego korzystać.
Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
2

Przeskoczenie do definicji oraz z powrotem, o ile nie piszesz w Notatniku albo na kartce papieru, to dosłownie dwa~trzy skróty klawiszowe i max kilkanaście sekund na rzucenie okiem.

W tym wypadku próba utrzymania TPracodawca wewnątrz WypełnijDane byłaby bardzo na siłę, dodatkowo kosztem poprawności typów (tj. konieczności wykorzystania nagiego wskaźnika).

IMHO powinieneś TPracodawca wyrzucić poza procedurę, na górę modułu.


edytowany 3x, ostatnio: Patryk27
MR
  • Rejestracja:prawie 7 lat
  • Ostatnio:8 dni
  • Postów:118
0

a może jakieś inne sposoby?

AK
moim zdaniem też KOMBINUJESZ STRASZNIE
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Tuchów
  • Postów:12175
3

@My Razem: nie wiem dlaczego tak kombinujesz, ale jeśli koniecznie chcesz mieć tę deklarację jako lokalną, to zadeklaruj parametr albo jako beztypowy i zabsolutuj go z lokalną zmienną:

Kopiuj
  procedure DoSomething(var ARecord);
  type
    TSecretRecord = record
      Foo: AnsiChar;
      Bar: UInt8;
    end;
  var
    Secret: TSecretRecord absolute ARecord; // w ten sposób
  begin
    WriteLn(Secret.Foo);
    WriteLn(Secret.Bar);
  end;

var
  Trick: UInt16 = $4137;
begin
  DoSomething(Trick);
  ReadLn();
end.

albo zadeklaruj parametr jako wskaźnik ogólny i przekazuj adres zmiennej z danymi, a następnie zrzutuj:

Kopiuj
  procedure DoSomething(ARecord: Pointer);
  type
    TSecretRecord = record
      Foo: AnsiChar;
      Bar: UInt8;
    end;
  var
    Secret: TSecretRecord;
  begin
    Secret := TSecretRecord(ARecord^); // w ten sposób

    WriteLn(Secret.Foo);
    WriteLn(Secret.Bar);
  end;

var
  Trick: UInt16 = $4137;
begin
  DoSomething(@Trick);
  ReadLn();
end.

Pamiętaj jednak, że takie zabiegi są dopuszczalne i będą działać prawidłowo, ale łatwo się w tym pogubić i stworzyć kod-potworek, którego trudno będzie zrozumieć bez dokumentacji. Ogólnie to prosta droga do spaghetti.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 2x, ostatnio: flowCRANE

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.