2009-12-02 10 views
5

Ich habe eine Ganzzahl ohne Vorzeichen, aber wenn ich sie mit% d ausdrucke, gibt es dort manchmal einen negativen Wert?C Unsigned Int liefert einen negativen Wert?

+1

Sehen Sie, ob Ihr Compiler eine Option hat, über diese Art von Fehler zu warnen. Es ist -W Format mit gcc. –

+0

Mögliches Duplikat von [Wie kann ich den Maximalwert einer Ganzzahl ohne Vorzeichen drucken?] (Http://stackoverflow.com/questions/12812812/how-can-i-print-maximum-value-of-an-unsigned-integer) –

Antwort

10

sollte diese Arbeit:

unsigned int a; 
printf("%u\n", a); 

Erläuterung: Auf den meisten Architekturen unterzeichnete ganze Zahlen in two's complement vertreten sind. In diesem System werden positive Zahlen kleiner als 2**(N-1) (wobei N = sizeof(int)) auf die gleiche Weise dargestellt, unabhängig davon, ob Sie eine int oder eine unsigned int verwenden. Wenn die Zahl in Ihrem unsigned int jedoch größer als 2**(N-1) ist, stellt es eine negative vorzeichenbehaftete Zahl unter Zweierkomplement dar - was printf Ihnen gab, als Sie es "%d" übergeben.

26

Drucken %d liest die Ganzzahl als eine vorzeichenbehaftete Dezimalzahl, unabhängig von ihrem definierten Typ.

Um vorzeichenlose Nummern zu drucken, verwenden Sie %u.

Dies geschieht aufgrund der Möglichkeit von C, Variablenargumente zu verarbeiten. Der Compiler zieht nur Werte aus dem Stack (eingegeben als void* und zeigt auf den Aufruf-Stack) und printf muss herausfinden, was die Daten aus der Format-Zeichenfolge enthält, die Sie es geben.

diesem Grund sollten Sie die Formatzeichenfolge liefern müssen - C hat keine Möglichkeit, RTTI oder eine ‚Basisklasse‘ (Object in Java, zum Beispiel) aus einer generischen oder vordefinierten toString zu erhalten.

+4

Nitpick: C ist call by value, daher zieht der Compiler Argumentwerte, keine Zeiger. Übergeben Sie keine Zeiger auf Werte (printf ("% u", & myvariable);), übergeben Sie Werte direkt (printf ("% u", myvariable);). – unwind

+1

Es gibt tatsächlich 'printf' einen Zeiger auf den Stapel. – LiraNuna

+0

@LiraNuna - Die Implementierung von varargs Funktionen ist nicht spezifiziert, weshalb weder '#define va_copy (dest, src) dest = src' noch' #define va_copy (dest, src) memcpy (dest, src, sizeof (va_list)) 'ist ein tragbarer Ersatz für das Makro' va_copy' auf Systemen, auf denen es nicht zur Verfügung steht. Einer von ihnen mag arbeiten, aber wer weiß was? –

4

% d bedeutet printf interpretiert den Wert als int (was mit Vorzeichen versehen ist). Verwenden Sie% u, wenn es ein unsigned int ist.

Verwandte Themen