Struktur initialisieren/auf null/null zurücksetzen

Lesezeit: 5 Minuten

Benutzeravatar von Hari
Hari

struct x {
    char a[10];
    char b[20];
    int i;
    char *c;
    char *d[10];
};

Ich fülle diese Struktur und verwende dann die Werte. Bei der nächsten Iteration möchte ich alle Felder auf zurücksetzen 0 oder null bevor ich anfange, es wiederzuverwenden.

Wie kann ich das machen? Kann ich benutzen memset oder muss ich alle mitglieder durchgehen und dann einzeln machen?

Benutzeravatar von David Heffernan
David Heffernan

Definieren Sie eine konstante statische Instanz der Struktur mit den Anfangswerten und weisen Sie dann einfach diesen Wert Ihrer Variablen zu, wann immer Sie sie zurücksetzen möchten.

Zum Beispiel:

static const struct x EmptyStruct;

Hier verlasse ich mich auf die statische Initialisierung, um meine Anfangswerte festzulegen, aber Sie könnten einen Struct-Initialisierer verwenden, wenn Sie andere Anfangswerte wünschen.

Dann kannst du jedes Mal um die Schleife herum schreiben:

myStructVariable = EmptyStruct;

  • @David Heffernan: Ist das besser als die Verwendung memset wenn ich nur alles zurücksetzen will 0??

    – hari

    31. Juli 2011 um 19:31 Uhr


  • @hari Ich würde diesen Ansatz selbst bevorzugen. Verwenden memset macht mich schmutzig. Ich ziehe es vor, den Compiler, wo immer möglich, um das Speicherlayout kümmern zu lassen. Genau genommen eine solche Verwendung von memset ist nicht portierbar, aber in der Praxis wäre ich erstaunt, wenn Sie Ihren Code jemals irgendwo kompiliert haben, was wichtig ist. Sie können memset also wahrscheinlich sicher verwenden, wenn Sie es bevorzugen.

    – David Heffernan

    31. Juli 2011 um 19:33 Uhr

  • @hari, es ist konzeptionell besser, da Sie Standardinitialisierungswerte angeben (so etwas wie ein Objektfabrikmuster).

    – Diego Sevilla

    31. Juli 2011 um 19:34 Uhr


  • @cnicutar Ich weiß das. Beachten Sie, dass meine Antwort empfiehlt, memset nicht zu verwenden. Beachten Sie auch den Kommentar, in dem ich auf die Nichtportabilität der Verwendung von Memset als Mittel zur Zuweisung von Nullwerten hinweise. Mein vorheriger Kommentar weist nur darauf hin, dass 0-Bits ausnahmslos Gleitkomma-Nullen entsprechen.

    – David Heffernan

    31. Juli 2011 um 20:19 Uhr


  • @ kp11 Zitat bitte

    – David Heffernan

    15. Oktober 2014 um 5:25 Uhr

Der Weg, so etwas zu tun, wenn Sie modernes C (C99) haben, ist die Verwendung von a zusammengesetztes Literal.

a = (const struct x){ 0 };

Dies ist Davids Lösung etwas ähnlich, nur dass Sie sich keine Gedanken darüber machen müssen, ob Sie eine leere Struktur deklarieren oder ob Sie sie deklarieren sollen static. Wenn Sie die verwenden const Wie ich es getan habe, steht es dem Compiler frei, das zusammengesetzte Literal gegebenenfalls statisch im Nur-Lese-Speicher zuzuweisen.

  • Wie alle Optimierungen ist dies vollständig vom Compiler abhängig, sodass Sie überprüfen müssen, was Ihr Compiler produziert. Bei modernen Compilern “normalerweise” nicht, diese können Initialisierungen sehr gut verfolgen und tun nur das Notwendige, nicht mehr. (Und denken Sie nicht, dass solche Dinge Probleme sind, bevor Sie eine echte Verlangsamung messen. Normalerweise sind sie es nicht.)

    – Jens Gustedt

    17. Juni 2014 um 11:59 Uhr

  • “Fehlender Initialisierer”-Warnungen sind wirklich falsch. Die C-Norm schreibt genau vor, was dann passieren muss, und sieht das vor { 0 } als Standardinitialisierer. Schalten Sie diese Warnung aus, es ist ein falscher Fehlalarm.

    – Jens Gustedt

    5. April 2015 um 16:00 Uhr

  • Ist das “const” wirklich notwendig? Sicherlich könnte der Compiler es richtig optimieren, da es sich um ein Literal handelt, das nur für diese Zuweisung verwendet wird.

    – Sam Watkins

    12. November 2015 um 10:09 Uhr

  • @JensGustedt Wird diese Typumwandlung wirklich benötigt? Kann ich das nicht so schreiben? struct xa = (const){0};

    – Patrick

    18. Februar 2017 um 14:11 Uhr


  • @Patrick, obwohl die Syntax ähnlich ist, ist dies keine Umwandlung, sondern ein “zusammengesetztes Literal”. Und Sie verwechseln Initialisierung und Zuweisung.

    – Jens Gustedt

    18. Februar 2017 um 20:31 Uhr

