Verkettung mehrerer Größer/Kleiner-als-Operatoren

Lesezeit: 4 Minuten

Benutzeravatar von jscode
jscode

In einem (n if Anweisung Ich möchte einen Bereich einschließen, zB:

if(10 < a < 0)

aber dabei erhalte ich eine Warnung “Sinnloser Vergleich”. Dies funktioniert jedoch ohne Vorwarnung:

if(a<10 && a>0)

Kann der erste Fall in C implementiert werden?

  • Was mir vorher nicht aufgefallen ist: (a>10 && a<0) ist für jeden möglichen Wert von falsch a. Meinten Sie (a>0 && a<10)?

    – Keith Thompson

    27. Januar 2012 um 10:43 Uhr

  • @KeithThompson (6 Jahre später) Nur für native Datentypen.

    – Benutzer202729

    10. Februar 2018 um 9:55 Uhr

  • @user202729 (12 Stunden später) C wird nicht unterstützt < und > für nicht-native Datentypen.

    – Keith Thompson

    10. Februar 2018 um 22:28 Uhr

  • @KeithThompson Entschuldigung, ich dachte, es wäre C++.

    – Benutzer202729

    11. Februar 2018 um 4:06 Uhr

Benutzeravatar von Keith Thompson
Keith Thompson

Beachten Sie, dass die Originalversion if(10 < a < 0) ist vollkommen legal. Es tut einfach nicht das, was Sie (vernünftigerweise) denken könnten. Sie haben Glück, dass der Compiler es als wahrscheinlichen Fehler erkannt und Sie davor gewarnt hat.

Das < Operator assoziiert von links nach rechts, genau wie die + Operator. Also genauso a + b + c wirklich bedeutet (a + b) + c, a < b < c wirklich bedeutet (a < b) < c. Das < -Operator ergibt einen int-Wert von 0, wenn die Bedingung falsch ist, und 1, wenn sie wahr ist. Sie testen also entweder, ob 0 kleiner als c ist, oder ob 1 kleiner als c ist.

In dem unwahrscheinlichen Fall, dass Sie das wirklich wollen, wird die Warnung durch das Hinzufügen von Klammern wahrscheinlich stummgeschaltet. Es wird auch allen, die Ihren Code später lesen, versichern, dass Sie wissen, was Sie tun, damit sie ihn nicht “reparieren”. (Auch dies gilt nur für den unwahrscheinlichen Fall, dass Sie Ja wirklich will (a < b) < c).)

Der Weg, um zu überprüfen, ob a ist weniger als b und b ist weniger als c ist:

a < b && b < c

(Es gibt Sprachen, einschließlich Python, wo a < b < c meint a<b && b<c, wie es in der Mathematik üblich ist. C ist einfach keine dieser Sprachen.)

  • Mit einigen Compilern, sagen (a < b) < c gibt immer noch eine Warnung: Vergleichen Sie die Ausgabe eines binären booleschen Werts mit int. Du musst sagen (int) (a < b) < c. 🙂

    – Alex

    21. Juni 2017 um 14:27 Uhr


  • @Alex: Nein, musst du nicht. Compiler können vor allem warnen, was sie wollen, aber (a < b) < c ist ein gültiger Ausdruck mit wohldefinierter Semantik. Die Umwandlung konvertiert nur einen Ausdruck, der bereits vom Typ ist int tippen int. Welcher Compiler warnt davor, und was ist die Warnung? (gcc und clang nicht.)

    – Keith Thompson

    21. Juni 2017 um 16:34 Uhr

Es ist nicht möglich, Sie müssen den Scheck wie in Fall 2 aufteilen.

Nein, das ist nicht möglich.
Sie müssen den zweiten Weg verwenden, indem Sie die beiden bedingten Prüfungen aufteilen.

Der erste führt einen Vergleich durch und vergleicht dann das Ergebnis des ersten mit dem zweiten Wert. In diesem Fall gruppieren die Operatoren von links nach rechts, also ist es äquivalent zu (10<a) < 0. Die Warnung, die es Ihnen gibt, ist wirklich, weil < ergibt immer 0 oder 1. Die Warnung sagt Ihnen, dass das Ergebnis des ersten Vergleichs niemals kleiner als 0 sein kann, sodass der zweite Vergleich immer falsch ergibt.

Auch wenn der Compiler sich nicht darüber beschweren wird, ist die zweite nicht wirklich viel Verbesserung. Wie kann eine Zahl gleichzeitig kleiner als 0, aber größer als 10 sein? Im Idealfall würde der Compiler Sie warnen, dass die Bedingung immer falsch ist. Vermutlich willst du 0<a<10 und a>0 && a<10.

Sie können den Effekt des zweiten mit nur einem einzigen Vergleich erhalten: if ((unsigned)a < 10) ist nur wahr, wenn die Zahl im Bereich 0..10 liegt. Ein Bereichsvergleich kann normalerweise auf einen einzigen Vergleich mit Code wie dem folgenden reduziert werden:

if ((unsigned)(x-range_start)<(range_end-range_start))
    // in range
else
    // out of range.

Früher war dies ein fester Bestandteil anständiger Assemblerprogrammierung. Ich bezweifle jedoch, dass viele Leute es noch tun (ich tue es sicherlich nicht in der Regel).

Wie oben erwähnt, müssen Sie den Scheck aufteilen. Betrachten Sie es aus der Sicht des Compilers, der jeweils einen Operator betrachtet. 10 < a = Wahr oder Falsch. Und dann macht es True/False < 0, was keinen Sinn ergibt.

  • Ich glaube nicht, dass die if-Anweisung sogar überprüft, ob wahr/falsch <0 oder nicht, auch wenn es Sinn macht oder nicht ... lol ...: D

    – nobalG

    5. August 2011 um 19:41 Uhr


Benutzeravatar von nobalG
nobalG

Nein, dies ist keine gültige Syntax der if-Anweisung, sie sollte einen gültigen konstanten Ausdruck haben oder logische Operatoren enthalten und wird nur ausgeführt, wenn der Ausdruck in der Klammer wahr oder ein Wert ungleich Null ist

  • Ich glaube nicht, dass die if-Anweisung sogar überprüft, ob wahr/falsch <0 oder nicht, auch wenn es Sinn macht oder nicht ... lol ...: D

    – nobalG

    5. August 2011 um 19:41 Uhr


1437580cookie-checkVerkettung mehrerer Größer/Kleiner-als-Operatoren

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy