Unions in C für effizientes Daten-Packing und -Unpacking nutzen
Unions in C für effizientes Daten-Packing und -Unpacking nutzen
Unions bieten eine mächtige, speichereffiziente Möglichkeit, dieselben Bytes als verschiedene Datentypen neu zu interpretieren. Ursprünglich für geteiltes Speicher unter sich gegenseitig ausschließenden Variablen gedacht, nutzen moderne C-Programmierer Unions oft für Daten-Packing, -Unpacking und Type Punning – besonders beim Handling serieller Protokolle oder Low-Level-Kommunikation.
Wie eine Union Speicher teilt
Alle Member einer Union teilen sich dieselbe Speicherregion. Das größte Member bestimmt die Größe der Union, und jedes Member startet an derselben Adresse.
union { uint16_t word; struct { uint8_t byte1; uint8_t byte2; }; } u1;
Hier belegt word zwei Bytes, während die verschachtelte Struktur diese zwei Bytes in byte1 und byte2 aufteilt. Das Layout lässt sich visualisieren als:

Zwei Bytes in ein 16-Bit-Word packen
Um zwei 8-Bit-Werte x und y in ein 16-Bit-Word zu kombinieren, weisen Sie sie den Struktur-Membern zu und lesen dann das word-Member:
u1.byte1 = y; u1.byte2 = x; uint16_t packed = u1.word;
Dieses „Data Punning“ ist unkompliziert, hängt aber von der Byte-Reihenfolge des Prozessors ab.
Prozessor-Endianness ist entscheidend
Little-Endian-Systeme speichern das least significant byte zuerst, während Big-Endian-Systeme das most significant byte zuerst speichern. Betrachten Sie die Sequenz 0x01020304:

Ein simpler Test auf einer Little-Endian-Maschine liefert:
#include <stdio.h>
#include <stdint.h>
int main() {
union {
struct { uint8_t byte1; uint8_t byte2; };
uint16_t word;
} u1;
u1.byte1 = 0x21;
u1.byte2 = 0x43;
printf("Word is: %#X\n", u1.word);
return 0;
}
Output: Word is: 0X4321 – bestätigt Little-Endian-Speicherung. Auf einem Big-Endian-Target würde derselbe Code 0X2143 ausgeben.
Bitweise Alternative: Endianness-unabhängiges Packing
Shiften und Maskieren bieten einen portablen Weg, einen 16-Bit-Wert zu bauen:
uint16_t word2 = (((uint16_t)byte3) << 8) | ((uint16_t)byte4);
Beide Methoden vergleichen:
#include <stdio.h>
#include <stdint.h>
int main() {
union {
struct { uint8_t byte1; uint8_t byte2; };
uint16_t word1;
} u1;
u1.byte1 = 0x21;
u1.byte2 = 0x43;
printf("Word1 is: %#X\n", u1.word1);
uint8_t byte3 = 0x21, byte4 = 0x43;
uint16_t word2 = (((uint16_t)byte3) << 8) | ((uint16_t)byte4);
printf("Word2 is: %#X\n", word2);
return 0;
}
Auf einem Big-Endian-Prozessor: Word1 is: 0X2143, Word2 is: 0X2143. Auf einem Little-Endian-Prozessor: Word1 is: 0X4321, Word2 is: 0X2143. Der bitweise Ansatz garantiert konsistente Ergebnisse über Architekturen hinweg.
Praktisches Beispiel: Float über UART senden
Serielle Links übertragen typischerweise ein Byte zur Zeit. Um einen 32-Bit float zu senden, können wir eine Union nutzen, um den Float als Array von vier Bytes zu betrachten:
union buffer { float f; struct { uint8_t byte[4]; }; };
Sender-Seite:
union buffer tx; union buffer rx; float f1 = 5.5f; tx.f = f1; for (int i = 0; i < 4; ++i) { // send tx.byte[i] over UART rx.byte[i] = tx.byte[i]; // Simulierter Empfang } printf("The received data is: %f\n", rx.f);
Output: The received data is: 5.500000. Die Union trennt sauber die Byte-Darstellung vom Floating-Point-Wert, was den Code lesbar und wartbar macht.

Kernaussagen
- Unions erlauben Type Punning, aber Ergebnisse hängen von Endianness ab.
- Bitweise Operatoren bieten portables, architekturunabhängiges Packing.
- Für Klarheit und Wartbarkeit bevorzugen viele Entwickler Unions in eingebetteten Kontexten.
- Unions glänzen beim Übertragen beliebiger Datenstrukturen über byte-orientierte Links.
Um mehr über C, Unions und Embedded Systems zu erfahren, durchsuchen Sie meine vollständige Artikelliste.
Eingebettet
- Semaphores in Nucleus RTOS: Utility Services & Data Structures
- U.S. Army treibt Condition-Based Maintenance mit innovativen Sensoren und Predictive Analytics voran
- Wie IIoT & Data Analytics EHS transformieren: Sicherheit, Effizienz und Einsparungen steigern
- Verantwortungsvolle und vertrauenswürdige KI aufbauen: Leitfaden zu Erklärbarkeit, Rechenschaftspflicht und Ethik
- Fog Computing erklärt: IoT-Datenfluss transformieren & Cloud-Last reduzieren
- C-Unions erklärt: Effizientes Speichermanagement für mehrere Datentypen
- Lieferketten-Transparenz entschlüsseln: Die entscheidende Rolle von Daten und Kontext
- Flottenmanagement revolutionieren: KI & IoT-Integration für intelligentere Operationen
- Industrielles AIoT: KI und IoT verschmelzen für Industry-4.0-Innovation
- Litmus und Oden starten integrierte IIoT-Lösungen für Smart Manufacturing