Besser als alles oben Genannte ist es, die Standard-C-Spezifikation für die Strukturinitialisierung zu verwenden:

struct StructType structVar = {0};

Hier sind alle Bits Null (immer).

  • Ich glaube nicht, dass Sie das jedes Mal um eine Schleife herum tun können

    – David Heffernan

    31. Juli 2011 um 19:35 Uhr

  • Das soll tatsächlich funktionieren. Aber leider beschweren sich gcc & g++ darüber. gcc generiert Warnungen, während g++ einen Fehler generiert. Ich weiß, dass gcc & g++ daran schuld sind (sie sollten der Standard-C-Spezifikation folgen), aber dennoch ist es für eine gute Portabilität zwingend erforderlich, eine solche Einschränkung zu berücksichtigen.

    – Cyan

    10. März 2015 um 13:00 Uhr


  • @Cyan Sie können verwenden {} in C++. Die gcc-Entwickler scheinen unsicher, ob C++ unterstützen soll {0} und ich bin mit diesem Teil des Standards selbst nicht vertraut.

    – Matthäus Lesen

    24. März 2015 um 16:37 Uhr

  • @Matthew: Ja, eigentlich habe ich memset() verwendet, weil es zu viele Portabilitätsprobleme gab {0} oder {}. Ich bin mir nicht sicher, ob die C- und C++-Standards zu diesem Thema klar und synchron sind, aber Compiler sind es anscheinend nicht.

    – Cyan

    25. März 2015 um 7:27 Uhr

  • geht das in so einem fall? struct StructType structVar = malloc (sizeof(StructType)); structVar ={0}

    – Sam Thomas

    13. Juni 2018 um 19:03 Uhr

In C ist es üblich, den Speicher für a auf Null zu setzen struct verwenden memset:

struct x myStruct;
memset(&myStruct, 0, sizeof(myStruct));

Technisch gesehen glaube ich nicht, dass dies portabel ist, weil es davon ausgeht, dass die NULL Ein Zeiger auf einer Maschine wird durch den ganzzahligen Wert 0 dargestellt, aber er wird häufig verwendet, da dies auf den meisten Maschinen der Fall ist.

Wenn Sie von C zu C++ wechseln, achten Sie darauf, diese Technik nicht für jedes Objekt anzuwenden. C++ macht dies nur für Objekte ohne Mitgliedsfunktionen und ohne Vererbung zulässig.

Benutzeravatar von Rudy Velthuis
Rudy Velthuis

Wenn Sie einen C99-kompatiblen Compiler haben, können Sie verwenden

mystruct = (struct x){0};

Andernfalls sollten Sie tun, was David Heffernan geschrieben hat, dh erklären:

struct x empty = {0};

Und in der Schleife:

mystruct = empty;

Sie können verwenden memset mit der Größe der Struktur:

struct x x_instance;
memset (&x_instance, 0, sizeof(x_instance));

Benutzeravatar von Archmede
Archmed

Ich glaube, Sie können einfach die leere Menge zuweisen ({}) zu Ihrer Variablen.

struct x instance;

for(i = 0; i < n; i++) {
    instance = {};
    /* Do Calculations */
}

  • Dies ist kein gültiges C, nicht einmal C99. Es muss ein zusammengesetztes Literal sein, wie in JensGustedts Antwort oben.

    – Anders

    31. Oktober 2020 um 0:11 Uhr

1421610cookie-checkStruktur initialisieren/auf null/null zurücksetzen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy