Frage

Wie vergleichen Sie zwei Instanzen von Strukturen für die Gleichstellung in Standard-C?

War es hilfreich?

Lösung

C keine Sprach Einrichtungen bietet, dies zu tun -. Sie haben es selbst zu tun und jedes Strukturelement vom Mitglied vergleichen

Andere Tipps

Sie können memcmp(&a, &b, sizeof(struct foo)) zu verwenden versucht sein, aber es kann alle Situationen nicht funktioniert in. Der Compiler kann Ausrichtungspufferraum auf eine Struktur hinzuzufügen, und die Werte an Speicherstellen zu finden in dem Pufferraum liegen, nicht einen bestimmten Wert sein, garantiert.

Aber, wenn Sie calloc verwenden oder memset die volle Größe der Strukturen vor der Verwendung, Sie können tun ein flach Vergleich mit memcmp (wenn Ihre Struktur enthält Zeiger, es wird nur entsprechen, wenn die Adresse der Zeiger die gleiche sind, zeigen).

Wenn Sie es viel tun, würde ich vorschlagen, eine Funktion zu schreiben, die die beiden Strukturen vergleichen. Auf diese Weise, wenn Sie jemals die Struktur ändern müssen Sie nur die Änderungen an einem Ort vergleichen.

Was, wie es zu tun .... Sie müssen einzeln jedes Element vergleichen

Sie können memcmp nicht verwenden, um Strukturen für die Gleichstellung wegen möglichen Zufall Füllzeichen zwischen Feld in structs zu vergleichen.

  // bad
  memcmp(&struct1, &struct2, sizeof(struct1));

Das oben würde für eine Struktur wie folgt ausfallen:

typedef struct Foo {
  char a;
  /* padding */
  double d;
  /* padding */
  char e;
  /* padding */
  int f;
} Foo ;

Sie haben zu verwenden, Mitglied weist Vergleich sicher zu sein.

Beachten Sie memcmp () auf nicht statisch stuctures verwenden, ohne so lange sich Gedanken über Polsterung, da Sie nicht initialisieren alle Mitglieder (auf einmal). Diese ist definiert durch C90:

http://www.pixelbeat.org/programming/gcc/auto_init.html

@ Greg richtig ist, dass eine ausdrückliche Vergleichsfunktionen im allgemeinen Fall schreiben müssen.

Es ist möglich, memcmp zu verwenden, wenn:

  • enthalten die structs keine Gleitkommazahlen Felder, die möglicherweise NaN sind.
  • enthalten die structs keine Polsterung oder die structs (Verwendung -Wpadded mit Klirren dies zu überprüfen) explizit mit memset bei der Initialisierung.
  • initialisiert
  • gibt es keine Elementtypen (wie Windows BOOL), die haben unterschiedliche, aber gleichwertige Werte.

Wenn Sie nicht für eingebettete Systeme programmieren (oder eine Bibliothek zu schreiben, die auf sie verwendet werden könnten), würde ich nicht über einige der Ecke Fälle in dem C-Standard sorgen. Die in der Nähe von vs. far-Zeiger Unterscheidung existiert nicht auf jedem 32- oder 64-Bit-Gerät. Kein Nicht-Embedded-System, die ich kenne hat mehrere NULL Zeiger.

Eine weitere Option ist, um die Gleichheitsfunktionen automatisch zu generieren. Wenn Sie Ihre Struktur Definitionen aus auf einfache Weise legen, ist es möglich, einfache Textverarbeitung verwenden einfache Struktur Definitionen zu handhaben. Sie können libclang für den allgemeinen Fall verwenden -., Da sie die gleiche Frontend wie Clang verwendet, es alle Eckfällen korrekt behandelt (abgesehen von Bugs)

Ich habe keinen Code Generation Bibliothek gesehen. Es scheint jedoch, relativ einfach.

Es ist aber auch der Fall, dass eine solche erzeugte Gleichheitsfunktionen oft würden die falsche Sache auf Anwendungsebene zu tun. Zum Beispiel sollte zwei UNICODE_STRING structs in Windows im Vergleich seicht oder tief?

Es hängt davon ab, ob die Frage, die Sie fragen, ist:

  1. Sind diese beiden Strukturen das gleiche Objekt?
  2. Haben sie den gleichen Wert haben?

Um herauszufinden, ob sie das gleiche Objekt sind, zu vergleichen, Zeiger auf die beiden Strukturen auf Gleichheit. Wenn Sie in der Regel wollen, um herauszufinden, ob sie den gleichen Wert haben haben Sie einen tiefen Vergleich zu tun. Dies beinhaltet alle Mitglieder zu vergleichen. Wenn die Mitglieder Verweise auf andere Strukturen sind, müssen Sie auch in diese Strukturen Rekursion.

In dem speziellen Fall, wo die Strukturen enthalten keine Zeiger Sie eine memcmp tun können einen bitweise Vergleich der Daten in jedem enthalten, ohne dass Sie wissen, was die Daten bedeuten.

Stellen Sie sicher wissen, was ‚gleich‘ für jedes Mitglied bedeutet - es ist offensichtlich, für ints aber subtiler, wenn es um Fließkommawerte oder benutzerdefinierte Typen

.

memcmp nicht vergleichen Struktur, memcmp die binäre vergleicht, und es gibt immer Müll in der Struktur, daher kommt es immer falsch heraus im Vergleich.

Vergleichen Element für Element seiner sicheren und nicht ausfällt.

Wenn die structs nur Primitiven enthalten oder wenn Sie Interesse an strikte Gleichheit sind, dann können Sie etwas tun:

int my_struct_cmp(const struct my_struct * lhs, const struct my_struct * rhs)
{
    return memcmp(lhs, rsh, sizeof(struct my_struct));
}

Wenn Sie jedoch structs enthalten Verweise auf andere Strukturen oder Gewerkschaften dann müssen Sie eine Funktion schreiben, die die Grundelemente richtig und machen Vergleich Anrufe gegen die anderen Strukturen als angemessen vergleicht.

Beachten Sie jedoch, dass Sie verwendet Memset haben sollte (& a, sizeof (struct my_struct), 1), um den Speicherbereich der Strukturen als Teil Ihrer ADT Initialisierung auf Null aus.

, wenn die zwei Strukturen Variable initialied mit calloc oder sie werden mit 0 durch Memset gesetzt, so dass Sie Ihre 2 Strukturen mit memcmp vergleichen kann, und es gibt keine Sorge über Struktur Müll und dies ermöglicht es Ihnen, Zeit zu verdienen

Dieses konforme Beispiel verwendet die #pragma pack Compiler Erweiterung von Microsoft Visual Studio der Strukturelemente möglichst dicht gepackt sind, um sicherzustellen:

#include <string.h>

#pragma pack(push, 1)
struct s {
  char c;
  int i;
  char buffer[13];
};
#pragma pack(pop)

void compare(const struct s *left, const struct s *right) { 
  if (0 == memcmp(left, right, sizeof(struct s))) {
    /* ... */
  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top