short int - unteres byte herrauslesen

Gast #350474
Lesenswert?
• ▲
▼
Pointergewurschtel ist nicht notwendig. Sauber sieht es mit Unions aus.
Als Beispiel vom PC ein Long mit byteweisem Auslesen, sollte sich auch
auf µC-C übertragen lassen:


union U{
    char c[4];
    long i;
};

int main()
{
    U u;
    u.i = 0x12345678;

    for (int i=3; i>=0; --i)
        printf("%x ", u.c[i]);
Gast #350475
Lesenswert?
• ▲
▼
So, da fehlt jetzt die Hälfte, weil ich versucht habe TAB im Textfenster
einzugeben und dann Submit ausgelöst habe ;)

Die Unionlösung sieht eigentlich ganz elegant aus. Für was anderes
fällt mir eigentlich auch kein sinnvoller Nutzen von Unions ein...
Gast #350477
Lesenswert?
• ▲
▼
> Pointergewurschtel ist nicht notwendig.

Wäre aber besser.

> Sauber sieht es mit Unions aus.

Sauber ist das gar nicht. Unions sind für sowas eigentlich nicht
gedacht. Laut C-Norm darf man aus einer Union auch nur das Member
lesen, das man davor als letztes reingeschrieben hat. Geht halt
meistens trotzdem, aber ist eigentlich eher ein Hack.
Gast #350478
Lesenswert?
• ▲
▼
Bis letztes Jahr hatte ich bei dieser "union" Sache den Eindruck, dass
nur Maschinen aus dem Neolithikum damit ein Problem haben würden. Das ja
wohl alles was heute noch rumläuft das richtig behandeln wird.

Denkste!

Maxim hat es fertig gebracht, eine Architektur zu definieren, in der
ein Pointer-to-Byte anders dargestellt wird, als ein Pointer-to-Word.
Und weil MAXQ2000 nur 16bittig ist, kann er Speicher als 64K Worte oder
als 64K Bytes adressieren. Also kann nur die Hälfte vom Speicher auch
byteweise verwendet werden - eines der angesprochenen Urviecher hatte
dafür ein 17.Adressbit im Carryflag, MAXQ nicht. Da können solche
Tricks bös in die Hose gehen.

Wüsste gerne welcher Teufel Maxim da geritten hat.
#350479
Lesenswert?
• ▲
▼
Da hat Rolf recht, ne union ist ein böser Hack und geht nur gut auf der
gleichen CPU und mit der gleichen Compilerversion.

Schieben ist dagegen immer richtig, also völlig Compiler und
CPU-unabhängig.

Und die meisten Compiler optimieren das auch sehr ordentlich, bzw.
wenns einen Zyklus länger dauert, bricht man sich doch auch kein Bein.


Peter
Persönliche Seite #350480
Lesenswert?
• ▲
▼
Für das unterste Byte brauch man nochnichtmals Schieben.


long long_var = 0x12345678;
char lbyte = long_var & 0x000000FF;


Es müsste sogar ohne & Operator funktionieren.


Für die anderen Bytes kann man aber mit Pointern handtieren:

long long_var = 0x12345678;
char byte = *( ((char *) &long_var ) + 1) ); // Gibt das Byte über dem
untersten zurück.


PS: Für was ist Union denn dann gedacht? Oder ist es eine "herzlos
implementierte Funktion" die quasi Obsolet ist?
#350484
Lesenswert?
• ▲
▼
Pointer ist doch das gleiche, wie ne Union, da muß man auch die
Byteorder kennen, sonst gehts schief.

Ne Union macht durchaus Sinn, z.B. um einen Datensatz im EEPROM zu
speichern.
Da ja die gleiche CPU und die gleiche Compilerversion die Schreib- und
die Leseroutine ausführen, ist die Byteorder im EEPROM völlig egal.
Nach dem Lesen ist z.B ein float wieder ein float.


Peter

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.