Ergebnis 1 bis 14 von 14

Thema: [Delphi] Records auf Gleichheit prüfen

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Loesungsansatz 1:

    function is_equal(a,b:Record): Boolean;
    begin
    is_equal := true;
    is_equal := is_equal or ( a.x = b.x );
    is_equal := is_equal or ( a.y = b.y );
    is_equal := is_equal or ( a.z = b.z );
    ..
    end;

    Loesungsansatz 2: Du verwendest statt Records Objekte und bietest obige Funktion als Methode an.

  2. #2
    Zitat Zitat von Ineluki Beitrag anzeigen
    Loesungsansatz 1:

    function is_equal(a,b:Record): Boolean;
    begin
    is_equal := true;
    is_equal := is_equal or ( a.x = b.x );
    is_equal := is_equal or ( a.y = b.y );
    is_equal := is_equal or ( a.z = b.z );
    ..
    end;
    Genau das wollte ich eigentlich verhindern.
    Ich wollte es ganz gerne unabhängig von der Struktur des Records lösen.
    So muss ich ja jedes Mal, wenn sich die Struktur des Records ändert, auch die Funktion ändern.

    Dass mit den Objekten muss ich mir mal genauer anschauen, da ich noch nie mit Objekten gearbeitet habe und die Records leider vorgegeben worden sind (ist eine Aufgabe für die Schule).

  3. #3
    Wenn du es mit einer sich aendernden, nicht anpassbaren Struktur zu tun hast, dann wird es etwas schwierig. Andererseits koenntest du eine Variable fuer die Groesse in die Records aufnehmen. Zur Verarbeitung bieten sich Zeigerarithmetik und Schleifen an, falls ihr das schon angesprochen hattet.

  4. #4
    Ok, es gibt noch eine fiese Quick n' Dirty Methode fuer Records.
    Allerdings nur, wenn sie wirklich von absolut dem selben Typ sind und keinerlei dynamische Strukturen aufweisen.

    Dann koenntest du direkt auf binaere Identitaet pruefen mittels

    Unit Sysutils
    function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;

    Du machst die Funktion

    function is_equal(R1, R2: Record): Boolean;
    begin
    is_equal := CompareMem( @R1, @R2, SizeOf(Record) )
    end;

    Damit ueberpruefst du, ob der Speicherinhalt an den Speicherstellen @R1 und @R2 innerhalb einer Laenge von SizeOf(Record) Bytes identisch ist. SizeOf(Record) liefert gerade die Laenge deines Record-Typs in Byte.
    Das ganze geht natuerlich massiv in die Hose, wenn der Record eine dynamische Laenge besitzt (wie es z.B. manche Datentypen der Windows-API haben) und pro Instanz demnach unterschiedlich lang sein kann.

    Ausserdem gibts natuerlich Probleme, wenn dein Record selber Zeiger enthaellt. MemComp ueberprueft naemlich durch den byteweisen Vergleich, ob die Addressen, auf die die Zeiger zeigen, identisch sind, nicht, ob deren Inhalt identisch ist. Nehmen wir also an, du haettest einen Record R1 und einen Record R2, die beide einen typisierten Pointer P besitzen, (der auch auf alloziierten Speicher zeigt). Dann wuerde R2.P^ := R1.P^; eine Valide Zuweisung sein, indem der Inhalt von R2.P durch den Inhalt von R1.P ersetzt wird. Dennoch zeigen R1.P und R2.P auf unterschiedliche Speicherbereiche (Addressen), und MemComp schlaegt damit als binaerer Vergleich fehl, obwohl der Inhalt beider Zeiger (aber nicht beide Zeiger) identisch sind.

    Geändert von Ineluki (14.02.2010 um 06:50 Uhr)

  5. #5
    Zitat Zitat von Brauni90 Beitrag anzeigen
    Wenn du es mit einer sich aendernden, nicht anpassbaren Struktur zu tun hast, dann wird es etwas schwierig. Andererseits koenntest du eine Variable fuer die Groesse in die Records aufnehmen. Zur Verarbeitung bieten sich Zeigerarithmetik und Schleifen an, falls ihr das schon angesprochen hattet.
    Ich weiß, was Schleifen und Zeiger sind. Ist ja nicht so, dass ich schon seit Jahren programmiere und nun ins vierte Semester meiner Ausbildung komme

    Ich hab mir ja so eine Bibliothek unter C geschrieben und wollte sie jetzt nach Delphi übertragen, da ich nun solche Funktionen für eine Seminaraufgabe brauche. Unter C geht es ja mit if (struct1 == struct2), nur leider wohl unter Delphi nicht.

    Ok, da man wohl unter Delphi mit dreckigen und unsicheren Tricks arbeiten muss, dann lass ich wohl diese Funktionen raus, die von dieser Funktion abhängig sind. Je weniger murks da drinnen steht, desto weniger können sie danach fragen ^^

  6. #6
    Was hast du erwartet ?

    Du wusstest schon selber, dass es keinen Vergleichsoperator fuer Records gibt.
    Ergo gibt es nur 2 Moeglichkeiten:

    a) Du vergleichst alles per Hand.

    Das wolltest du aber nicht, da du dann, wenn du den Record aenderst, die Vergleichsfunktion anpassen musst.

    b) Du pruefst die Speicherbereiche auf identischen Inhalt.

    Das ist dir aber auch nicht recht, da es dir zu "dreckig" ist.

    Nur andere Moeglichkeiten gibt es nun einmal nicht. Selbst die eingebauten Identitaetsoperatoren in C arbeiten auf diesem Prinzip (idR nach b, wobei die natuerlich schon vom compiler her auf Typgleichheit testen koennen).

    Das ganze ist also kein "Delphi"-Problem, wie du es darstellst, sondern einfach, dass du etwas selbst implementieren musst, weil dir der syntaktische Zucker fehlt.

    PS: Ganz nebenbei, ein "Danke" haette dir auch nicht geschadet.

    Geändert von Ineluki (14.02.2010 um 09:17 Uhr)

  7. #7
    Zitat Zitat von Ineluki Beitrag anzeigen
    Was hast du erwartet ?
    Hätte ja angehen können, dass es dafür eine spezielle Funktion in irgendeiner der Delphi Units gibt oder was weiß ich.

    Zitat Zitat von Ineluki Beitrag anzeigen
    PS: Ganz nebenbei, ein "Danke" haette dir auch nicht geschadet.
    Als ob darauf heutzutage noch großartig Wert draufgelegt wird ...

    Danke

    (warum auch immer diese aggressive Tonlage? ...)

  8. #8
    Zitat Zitat von Whiz-zarD Beitrag anzeigen
    Hätte ja angehen können, dass es dafür eine spezielle Funktion in irgendeiner der Delphi Units gibt oder was weiß ich.
    Und wie hätte diese bitte aussehen sollen, wenn sie keinen Speichervergleich macht? RTTI? Soviel aufwand, nur um zwei Records zu vergleichen?

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •