Frage

Siehe diesen Code -Snippet

int main()
{ 
 unsigned int a = 1000;
 int b = -1;
 if (a>b) printf("A is BIG! %d\n", a-b);
 else printf("a is SMALL! %d\n", a-b); 
 return 0;
}   

Dies gibt die Ausgabe: a ist klein: 1001

Ich verstehe nicht, was hier passiert. Wie funktioniert der> Bediener hier? Warum ist "a" kleiner als "B"? Wenn es in der Tat kleiner ist, warum bekomme ich dann eine positive Zahl (1001) als Unterschied?

War es hilfreich?

Lösung

Binäre Operationen zwischen verschiedenen Integraltypen werden innerhalb eines "gemeinsamen" Typs durchgeführt, der von so genannt definiert wird übliche arithmetische Konvertierungen (Siehe die Sprachspezifikation, 6.3.1.8). In Ihrem Fall ist der "gemeinsame" Typ unsigned int. Das bedeutet, dass int Operand (Ihr b) wird zu konvertiert zu unsigned int vor dem Vergleich sowie zum Zweck der Durchführung der Subtraktion.

Wann -1 wird in konvertiert zu unsigned int Das Ergebnis ist das maximal möglich unsigned int Wert (gleiche wie UINT_MAX). Unnötig zu erwähnen, dass es größer sein wird als Ihre vorzeichenlosen 1000 Wert, bedeutet das a > b ist in der Tat falsch und a ist in der Tat klein verglichen mit (unsigned) b. Das if in Ihrem Code sollte sich auflösen else Zweig, was Sie in Ihrem Experiment beobachtet haben.

Die gleichen Konvertierungsregeln gelten für die Subtraktion. Dein a-b wird wirklich interpretiert als a - (unsigned) b und das Ergebnis hat Typ unsigned int. Ein solcher Wert kann nicht mit gedruckt werden %d Formatspezifizierer seitdem %d funktioniert nur mit unterzeichnet Werte. Ihr Versuch, es mit zu drucken %d führt zu undefiniertem Verhalten, so dass der Wert, den Sie sehen (auch wenn er in der Praxis eine logische deterministische Erklärung hat), aus Sicht der C -Sprache völlig bedeutungslos ist.

Bearbeiten: Eigentlich könnte ich mich in Bezug auf den undefinierten Teil des Verhaltens irren. Gemäß der C -Sprachspezifikation muss der gemeinsame Teil des Bereichs des entsprechenden signierten und unsignierten ganzzahligen Typs eine identische Darstellung haben (impliziert, wie die Fußnote 31 "Austauschbarkeit als Argumente für Funktionen"). Also das Ergebnis von a - b Ausdruck ist nicht signiert 1001 Wie oben beschrieben, und es sei denn, es fehlt mir etwas, ist es legal, diesen spezifischen nicht signierten Wert mit zu drucken %d Spezifizierer, da es in den positiven Bereich von fällt int. Drucken (unsigned) INT_MAX + 1 mit %d würde undefiniert sein, aber 1001u ist gut.

Andere Tipps

Bei einer typischen Implementierung wo int ist 32 -Bit, -1, wenn er zu einem konvertiert wird unsigned int ist 4.294.967.295, was in der Tat ≥ 1000 ist.

Auch wenn Sie die Subtraktion in einem behandeln unsigned Welt, 1000 - (4,294,967,295) = -4,294,966,295 = 1,001 Welches ist was du bekommst.

Deshalb gcc wird eine Warnung spucken, wenn Sie vergleichen unsigned mit signed. (Wenn Sie keine Warnung sehen, bestehen Sie die -Wsign-compare Flagge.)

Sie führen einen vorzeichenlosen Vergleich durch, dh 1000 bis 2^32 - 1.

Die Ausgabe wird aufgrund von %d in printf signiert.

NB manchmal ist das Verhalten, wenn Sie signierte und nicht signierte Operanden mischen, Compiler-spezifisch. Ich denke, es ist am besten, sie zu meiden und Casts zu machen, wenn Sie Zweifel haben.

Finden Sie eine einfache Möglichkeit zu vergleichen, vielleicht nützlich, wenn Sie die nicht signierte Erklärung nicht beseitigen können (z. B. [NSArray Count]), nur die "nicht signierte int" zu einem "int" erzwingen.

Bitte korrigieren Sie mich, wenn ich falsch liege.

if (((int)a)>b) {
    ....
}

Die Hardware ist so konzipiert, dass sie mit signiertem und nicht signiertem Unsigned unterzeichnet ist.

Wenn Sie das arithmetische Ergebnis wünschen, konvertieren Sie den nicht signierten Wert zuerst in einen größeren signierten Typ. Andernfalls geht der Compiler davon aus, dass der Vergleich wirklich zwischen nicht signierten Werten liegt.

Und -1 wird als 1111..1111 dargestellt, also ist es eine sehr große Menge ... das größte ... wenn es als nicht signiert interpretiert wird.

 #include<stdio.h>
 int main()
 {
   int a = 1000;
   signed int b = -1, c = -2;
   printf("%d",(unsigned int)b);
   printf("%d\n",(unsigned int)c);
   printf("%d\n",(unsigned int)a);

   if(1000>-1){
      printf("\ntrue");
   }
   else 
     printf("\nfalse");
     return 0;
 }

Dafür müssen Sie die Vorrang vor Operatoren verstehen

  1. Relationale Operatoren arbeiten von links nach rechts ... also, wenn es umsetzt

    if (1000> -1)

Zuerst ändert sich es zuerst -1 in die unsignierte Ganzzahl, da die int standardmäßig als nicht signierte Zahl behandelt wird und es größer ist als die signierte Zahl

-1 ändert sich in die nicht signierte Zahl, sie ändert sich in eine sehr große Zahl

Beim Vergleich von a> b wobei a unsigned int type und b int type ist, B ist Typ gegossen in nicht signiertes int gegossen Daher wird der signierte Int -Wert -1 in maximaler Wert von nicht signiert ** (Bereich: 0 bis (2^32) -1) ** Daher wird a> b ie, (1000> 4294967296) falsch. Daher sonst Schleife printf ("a ist klein! %d n", ab); hingerichtet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top