Składnia [] dla TBytes i Binary

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:

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)
0

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

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;

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.

0

a sygnatura Encode i Decode ?

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);
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

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?

3

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

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:

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1