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ąć.
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.
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).
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.
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].
ja używam Length(tablica) i działa:D
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).
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
A jeśli wiesz ile zajmuje jedna komórka tablicy to się chyba da policzyć...
ten wątek ma 22 miesiace, nie nudzi sie wam ?