Initialisieren einer Struktur auf 0

Lesezeit: 5 Minuten

Benutzeravatar von Daan Timmer
Dan Timmer

Wenn ich eine Struktur wie diese habe:

typedef struct
{
    unsigned char c1;
    unsigned char c2;
} myStruct;

Was wäre der einfachste Weg, diese Struktur auf 0 zu initialisieren? Würde folgendes reichen?

myStruct _m1 = {0};

oder müsste ich jedes Mitglied explizit auf 0 initialisieren?

myStruct _m2 = {0,0};

  • Hinweis: Wenn die Struktur Füllbytes hat (aufgrund der Ausrichtung), garantiert keines von beiden, dass sie initialisiert werden. Es kann wichtig sein, wenn die Struktur auf einen externen Speicher, ein Netzwerk oder einen Vergleich mit geschrieben wird memcmp. In solchen Fällen sollte man verwenden memset.

    – Jakow Galka

    29. Januar 2021 um 3:18 Uhr


Benutzeravatar von Alok Save
Alok Speichern

Das erste ist am einfachsten (erfordert weniger Tippen) und es funktioniert garantiert, alle Mitglieder werden darauf eingestellt 0[Ref 1].
Der zweite ist besser lesbar.

Die Wahl hängt von der Benutzerpräferenz ab oder von derjenigen, die Ihr Codierungsstandard vorschreibt.

[Ref 1] Referenz C99 Standard 6.7.8.21:

Wenn es weniger Initialisierer in einer in geschweiften Klammern eingeschlossenen Liste gibt als Elemente oder Mitglieder eines Aggregats oder weniger Zeichen in einem Zeichenfolgenliteral, das zum Initialisieren eines Arrays bekannter Größe verwendet wird, als Elemente im Array vorhanden sind, muss der Rest des Aggregats implizit genauso initialisiert werden wie Objekte mit statischer Speicherdauer.

Gute Lektüre:

C und C++ : Teilinitialisierung der automatischen Struktur

  • Außerdem verwende ich = {}; Ich bin mir aber nicht sicher, ob das gültig ist.

    – Wilhelm Entriken

    19. März 2015 um 21:09 Uhr

  • @FullDecent leere Klammern für die Initialisierung ist eine GNU-Erweiterung.

    – a3f

    12. September 2015 um 18:13 Uhr


  • @alias65536 Die Frage ist mit C und nicht mit C++ gekennzeichnet.

    – a3f

    21. Juli 2017 um 17:27 Uhr

  • Ich habe eine Fehlermeldung erhalten: „Fehlende Klammern um den Initialisierer [-Werror=missing-braces]” Wahrscheinlich wegen eines Member-Arrays :/

    – jaques-sam

    14. Februar 2018 um 11:07 Uhr


  • @Edenia. Ich stimme dir nicht zu. Ich weiß schon was foo = {0} meint. Wenn ich sähe foo = ZERO_FULLmüsste ich nach der Definition von ZERO_FULL suchen.

    – Andrew Bainbridge

    24. Juli 2018 um 14:51 Uhr


Benutzeravatar von Basile Starynkevitch
Basile Starynkevitch

Wenn die Daten eine statische oder globale Variable sind, werden sie standardmäßig mit Nullen gefüllt, also deklarieren Sie sie einfach myStruct _m;

Wenn es sich bei den Daten um eine lokale Variable oder eine Heap-zugewiesene Zone handelt, löschen Sie sie mit memset wie:

memset(&m, 0, sizeof(myStruct));

Aktuelle Compiler (z. B. neuere Versionen von gcc) optimieren das in der Praxis recht gut. Dies funktioniert nur, wenn alle Nullwerte (einschließlich Nullzeiger und Gleitkomma-Null) als reine Nullbits dargestellt werden, was auf allen mir bekannten Plattformen zutrifft (aber die C Standard erlaubt Implementierungen, wo dies falsch ist; Mir ist keine solche Implementierung bekannt).

Könntest du vielleicht codieren myStruct m = {}; oder myStruct m = {0}; (auch wenn das erste Mitglied von myStruct ist kein Skalar).

Mein Gefühl ist das mit memset für lokale Strukturen ist die beste und vermittelt besser die Tatsache, dass zur Laufzeit etwas getan werden muss (während globale und statische Daten normalerweise als zur Kompilierzeit initialisiert verstanden werden können, ohne dass zur Laufzeit Kosten entstehen).

  • Es gibt keine Garantie dafür, dass alle Bytes der Struktur auf gesetzt werden 0 entspricht der Initialisierung aller Strukturmitglieder mit 0 obwohl. Auf vielen Plattformen wird dies zutreffen, aber nicht überall.

    – Sander DeDycker

    22. Juni 2012 um 7:55 Uhr

  • Können Sie ein Beispiel nennen, Sander? Echte Neugier. (Offensichtlich bedeutet nicht allgemeingültig nicht unbedingt, dass es eine leicht zu erklärende Ausnahme gibt, aber wenn es eine gibt …)

    – Steven Fischer

    22. Juni 2012 um 7:57 Uhr

  • Das C Der Standard erlaubt es, dass der Nullzeiger (oder eine Null-Gleitkommazahl) im Speicher durch etwas anderes als nur Null-Bits dargestellt wird. Sehr wenige und seltsame Implementierungen tun dies (ich kann keine nennen).

    – Basile Starynkevitch

    22. Juni 2012 um 7:59 Uhr


  • -1 finden Sie die Initialisierung, nach der das OP fragt, vielleicht hässlich, aber es ist genau das, was der Standard vorsieht und das von allen Compilern leicht optimiert werden kann. Dann das Formular {} ist kein gültiges C, sondern nur in C++ verfügbar.

    – Jens Gustedt

    22. Juni 2012 um 8:08 Uhr

  • @Steven: Mir fallen nur obskure und/oder alte Plattformen ein. Die C-FAQ enthält eine Liste von Plattformen, die eine hatten NULL Zeiger das war noch nicht alles 0 Bits: c-faq.com/null/machexamp.html. Und dann besteht die Möglichkeit, dass die Plattform nicht IEEE 754 verwendet, um Gleitkommawerte darzustellen, sondern eine andere Darstellung verwendet, die kein All hat 0 bisschen 0.0 wert – aber zugegebenermaßen kenne ich keine solche Plattform.

    – Sander DeDycker

    22. Juni 2012 um 8:32 Uhr

Benutzeravatar von dirkgently
dirkly

Siehe §6.7.9 Initialisierung:

21 Wenn es weniger Initialisierer in einer geschweiften Liste gibt als Elemente oder Mitglieder eines Aggregats oder weniger Zeichen in einem String-Literal, das zum Initialisieren eines Arrays bekannter Größe verwendet wird, als Elemente im Array vorhanden sind, der Rest des Aggregats sollen implizit genauso initialisiert werden wie Objekte mit statischer Speicherdauer.

Also, ja, beide funktionieren. Beachten Sie, dass in C99 auch eine neue Art der Initialisierung, die so genannte designierte Initialisierung, verwendet werden kann:

myStruct _m1 = {.c2 = 0, .c1 = 1};

  • Vor allem ist dies bereits C89: open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf#page=139 (Wichtig für bestimmte Signalverarbeitungsziele)

    – Tobias

    2. Juli 2019 um 14:55 Uhr


  • Beachten Sie jedoch, dass es für {0} intuitiv funktioniert, aber nicht so klar, wenn Sie beispielsweise {1} verwenden. Es ist leicht zu glauben, dass es alles auf 1 setzen würde, aber es wird nur das erste auf 1 setzen und den Rest implizit initialisieren, sodass Sie wahrscheinlich mit 1,0 enden.

    – Zitrax

    12. Februar 2021 um 11:39 Uhr

Benutzeravatar von pgibbons
gibbons

Ich dachte auch, das würde funktionieren, aber es ist irreführend:

myStruct _m1 = {0};

Als ich das probiert habe:

myStruct _m1 = {0xff};

Es wurde nur das 1. Byte gesetzt 0xffdie restlichen wurden auf gesetzt 0. Ich würde es mir also nicht angewöhnen, das zu verwenden.

1424460cookie-checkInitialisieren einer Struktur auf 0

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

Privacy policy