warum wird char mit 4 Bytes dargestellt?

OP #5832429
Lesenswert?

#include <stdio.h>

int main(){
  signed char test = 'a';
  signed char neg_test = ~'a';

  printf("test = %d Byte \n", sizeof(test) );
  printf("Integer: %d\n", test );
  printf("ist in Hex: x%x\n", test);
  printf( "neg_test = %d Byte(s) \n", sizeof(neg_test) );
  printf("Integer: %d\n", neg_test );
  printf("ist in Hex: x%x\n", neg_test);
  return 0; }

Ausgabe:
test = 1 Byte
Integer: 97
ist in Hex: x61
neg_test = 1 Byte(s)
Integer: -98
ist in Hex: xffffff9e

Meine Frage bezieht sich auf die letzte Zeile der Ausgabe
Gast #5832443
Lesenswert?

Führende Nullen werden weggelassen und bei HEX-Darstellung wird kein 
Minus angezeigt. Die Fs bzw. Einsen müssen also irgendwie ausgegeben 
werden.


Lieber immer die Breite mitangeben, z.B.: "0X%02X", "0X%04X"

Gruß
Daniel
Moderator #5832482
Lesenswert?

devzero schrieb:
> printf("%hhx", dein_char);

Zu spät, aber dafür etwas ausführlicher:

Walter K. schrieb:
> DanielF schrieb:
>> Die Fs bzw. Einsen müssen also irgendwie ausgegeben
>> werden.
>
> das heisst aber auch, dass char 4 Bytes gross ist - und nicht 1 Byte,
> wie es für -128 bis +127 notwendig wäre?

Nein, aber das "%x"-Format stellt den Wert als int dar. Für short gibt
es dan Formatpräfix "h" und für char "hh". Das Format, das du sucht,
ist also "%hhx" oder "%#hhx". Letzteres stellt automatisch ein "0x" vor
die ausgegebene Zahl.

"%d" sollte auch nicht für sizeof-Ergebnisse verwendet werden, das diese
nicht vom Typ int sondern size_t sind. Das richtige Format ist hier
"%zd".
OP #5832487
Lesenswert?

Niklas G. schrieb:
>> printf("test = %d Byte \n", sizeof(test) );
>
> Das ist übrigens immer 1, denn sizeof gibt die Größe in Vielfachen von
> "char" an, und "test" ist vom Typ "char", und char ist nunmal genau 1
> char groß.

hmm .. dann haette ich aber auch für den Typ size_t des Rückgabewerte 
von sizeof() in printf auch %z als Formatbezeichner nutzen müssen ...

edit: .. da war jemand schneller ;-)
#5832494
Lesenswert?

Zudem werden bei Funktionen mit variabler Argumentenliste (wie printf) 
die Werte auf mindestens int (bei Ganzzahltypen) oder double (bei 
Fließkommatypen) aufgewertet.

D.h bei
1
  signed char neg_test = ~'a';
2
  printf("ist in Hex: x%x\n", neg_test);
 wird tatsächlich ein int übergeben.
Bei %hhx auch, aber da wird halt nur ein Byte berücksichtigt.

!ACHTUNG
Bei scanf werden im allgemeinen Pointer/Adressen übergeben.
da ist es extrem wichtig, den richtigen Formatspecifier zu wählen.
Sonst werden mal 4 Byte geschrieben, wo nur 1 BYte Platz ist.
Gast #5832514
Lesenswert?

Dirk B. schrieb:
> Zudem werden bei Funktionen mit variabler Argumentenliste (wie printf)
> die Werte auf mindestens int (bei Ganzzahltypen) oder double (bei
> Fließkommatypen) aufgewertet.

aber man hatte schon bei der Zuweisung mit 4 Bytes zu tun oder?

also hier:

Walter K. schrieb:
> signed char neg_test = ~'a';

1
  size_t len = sizeof('a');
2
  printf("%zu\n", len);
Persönliche Seite #5832516
Lesenswert?

Yalu X. schrieb:
> Das richtige Format ist hier
> "%zd".

Eher %zu, denn size_t ist ja unsigned.

zitter_ned_aso schrieb:
> aber man hatte schon bei der Zuweisung mit 4 Bytes zu tun oder?
Ja, char-Literale wie 'a' sind in C vom Typ "int". Der wird dann aber 
auf "char" gekürzt.

In C++ ist das aber nicht so - da ist 'a' vom Typ char.

Daher liefert das

zitter_ned_aso schrieb:
> size_t len = sizeof('a');
>   printf("%zu\n", len);

in C z.B. 4 (je nach Plattform), in C++ immer 1. Das ist einer der 
wenigen Fälle wo C-Code in C++ anders ausgeführt wird.
Gast #5833211
Lesenswert?

Rolf M. schrieb:
> Walter K. schrieb:
> und vorher bei C90 war es wohl %lu
>
> Nein, das l steht für long, nicht für size_t. Die müssen nicht zwingend
> beide gleich groß sein. Man kann aber %lu verwenden und den übergebenen
> Parameter nach unsigned long casten.

%z wurde erst mit c99 Standard

Beim c90 musste man wohl sich mit Long behelfen

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren