2012-11-14 6 views
8

fand ich einen Code als ähnliche Demo implementiert unten ..Was sind die Vorteile unbenannter Strukturen/Vereinigungen in C?

struct st 
{ 
int a; 
struct 
{ 
int b; 
}; 
}; 

6,58 Unbenannt struct/union Felder gezeigt in structs/unions

von ISO C11 erlaubt As.

Aber was sind Vorteile davon?

Da ich sowieso die Datenelemente in gleicher Weise zugreifen können, wie

int main() 
{ 
struct st s; 
s.a=11; 
s.b=22; 
return 0; 
} 

auf gcc 4.5.2 mit,

gcc -Wall demo.c -o demo 

und keine Fehler,

+0

mögliche Duplikate von [Was sind anonyme Strukturen und Vereinigungen nützlich in C11?] (Http://stackoverflow.com/questions/8932707/what-are-anonymous-structs-and-union-useful-for-in-in- c11) –

Antwort

14

Es muss nicht eine anonyme Struktur innerhalb einer Struktur sein, die ich nicht sehr nützlich finde: Dies wird in der Regel nur das Layout geringfügig ändern, indem mehr Padding eingeführt wird, mit anderen sichtbaren Effekten (im Vergleich zu Inlining der Mitglieder von die Kind-Struktur in die Eltern-Struktur).

Ich denke, dass der Vorteil von anonymen struct/unions ist woanders: Sie können verwendet werden, um eine anonyme Struktur innerhalb einer Union oder einer anonymen Union innerhalb einer Struktur zu platzieren.

Beispiel:

union u 
{ 
    int i; 
    struct { char b1; char b2; char b3; char b4; }; 
}; 
+1

Können Sie erklären, wie Sie diese Verbindung verwenden? Zum Beispiel, wenn ich Instanz x von u habe und 'x.b1 = 'a'' verwende, würde der Rest b2, b3, b4 initialisiert werden und Speicherplatz einnehmen? – Herbert

+0

@Herbert Dasselbe wie für eine traditionelle (benannte) Struktur in einer Union. Ihre Frage bezieht sich wirklich auf Unionen, die Strukturen enthalten. Sie sollten es als eine SO-Frage anstatt als einen Kommentar auf eine Antwort auf eine spezifischere Frage stellen, aber da Sie letzteres getan haben, initialisiert 'x.b1 = 'a''die Mitglieder' b2', 'b3' nicht , 'b4', aber diese nehmen" Speicherplatz ", wie man sehen kann, wenn man den Wert von' sizeof (union u) 'druckt. Theoretisch, wenn Sie eine 'union u'-Variable deklarieren, von der Sie nur das' b1'-Member verwenden, kann ein ausreichend intelligenter Compiler nur Speicher für 'b1', ... –

+0

@Herbert reservieren, aber im Prinzip eine' union u' deklarieren Objekt bedeutet, dass Sie möglicherweise zu einem der Mitglieder der Strukturen schreiben möchten, die es später enthält, sodass Speicher für sie reserviert werden sollte. –

11

Der Vorteil ist, ziemlich offensichtlich, oder? Es erspart dem Programmierer einen Namen! Seit naming things is hard ist es nett, dass es möglich ist, dies zu vermeiden, wenn es keinen wirklichen Bedarf gibt.

Es ist auch ein ziemlich klares Signal, dass diese struct lokal ist und nirgendwo anders, aber im Kontext des Seins ein Feld in der übergeordneten Struktur, die wirklich verwendet wird, wirklich schön Informationen, da es reduziert die Möglichkeit unnötiger Kopplung .

Betrachten Sie es als static; Es beschränkt die Sichtbarkeit der inneren struct auf die äußere, in ähnlicher Weise (aber nicht natürlich äquivalent), wie static die Sichtbarkeit von globalen Symbolen auf die Kompilierungseinheit beschränkt, in der sie erscheinen.

+0

Wenig aufwendig .. statisch ?? und eine weitere, wenn diese lokal ist, dann die Verwendung des gleichen Namens der Kennung gibt Fehler .. aber in der Funktion können wir denselben Namen innerhalb von {} geben wegen des Blockumfangs, warum ist es hier nicht erlaubt struct {} – Omkant

+4

Die 'struct' wird so lokal, dass es schwer zu verstehen ist, warum der Programmierer seine Mitglieder nicht direkt in die Elternstruktur einbindet. Diese Antwort in ihrer aktuellen Version enthält keine Vorteile in Bezug auf diese Alternative. Das Layout unterscheidet sich von der verschachtelten Struktur im Vergleich zu den Inline-Elementen (mit mehr Auffüllung, was zwar der beabsichtigte Effekt sein kann, aber normalerweise als Nachteil angesehen wird). –

+0

Es scheint, dass eine anonyme "Union" aus dem oben genannten Grund viel vorteilhafter ist als eine anonyme Struktur. – sherrellbc

1

Ich lief in einen großen Nutzen von anonymen union. Seien Sie jedoch gewarnt, dies ist keine Geschichte für schwache Nerven, noch ist es eine empfohlene Praxis. In einem älteren C-Programm von Hunderten von Quellcodedateien gibt es eine globale Variable, eine struct, die eine struct als Mitglied enthielt. So ist die Typdefinition für die globale Variable sah etwas, was wie:

typedef struct { 
    LONG  lAmount; 
    STRUCTONE largeStruct; // memory area actually used for several different struct objects 
    ULONG  ulFlags; 
} STRUCTCOMMON; 

Die struct, STRUCTONE, war einer von mehreren großen structs aber die anderen waren alle kleiner als STRUCTONE zum Zeitpunkt der Code geschrieben wurde. Dieser Speicherbereich largeStruct wurde also als union verwendet, aber ohne die entsprechenden Quellanweisungen. Stattdessen wurden verschiedene struct Variablen in diesen Bereich unter Verwendung von memcpy() kopiert.Um das Ganze noch schlimmer zu machen, geschah dies manchmal durch den tatsächlichen Namen der globalen Variablen und manchmal durch einen Zeiger auf die globale Variable.

Wie in der Regel passiert, wie die Zeit fortschreitet letzten Änderungen führten zu einer der anderen Strukturen die größte. Und ich war damit konfrontiert, dass ich durch hundert Dateien gehen musste, um herauszufinden, wo diese verwendet wurden, zusammen mit all den verschiedenen Aliasen und allem anderen.

Und dann erinnerte ich mich an anonyme Gewerkschaften. So modifizierte ich die typedef, die folgenden sein:

typedef struct { 
    LONG  lAmount; 
    union { 
     // anonymous union to allow for allocation of largest space needed 
     STRUCTONE largeStruct; // memory area actually used for several different struct objects 
     STRUCTTHREE largerStruct; // memory area for even larger struct 
    }; 
    ULONG  ulFlags; 
} STRUCTCOMMON; 

Und dann alles neu kompiliert.

So all die Tage der Quellcode-Überprüfung und Regressionstests, auf die ich mich unglücklich freute, sind nicht mehr notwendig.

Und ich kann jetzt den Prozess der langsamen Änderung der Quelle mit dieser globalen beginnen, um diese Quelle zu moderneren Standards auf meinem eigenen Zeitplan zu bringen.

Verwandte Themen