Ich habe ein seltsames Problem mit der Arbeit mit ganzen Zahlen in C ++.
Ich habe ein einfaches Programm geschrieben, das einen Wert auf eine Variable setzt und diese dann druckt, aber es funktioniert nicht wie erwartet.
Mein Programm hat nur zwei Codezeilen:
uint8_t aa = 5;
cout << "value is " << aa << endl;
Die Ausgabe dieses Programms ist value is
Dh es druckt leer für aa
.
Wenn ich uint8_t
zum uint16_t
obigen Code wechsle , funktioniert das wie ein Zauber.
Ich verwende Ubuntu 12.04 (Precise Pangolin), 64-Bit, und meine Compiler-Version lautet:
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
Antworten:
Es wird nicht wirklich ein Leerzeichen gedruckt, aber höchstwahrscheinlich das ASCII-Zeichen mit dem Wert 5, das nicht druckbar (oder unsichtbar) ist. Es gibt eine Reihe von unsichtbaren ASCII-Zeichencodes , die meisten davon unter dem Wert 32, der eigentlich leer ist.
Sie müssen in konvertieren
aa
,unsigned int
um den numerischen Wert auszugeben, daostream& operator<<(ostream&, unsigned char)
versucht wird, den sichtbaren Zeichenwert auszugeben.quelle
int
. Eine Besetzung ist eine Möglichkeit, aber nicht die einzige.+aa
funktioniert auch.int(var)
und(int)var
genau die gleiche Bedeutung haben.int(var)
wird in genau den Fällen entmutigt, in denen dies(int)var
aus genau den gleichen Gründen der Fall ist, weil es genau das Gleiche bedeutet. (Ich kann verstehen, warum Sie es hier sowieso versuchen würden, also sage ich nicht, dass Sie es verwenden müssenstatic_cast
. Ich denke nur, dass der Kommentarpfad hier ein bisschen unnötig verwirrend geworden ist.)uint8_t
wird höchstwahrscheinlich eintypedef
für seinunsigned char
. Dieostream
Klasse hat eine spezielle Überladung fürunsigned char
, dh sie druckt das Zeichen mit der Nummer 5, die nicht druckbar ist, daher der leere Raum.quelle
Wenn Sie vor der Variablen eines primitiven Datentyps einen unären + -Operator hinzufügen, erhalten Sie einen druckbaren numerischen Wert anstelle eines ASCII-Zeichens (im Fall eines Zeichentyps).
quelle
uint8_t
alsunsigned char
die numerische Werte sein würde?uint8_t
nur ein Typ def von istunsigned char
, aberunsigned char
selbst vonostream
like behandelt wirdchar
und seinen ASCII-Wert druckt.unsigned char
, die viel erklärt. Die einzige ganze Zahl ist alsoint
, richtig?short int
2 Bytes belegen . Es gibt auch einige andere Variationen des Integer-Typs.long
oderint
weil der Compiler die Verwendung von RAM oder Flash optimieren würde Habe ich recht, was füllt dieses Register?Dies liegt daran, dass der Ausgabeoperator das Gleiche
uint8_t
wie a behandeltchar
(uint8_t
normalerweise nur ein Alias fürunsigned char
), sodass das Zeichen mit dem ASCII-Code (dem am häufigsten verwendeten Zeichencodierungssystem) gedruckt wird5
.Siehe zB diese Referenz .
quelle
signed
als auch fürunsigned
Zeichen überladen ist (jenseits der Ebene,char
die in C ++ tatsächlich ein dritter separater Typ ist). Wennuint8_t
also ein Alias fürunsigned char
(sehr wahrscheinlich) ist, wird dieser verwendet.Verwendung von ADL (Argument-abhängige Namenssuche):
Ausgabe:
Ein benutzerdefinierter Stream-Manipulator wäre ebenfalls möglich.
cout << +i << endl
).quelle
return std::is_signed<char>::value ? os << static_cast<int>(c) : os << static_cast<unsigned int>(c);
cout
behandeltaa
alschar
ASCII - Wert5
typecasting , auf die ein nicht druckbare Zeichen, versuchenint
vor dem Druck.quelle
Die
operator<<()
Überlastung zwischenistream
undchar
ist eine Nichtmitgliedsfunktion. Sie können die Elementfunktion explizit verwenden, um achar
(oder auint8_t
) als zu behandelnint
.Ausgabe:
quelle
Wie bereits erwähnt, tritt das Problem auf, weil der Standard-Stream vorzeichenbehaftete Zeichen und vorzeichenlose Zeichen als einzelne Zeichen und nicht als Zahlen behandelt.
Hier ist meine Lösung mit minimalen Codeänderungen:
Das Hinzufügen
"+0"
ist mit jeder Zahl einschließlich Gleitkomma sicher.Bei ganzzahligen Typen wird der Ergebnistyp in
int
if geändertsizeof(aa) < sizeof(int)
. Und es wird den Typ nicht ändern, wennsizeof(aa) >= sizeof(int)
.Diese Lösung eignet sich auch gut für die Vorbereitung
int8_t
des Drucks zum Streamen, während einige andere Lösungen nicht so gut sind:Ausgabe:
PS-Lösung mit ADL von pepper_chico und πάντα ῥεῖ ist wirklich schön.
quelle