2010-05-11 17 views
8

Was ich weiß, über unsigned Numerik (unsigned short, int und longs), dass es nur positive Zahlen enthält, aber das folgende einfache Programm erfolgreich eine negative Zahl zu einem unsigned int zugewiesen:Warum unsigned int enthielt negative Zahl

1 /* 
    2 * ===================================================================================== 
    3 * 
    4 *  Filename: prog4.c 
    5 * 
    6 * ===================================================================================== 
    7 */ 
    8 
    9 #include <stdio.h> 
10 
11 int main(void){ 
12 
13  int v1 =0, v2=0; 
14  unsigned int sum; 
15  
16  v1 = 10; 
17  v2 = 20; 
18  
19  sum = v1 - v2; 
20  
21  printf("The subtraction of %i from %i is %i \n" , v1, v2, sum); 
22  
23  return 0; 
24 } 

der Ausgang ist: The subtraction of 10 from 20 is -10

+4

Auch Ihre Nachricht ist irreführend. Es sollte sagen "Die Subtraktion von ** 20 ** von ** 10 ** ist ...", was Sie berechnen. –

+0

Ich suche keine Lösung für ein solches Problem, ich möchte die Idee dazu verstehen. –

+0

Mögliches Duplikat von [C Unsigned int liefert einen negativen Wert?] (Http://stackoverflow.com/questions/1831753/c-unsigned-int-providing-a-negative-value) –

Antwort

22

%i der Spezifizierer für eine ganze Zahl signierten Format ist; Sie müssen %u verwenden, um eine Ganzzahl ohne Vorzeichen zu drucken.

+2

Denken Sie daran, weil vorzeichenlose Werte nur speichern können Nichtnegative Werte, die eine vorzeichenlose Ganzzahl von einer anderen subtrahieren, führen zu einem Unterlauf, wenn der Minuend kleiner als der Subtrahend ist. Dann erhalten Sie einen Unterlauf. Werfen Sie einen Blick: http://www.topbits.com/integer-overflow.html – LandonSchropp

1

Da unsigned int Wert, der in der Summe gespeichert ist wie signierte ganze Dezimalzahl behandelt wird in printf %i

8

Mit printf die %i Format gibt ein signed int. Verwenden Sie %u, um eine unsigned int auszugeben. Dies ist ein häufiges Problem beim Starten der C-Programmierung. Um Ihre Frage zu beantworten, ist das Ergebnis von v1 - v2 -10, aber sum ist ein unsigned int, so die echte Antwort ist wahrscheinlich so etwas wie 4294967286 (2 - 10). Sehen Sie, was Sie bekommen, wenn Sie The subtraction of %i from %i is %u \n verwenden. :)

6

Signed int und unsigned int haben die gleiche Größe im Speicher, der einzige Unterschied zwischen ihnen ist, wie Sie sie interpretieren. Signierte Werte verwenden eine Zweierkomplementdarstellung.

Wenn Sie 0xFFFFFFFF in einem 4-Byte-Speicherort, und dann fragen, was ist der Wert dort? Nun, wenn wir es als ein vorzeichenbehaftetes int interpretieren, dann ist es -1, aber wenn wir es als unsigned int interpretieren, dann ist der Wert 4294967295. So oder so ist es das gleiche Bitmuster, der Unterschied ist, was Sie bedeuten.

Wenn Sie 10 - 20 in einen unsigned int zugewiesen haben, haben Sie einen Wert von -10 berechnet (C führt keine Überlauf- oder Unterlaufüberprüfung durch), das ist ein Bitmuster von 0xFFFFFFF6, was -10 in einem vorzeichenbehafteten int oder bedeutet 4294967286 in einem unsigned int. Wenn Sie dann den Compiler (mit% i) anweisen, ein vorzeichenbehaftetes int zu drucken, dann interpretiert er dieses Bitmuster als signed int und gibt -10 aus, wenn Sie dem Compiler (unter Verwendung von% u) ein unsigned int dann ausgeben interpretiert dieses Bitmuster als unsigned und druckt 4294967286.

+0

Also, die Art, wie ich das Bitmuster interpretiere, steuert den Wert im Speicher. Danke. –

+0

Nun, der Wert "im Speicher" ist immer der gleiche. Sie sind die gleichen Bits. Was sich ändert, ist die Art und Weise, wie es ausgegeben wird. – Veky