Porównywanie tablic

0

W jaki sposób porównać tablice? Jedna jest dynamiczna, druga jest otwarta, więc operator = odpada. Próbowałem też CompareMem(), ale nie działą dobrze w tym przypadku. Oczywiście, mogę zrobić pętlę po wszystkich itemach, ale chciałbym tego uniknąć.

0

Kombinowałem na różne sposoby i u mnie działa w ten sposób:

if CompareMem(@A[0], @B[0], SizeOf(A)) then // równe...

gdzie:
A - tablica statyczna
B - tablica dynamiczna

Tylko nie wiem czemu SizeOf(B) zwraca zawsze 4 tak jakby podawał tylko rozmiar wskaźnika... ale to przecież nie jest wskaźnik (...?)
Tak czy siak trzeba podać SizeOf(A) i wtedy działa. Tzn. przy SizeOf(B) też, ale wtedy porównuje tylko pierwsze 4 bajty.

0

Tylko nie wiem czemu SizeOf(B) zwraca zawsze 4 tak jakby podawał tylko rozmiar wskaźnika... ale to przecież nie jest wskaźnik (...?)

To jest wskaznik. Tablice dynamiczne i stringi (nie ShortString) sa wskaznikami do miejsc w pamieci gdzie znajduja sie wlasciwe dane (a oprocz tego takie informacje jak liczba elementow tej tablicy oraz w przypadku stringow licznik referencji).

0

czemu SizeOf(B) zwraca zawsze 4 tak jakby podawał tylko rozmiar wskaźnika... ale to przecież nie jest wskaźnik (...?)

Owszem jest.

Thenkles, jeśli porównujesz np. tablicę shortstringów (array of string[rozmiar(<=255)]) to i tak będziesz musiał leciec po itemach, bo poza końcem każdego ciągu znaków znajdują się zawsze jakieś randomowe wartości, które zostaną porównane, przez comparemem. Co innego, gdy tablica ma zawsze 100% wypełnienie danymi.

0

Na razie zrobiłem pętelkę po itemach i działa nieźle, chociaż to takie trochę nieeleganckie :-P. Sprawdzę potem jeszcze raz, czy comparemem() działa i pewnie podmienię (problemów z tymi stringami nie będzie, bo tablica jest typu cardinal). Dzięki za odpowiedzi [browar].

0

ja używam Length(tablica) i działa:D

0

Ja zaproponuję takie coś:
A, B - tablice (dynamiczne)

function Rozne(var A, var B): Boolean;
begin
  if (Length(A) <> Length(B)) or (SizeOf(A[0]) <> SizeOf(B[0])) then
    Result := True
  else
    Result := CompareMem(@A[0], @B[0], Length(A) * SizeOf(A[0]));
    // możliwe, że będzie działać CompareMem(A, B, Length(A) * SizeOf(A[0]));
end;

Nie jestem pewny, czy się skompiluje (przez parametry formalne funkcji), ale chodziło o ogólny sposób rozwiązania.

// EDITED:
Misiekd: lepiej? Nie zabezpiecza to przed porównywaniem różnych typów, których rozmiary są takie same (czyli np. Longint i Pointer, a w związku z tym ostatnim również AnsiString etc.), ale - powtarzam - chodziło o ogólny sposób. Aby mieć pewność, co do zgodności typów, zapraszam do RTTI. Funkcja ma jeszcze jedną wadę - nie sprawdza, czy tablica w ogóle została zaalokowana (czy istnieje element A[0] bądź B[0]) - należy dodać warunek, bo program może się wykrzaczyć (AV bądź Range Error).

0
Pociech napisał(a)

ja używam Length(tablica) i działa:D

a co to zwraca? Ano ilość elementów w tablicy a nie ile zajmuje tablica, a w CompareMem ważne jest ile pamięci zajmuje tablica

0

A jeśli wiesz ile zajmuje jedna komórka tablicy to się chyba da policzyć...

0

ten wątek ma 22 miesiace, nie nudzi sie wam ?

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