Składnia [] dla TBytes i Binary

Składnia [] dla TBytes i Binary
JA
  • Rejestracja: dni
  • Ostatnio: dni
0

Cześć
pytanie początkującego
dlatego autor tego kodu nie korzysta ze zmiennych, tylko dodatkowo używa "indeksu", czemu ma służyć taki sposób przekazywania zmiennych do funkcji:

Kopiuj
Plaintext: Binary;
Ciphertext: TBytes;
...
SetLength(Ciphertext, Length(Plaintext));
Encode(Plaintext[1], Ciphertext[0], Length(Plaintext));
FillChar(Plaintext[1], Length(Plaintext), 0);
Decode(Ciphertext[0], Plaintext[1], Length(Ciphertext)
KamilAdam
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Silesia/Marki
  • Postów: 5550
0

Nie znam pascala ale zakladam ze Ciphertext i Plaintext to tablice (lub stringi) a funkcja przyjmuje pojedynczy element (char?) a nie tablice

JA
  • Rejestracja: dni
  • Ostatnio: dni
0
KamilAdam napisał(a):

Nie znam pascala ale zakladam ze Ciphertext i Plaintext to tablice (lub stringi) a funkcja przyjmuje pojedynczy element (char?) a nie tablice

Plaintext: Binary;
Ciphertext: TBytes;

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12269
2

Zapewne dlatego korzysta z indeksu, bo parametry zadeklarowane są jako beztypowe. Typu nie podaje się po to, aby można było przekazać cokolwiek. Przykładem jest FillChar — jej pierwszy parametr zadeklarowany jest jako var X. Czyli w skrócie, jest to coś jak cukier składniowy, pozwalający ominąć silne typowanie, dać nieco generyczności, a że całość i tak sprowadza się do przekazania pointera, to zapewnia nieco krótszy zapis (jeden znak mniej!).

W przykładzie, który podałeś, przekazywane są po prostu adresy konkretnych komórek macierzy, tyle że tego nie widać, bo nie ma nigdzie @ — pozyskanie adresu danych wykonywane jest niejawnie. Ot taka kretyńska składniowa abstrakcja, mieszająca w głowie.

KamilAdam
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Silesia/Marki
  • Postów: 5550
0

a sygnatura Encode i Decode ?

JA
  • Rejestracja: dni
  • Ostatnio: dni
0
KamilAdam napisał(a):

a sygnatura Encode i Decode ?

procedure Encode(const Source; var Dest; DataSize: Integer);
procedure Decode(const Source; var Dest; DataSize: Integer);
abrakadaber
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6610
3

chodzi o to, że do metody musisz przekazać początek bufora, którymi w tym wypadku są pierwsze elementy tablicy natomiast nie wiem co to jest Binary bo Delphi 10.2 tego nie zna

JA
  • Rejestracja: dni
  • Ostatnio: dni
0
abrakadaber napisał(a):

chodzi o to, że do metody musisz przekazać początek bufora, którymi w tym wypadku są pierwsze elementy tablicy natomiast nie wiem co to jest Binary bo Delphi 10.2 tego nie zna

faktycznie, Binary to RawByteString
przekazuje początek bufora, mimo że operacje są na całym?

abrakadaber
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6610
3

Tak, zauważ że dodatkowo musisz jeszcze przekazać długość bufora wejściowego

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12269
1
jastu napisał(a):
procedure Encode(const Source; var Dest; DataSize: Integer);
procedure Decode(const Source; var Dest; DataSize: Integer);

Tutaj po prostu przekazywane są dwa adresy, czyli na początek bloku źródłowego i docelowego, a także liczba bajtów do przetworzenia. Równie dobrze te sygnatury mogłyby wyglądać tak:

Kopiuj
procedure Encode(ASource, ADest: Pointer; ADataSize: Integer);
procedure Decode(ASource, ADest: Pointer; ADataSize: Integer);

i efekt byłby identyczny, tyle że wszystko byłoby klarowne — funkcja chce adresów na dowolne dwa bloki danych (stąd nietypowany wskaźnik), w wywołaniu jawnie trzeba by użyć operatora pozyskania adresu (lub po prostu przekazać zmienną wskaźnikową).

Podobną papkę z mózgu robi funkcja Move, bo też ma parametry beztypowe. Mając wskaźniki na dane, można łatwo spaść z rowerka, podając je do Move — jeśli zgubi się dereferencję przy którymś, to albo zostanie skopiowany adres pointera zamiast danych (bug trudny do wychwycenia), albo dane zostaną skopiowane do zmiennej wskaźnikowej, zamiast w miejsce, na które ten wskazuje. Drugi przypadek to jeszcze większe bagno, bo jeśli nie poleci błąd segmentacji, to nadpisze się inne zmienne lokalne w ramce stosu i wyjdą z tego banany.

Moja opinia jest taka, że parametry beztypowe to zło i należy ich unikać. Lepiej musieć napisać tę małpkę przed nazwą zmiennej, niż później tracić masę czasu na szukanie bugów. Mimo wszystko warto wiedzieć jak to wszystko działa, bo w przyszłości na pewno będzie się miało z tym do czynienia.

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.