Wie werden die Gewerkschaftsmitglieder gelagert?

Lesezeit: 4 Minuten

Benutzer-Avatar
Glücklich Mittal

union test
{
 int i;
 char ch;
}t;
int main()
{
 t.ch=20;
}

Vermuten sizeof(int)==2 und die für t zugewiesenen Speicheradressen seien 2000, 2001.
Wo ist dann 20, dh t.ch gespeichert – bei 2000 oder 2001 oder hängt von der Endianness der Maschine ab?

  • Ich bin mir nicht sicher, ob die Endianität etwas damit zu tun hat, wo eine Union gespeichert wird … speichern nicht alle Union-Typen am selben Ort (dh am Nullpunkt)? (Trotzdem gute Frage!)

    – Platin Azur

    27. Dezember 2010 um 17:54 Uhr


  • 2001 ist unwahrscheinlich, da nicht ausgerichteter Speicherzugriff je nach Architektur entweder langsam oder verboten ist.

    – Alexander C.

    27. Dezember 2010 um 17:56 Uhr

  • @Platinum Azure: Wenn wir einfach int a=20 definieren; hängt es dann nicht von endianness ab, wo 20 gespeichert ist?

    – Glücklicher Mittal

    27. Dezember 2010 um 18:01 Uhr

  • @Happy Mittal: Nein, weil Sie nur sagen, dass es unabhängig davon zwei Bytes (sowohl 2000 als auch 2001 in Ihrem Beispiel) verwendet. Nun, ob die hohen Bits (die die 16- und 4-Stelle darstellen) in 2000 oder 2001 sind, HÄNGT von Endian-ness ab, aber die Tatsache bleibt, dass, welches Byte auch immer die gesetzten Bits enthält, das andere immer noch unbrauchbar ist, weil es Teil von ist int Speicherplatz des Typs.

    – Platin Azur

    27. Dezember 2010 um 18:03 Uhr

  • @platinum Azure: Tut mir leid, ich konnte nicht verstehen, was du mit “16. und 4. Platz” meinst. Außerdem sage ich, dass, wenn ich dies tue: int a=20; printf(“%d”,* (char*)&a); Hängt die Ausgabe dann nicht von der Endianität ab, dh ob 20 bei 2000 oder 2001 gespeichert wird?

    – Glücklicher Mittal

    27. Dezember 2010 um 18:07 Uhr


Benutzer-Avatar
Matteo Italien

Der C99-Standard (§6.7.2.1.14) sagt:

Die Größe einer Gewerkschaft reicht aus, um die größten ihrer Mitglieder aufzunehmen. Der Wert von höchstens einem der Mitglieder kann jederzeit in einem Union-Objekt gespeichert werden. Ein Zeiger auf ein Vereinigungsobjekt, geeignet konvertiert, zeigt auf jedes seiner Mitglieder (oder wenn ein Mitglied ein Bitfeld ist, dann an die Einheit, in der es sich befindet) und umgekehrt.

(Betonung hinzugefügt)

Die fette Aussage besagt eigentlich, dass jedes Mitglied der Gewerkschaft die gleiche Adresse hat, also „beginnen“ sie alle an der gleichen Adresse. twie t.ch wie t.isollte also an der Adresse 2000 liegen t.ch überschneidet sich mit dem ersten Byte (in Adressreihenfolge) von t.i.

Was das in Bezug auf „was bekomme ich, wenn ich versuche zu lesen t.i nach Einstellung t.c” hängt in der realen Welt von der Plattformendianität ab, und tatsächlich ist der Versuch, ein Mitglied einer Gewerkschaft zu lesen, wenn Sie in einer anderen geschrieben haben, gemäß dem C-Standard ein nicht spezifiziertes Verhalten (§6.2.6.1.6/7, neu formuliert in §J. 1.1).


Was mehr hilft, die Endianness der Maschine zu verstehen (zumindest denke ich, dass es einfacher zu verstehen ist), ist eine Union wie diese:

union
{
    int i;
    unsigned char ch[sizeof(i)];
} t;

tun

t.i=20;

und dann schauen, was in den beiden Zeichen ist t.ch. Wenn Sie sich auf einer Little-Endian-Maschine befinden, erhalten Sie t.ch[0]==20 und t.ch[1]==0und das Gegenteil, wenn Sie sich auf einer Big-Endian-Maschine befinden (if sizeof(int)==2). Beachten Sie, dass dies, wie bereits gesagt, ein implementierungsspezifisches Detail ist, der Standard erwähnt nicht einmal Endianness.

Um es noch deutlicher zu machen: Wenn Sie ein 2-Byte haben int var auf 20 gesetzt, auf einer Little-Endian-Maschine den zugehörigen Speicher in Adressreihenfolge ausgeben, erhalten Sie (in hexadezimaler Darstellung, Bytes durch Leerzeichen geteilt):

14 00

während auf einer Big-Endian-Maschine erhalten Sie

00 14

Die Big-Endian-Darstellung sieht aus unserer Sicht “richtiger” aus, denn in der Little-Endian-Darstellung machen die Bytes das Ganze aus int werden in umgekehrter Reihenfolge gespeichert.


Außerdem sage ich, dass, wenn ich dies tue:

int a=20;
printf("%d",* (char*)&a);

Hängt die Ausgabe dann nicht von der Endianität ab, dh ob 20 bei 2000 oder 2001 gespeichert wird?

Ja, hier tut es das, aber in Ihrer Frage fragen Sie etwas anderes; das sieht eher aus mein Beispiel.

  • Danke Matteo. Eigentlich sagen Sie und Platinum Azure gegensätzliche Dinge, also war ich verwirrt.

    – Glücklicher Mittal

    27. Dezember 2010 um 18:34 Uhr

  • @Happy Mittal: Wie ich in meinem letzten Kommentar erklärt habe, habe ich Ihren alten Kommentar verwendet, der eine Int-to-Char-Konvertierung hatte. Tatsache bleibt: eine Sechzehn-Bit-Zahl, repräsentiert durch das Literal 20 wird immer noch in BEIDEN Bytes gespeichert, egal welche Endianness Ihre Architektur verwendet. Es ist nur so, dass das eine oder andere Byte Null sein wird. Wenn Sie eine Nummer wie speichern würden 257sind beide Bytes ungleich Null.

    – Platin Azur

    27. Dezember 2010 um 18:49 Uhr

test würde zwei Bytes benötigen und würde daher an Adresse 2000, 2002 usw. zugewiesen werden. Und jeder Wert für jede Instanz der Vereinigung würde beginnend an dieser Basisadresse gespeichert werden.

Jedes Mitglied der Vereinigung würde für diese Instanz der Vereinigung an der gleichen Adresse gespeichert werden. Aus diesem Grund können Sie nur einen Werttyp gleichzeitig in einer Union speichern. Daher belegen Vereinigungen die Anzahl von Bytes, die für das größte Element erforderlich sind.

1054350cookie-checkWie werden die Gewerkschaftsmitglieder gelagert?

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

Privacy policy