Hallo, ich habe eine doofe Frage und habe auch über die Suche nix gefunden. Aber vielleicht kann mir ja jemand weiterhelfen. Gibt es eine Möglichkeit in C das High- und Lowbyte einer Longint Variable direkt anzusprechen (schreiben/lesen)? Vielen Dank schonmal
Das Übliche: Nimm eine union. Wenn Du mit Low- und High-"Byte" die oberen und unteren 16 Bit meinst (wobei 16 Bit aber 2 Bytes sind!), dann ganz kurz:
1 | union
|
2 | {
|
3 | unsigned long wert; |
4 | unsigned int wert_hl[2]; |
5 | }
|
Oder mit Maskierung.
Wenn es wirklich nur das Low- und Highbyte sein soll, mach es doch einfach so. void main (void) { long int a=0xABCD; char LB=0; char HB=0; LB=(char)a; HB=(char)(a>>8); } Gruß Fisch
> HB=(char)(a>>8);
Es geht um einen long int. Da musste etwas mehr schieben...
Du hast recht. Dann muss er halt 24 schieben.
Oh, sorry ich meinte natürlich nicht long sondern short, also 16 Bit. Dann sollte es aber so gehen wie Fisch geschrieben hat, oder?
Wenn man a als int und nicht als long int deklariert, dann ja. Allerdings ist ein sicheres Funktionieren nur mit unsigned-Variablen gewährleistet. Je nachdem, was der Compiler aus dem Vorzeichen-Bit macht, kann sonst eventuell Murks rauskommen...
Was macht denn das (char)? Das (a>>8) schiebt ja alles um 8 Bit nach rechts. Irgendwie steh ich voll auf dem Schlauch. Und wie geht das in die Andere Richtung? also 2x char zu int
Das (char) ist ein sog. 'cast' Also: * Zerlegen int i; uint8_t LowByte, HighByte; LowByte = (uint8_t) i; HighByte = (uint8_t)( ((uint16_t)i) >> 8 ); * Zusammensetzen int i; utin8_t LowByte, HighByte; i = (int)( HighByte << 8 | LowByte ); Am besten macht man sich dafür ein paar Makros oder inline Funktionen #define LOW(x) ((uint8_t)(x)) #define HIGH(x) ((uint8_t)(((uint16_t)(x)) >> 8) #define TOWORD(x,y) (((x) << 8) | y) int i, j; uint8_t LowByte, HighByte; LowByte = LOW(i); HighByte = HIGH(i); j = TOWORD(HighByte, LowByte);
@ Karl heinz Buchegger was macht der 'cast' ich kapier das nicht. @all Ich habe mal 3 Funktiionen gebaut wäre schön wenn jemand mal drüberschauen könnte, ob die so in Ordnung sind. Vielen Dank schonmal! uint8_t highbyte(uint16_t a){return (uint8_t)(a>>8);} uint8_t lowbyte(uint16_t a){return (uint8_t)a;} uint16_t word(uint8_t a,uint8_t b){return (uint16_t)(a << 8 | b );}
@Buchegger
>#define TOWORD(x,y) (((x) << 8) | y)
Solltest Du hier nicht erst auf 16Bit casten, bevor Du schiebst?
1 | #define TOWORD(x,y) (((uint16_t)x << 8) | y)
|
@Pluto
Ich würde Makros, wie die Buchegger vorschlägt verwenden statt
Funktionen. Funktionen sind etwas langsamer, wegen dem Function-Call
Overhead.
>uint16_t word(uint8_t a,uint8_t b){return (uint16_t)(a << 8 | b );}
Allenfalls müsstest Du vor dem Links shiften ebenfalls auf 16Bit casten
und die Klammern anderst setzen. (Sicher ist sicher)
1 | uint16_t word(uint8_t a,uint8_t b){return (uint16_t)(((uint16_t)a << 8) | b );} |
@Peter:
Berechnungen werden doch standardmäßig eh in 16 Bit durchgeführt,
solange nichts anderes angegeben ist. Den cast nach uint16_t kann man
sich also sparen.
@Pluto:
> was macht der 'cast' ich kapier das nicht.
Der cast sorgt dafür, dass das Ergebnis der Berechnung (das ja immer
noch ein 16-Bit-Wert ist) als 8-Bit-Wert zurückgegeben wird. Du willst
ja aus einem 16-Bit-Wert 2 8-Bit-Werte machen. Ohne den cast vor dem
return wäre der Rückgabewert ein uint16_t und es würde eine
Fehlermeldung geben, dass der Typ des Rückgabewertes (also uint16_t)
nicht mit dem in der Funktionsdeklaration vereinbarten (also uint8_t)
übereinstimmt. Beim cast von 16-Bit-unsigned int-Variablen auf
8-Bit-unsigned int werden die 8 MSB des 16-Bit-int abgeschnitten und nur
die 8 LSB bleiben übrig. Ich hoffe, die Erklärung war jetzt nicht zu
unverständlich. Wie casts generell funktionieren (und auch wann sie
nicht funktionieren) solltest Du im C-Buch Deines Vertrauens mal
nachlesen.
"short, also 16 Bit." Wobei short vorzeichenbehafet ist. Wenn dir klar ist, was das bedeutet, ist es gut, sonst nimm lieber das auch in den Beispielen genannte unsigned short bzw. uint16_t. Oliver
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.