Forum: Compiler & IDEs longint highbyte und lowbyte direkt ansprechen in C


von pluto (Gast)


Lesenswert?

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

von johnny.m (Gast)


Lesenswert?

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.

von Fisch (Gast)


Lesenswert?

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

von johnny.m (Gast)


Lesenswert?

> HB=(char)(a>>8);
Es geht um einen long int. Da musste etwas mehr schieben...

von Fisch (Gast)


Lesenswert?

Du hast recht. Dann muss er halt 24 schieben.

von pluto (Gast)


Lesenswert?

Oh, sorry ich meinte natürlich nicht long sondern short, also 16 Bit.
Dann sollte es aber so gehen wie Fisch geschrieben hat, oder?

von johnny.m (Gast)


Lesenswert?

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...

von pluto (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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);

von pluto (Gast)


Lesenswert?

@ 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 );}

von Peter S. (psavr)


Lesenswert?

@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 );}



von johnny.m (Gast)


Lesenswert?

@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.

von Oliver (Gast)


Lesenswert?

"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
Noch kein Account? Hier anmelden.