Forum: PC-Programmierung Char mit 4 Bytes


von Marcus (Gast)


Lesenswert?

Einen schönen guten Tag zusammen,

ich bin hier absolut neu, deswegen bitte ich für kleinere Patzer 
schonmal im Vorfeld um Verzeihung.
Da mir Google und Suchfunktion bereits nicht weitergeholfen haben, 
versuche ich es diesmal mit einer direkten Frage:

Ich habe ein Array mit 12 Char-Variablen (4 genutzte Bit) welches ich in 
ein Array mit 6 Char-Variablen (mit 8 genutzen Bit) umwandeln möchte und 
das per Bitshift-Befehl, das sieht dann ungefähr so aus:
----------------------------------------------
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
int main(int argc, char *argv[]) {
5
  char i;
6
  char adr1[12] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc};
7
  for(i=0;i<6;i++)
8
    adr1[i] = (adr1[2*i] << 4) | (adr1[2*i+1]); //0x1+0x2 = 0x12
9
  return 0;
10
}
----------------------------------------------
Problem: Sobald die jeweils 1. Char-Variable größer 7 also mehr wie 3 
Bits genutzt werden, bekomme ich einen 4-Byte-großen Character heraus.
Kurz gefasst: (0x8 << 4) | 0x4 = 0xffffff84

Nun ist die Frage wie das überhaupt funktionieren kann, da ja eigentlich 
ein Character nur 1 Byte groß ist und wie sich dieses Problem beheben 
lässt.

Achso, als "Testumgebung" benutze ich momentan Dev-C++ wenn das 
irgendwie aussagekräftig ist.

Mit freundlichen Grüßen und mit Danke schon mal im Voraus
Marcus

: Bearbeitet durch User
von Hugo (Gast)


Lesenswert?

Nimm unsigned char

von Peter II (Gast)


Lesenswert?

Marcus schrieb:
> Kurz gefasst: (0x8 << 4) | 0x4 = 0xffffff84
>
> Nun ist die Frage wie das überhaupt funktionieren kann, da ja eigentlich
> ein Character nur 1 Byte groß ist und wie sich dieses Problem beheben
> lässt.

weil man ein char nicht zum rechnen nicht. Denn ist ist nicht definiert 
es ob es unsigned oder signed ist. C rechnet also vermutlich mit int. 
Damit ist das verhalten erklärbar.

also erstmal richtige datentype verwenden:

> char adr1[12]
unsigned char adr1[12]

oder noch besser

uint8_t adr1[12]

von Marcus (Gast)


Lesenswert?

Hätte nicht erwartet, dass ich so schnell zwei präzise Antworten 
bekomme.
Vielen Dank, hat wunderbar geklappt.

von Rolf Magnus (Gast)


Lesenswert?

Peter II schrieb:
> Marcus schrieb:
>> Kurz gefasst: (0x8 << 4) | 0x4 = 0xffffff84
>>
>> Nun ist die Frage wie das überhaupt funktionieren kann, da ja eigentlich
>> ein Character nur 1 Byte groß ist und wie sich dieses Problem beheben
>> lässt.
>
> weil man ein char nicht zum rechnen nicht. Denn ist ist nicht definiert
> es ob es unsigned oder signed ist. C rechnet also vermutlich mit int.

C rechnet immer mit int, wenn die Werte, die man übergibt, kleiner 
sind. Das nennt sich "integer promotion". 0x8 << 4 ergibt 0x00000080 
(Typ int). Das wird mit 0x4 verODERt, was 0x00000084 ergibt. Das wird 
dann wieder nach char reduziert durch abschneiden der oberen 24 Bits 
(0x84) und in adr1[i] abgespeichert. Wenn char vorzeichenbehaftet ist, 
ergibt das einen Wert von -124. Das Problem ist vermutlich erst bei der 
hier leider verheimtlichten Ausgabe des Wertes entstanden. Wenn der z.B. 
mit printf und %u ausgegeben wurd, wird der char-Wert erstmal 
vorzeichenrichtig nach int konvertiert und dann von printf als 
vorzeichenlos uminterpretiert, was dann die 0xffffff84 ergibt.

von Rolf Magnus (Gast)


Lesenswert?

Rolf Magnus schrieb:
> mit printf und %u

... oder %x

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.