Vergleich einer Variablen mit einem Wertebereich

Lesezeit: 5 Minuten

In der Mathematik die Notation 18 < age < 30 bedeutet, dass das Alter zwischen den Werten 18 und 30 liegen muss. Ist eine solche Schreibweise in der if-Anweisung möglich? Zum Beispiel habe ich versucht, auszuführen

if(18 < age < 30)

und ich bekomme eine seltsame Ausgabe, also ist es nicht ganz richtig. Gibt es eine Möglichkeit, dies zu tun, oder so muss ich einfach schreiben

if(age > 18) /*blah*/;
else if(age < 30) /*same blah*/;

  • Ihr Code ist falsch: Was ist, wenn das Alter gleich 65 ist? Sie führen blah aus, was Ihrer Beschreibung nach nicht das ist, was Sie erwarten.

    – Tibur

    30. September 2010 um 12:58 Uhr


Niemand hat geantwortet, was genau mit Ihrem Code passiert ist, also lassen Sie mich es auseinandernehmen.

Betrachten Sie die einzelne Aussage: bool result = 18 < age < 30;

Wir wollen den rechten Ausdruck auswerten: 18 < age < 30

Es gibt zwei Operatoren in diesem Ausdruck, und da sie identisch sind, haben sie beide die gleiche Priorität, in diesem Fall werden sie also von links nach rechts ausgewertet, daher ist der Ausdruck äquivalent zu:

(18 < age) < 30

Untersuchen wir also zuerst das linke Element: 18 < ageergibt es einen booleschen Wert, der entweder wahr oder falsch ist und typischerweise als ganzzahliger Wert bzw. 1 oder 0 dargestellt wird. Somit kann der Ausdruck wie folgt zusammengefasst werden:

{0,1} < 30

was immer stimmt.

Daher sollten Sie verwenden assert(18 < age < 30); es würde niemals nach hinten losgehen.

Diese implizite Konvertierung zwischen eingebauten Ganzzahl- (und Fließkomma-) Typen ist wirklich ärgerlich …

Vergleich einer Variablen mit einem Wertebereich
Tibur

Du kannst tun:

if (18 < age && age < 30) /*blah*/;

  • Du hast es. Könnte das erwähnen if( 18 < age < 30) ein zulässiger C++-Ausdruck ist, und erläutern Sie, wie er ausgewertet wird.

    – Johannes Dibling

    30. September 2010 um 12:58 Uhr

  • Aus Sicherheitsgründen werde ich gerne zusätzliche Klammern setzen. if((18 < Alter) && (30 > Alter))

    – Manoj R

    30. September 2010 um 13:05 Uhr


  • Der Betreiber < wird vorher ausgewertet &&. Es müssen also keine zusätzlichen Klammern verwendet werden.

    – Tibur

    30. September 2010 um 13:17 Uhr

  • @tibur, trotzdem macht es den Code leichter lesbar und formbarer für vim ci( 🙂

    – Alex B

    30. September 2010 um 13:26 Uhr

  • Ich bin mit ManoJ R beim Hinzufügen von Zahnspangen. Aber ich würde es für die Lesbarkeit tun.

    – Martin York

    30. September 2010 um 13:29 Uhr

Ein bisschen Vorlagencode kann hier helfen:

template <int min, int max> class range {
  static bool contains(int i) { return min <= i  && i < max; } // In C++, ranges usually are half-open.
};

int age = 23;
if (range<18,30>::contains(age)) { /****/ }

  • Sehr nützliches Stück Code, das überlegt, es zwischen Klassen mit überladenen Operatoren zu verwenden

    – neugierig

    6. Dezember 2019 um 8:45 Uhr


1646638211 393 Vergleich einer Variablen mit einem Wertebereich
Benutzer433534

Ist es möglich, diese Art der Notation in der if-Anweisung zu verwenden?

Ja, möglich.

Wünschenswert, kaum jemals: Programmierer gehen davon aus, dass die in anderen Antworten beschriebenen Verhaltensweisen immer gelten. Wenn Sie also die Reihenfolge der Auswertung und die Bedeutung eines Ausdrucks dramatisch ändern, wird dies sie wirklich sehr verwirren und – früher oder später – Kummer verursachen. Wenn Sie ein sehr kleines Projekt mit wenigen Mitarbeitern haben und diese im Grunde versuchen, eine domänenspezifische Sprache in C++ zu erstellen, in der die Notation der Domäne mit dieser Notation wirklich viel lesbarer und vertrauter ist (vielleicht sind sie sowieso Mathematiker und keine Programmierer). ), dann Sie könnte Ziehen Sie im Extremfall etwas in Betracht, das ich unten präsentiere, obwohl es wahrscheinlich immer noch Probleme verursachen wird.

Ich habe so etwas schon einmal vor Jahren als Sondierungsübung implementiert. Wenn Sie dies tun möchten, aber Hilfe beim Einstieg benötigen: aus dem Kopf (dh zweifellos fehlerhaft), überlegen Sie:

struct Weird
{
    Weird(int n) : n_(n), b_is_meaningful_(false) { }
    Weird(int n, bool b) : n_(n), b_is_meaningful_(true), b_(b) { }

    int n_;

    bool b_is_meaningful_;
    bool b_;
};

Weird operator<(Weird lhs, Weird rhs)
{
    if (lhs.b_is_meaningful_)
        if (!lhs.b_) // effectively, anding with something already known false...
            return Weird(rhs.n_, false);
    return Weird(rhs.n_, lhs.n_ < rhs.n_);
}

Im Grunde hacken Sie es herum, bis Sie können:

Weird x = 10;
assert(6 < x < 20 < 30 < Weird(80));

An jedem Punkt, der operator< schafft ein neues Weird Objekt mit dem Wert für die rechte Seite (rhs), während der boolesche Zustand unter der Annahme aktualisiert wird, dass Sie effektiv eine Reihe von Vergleichen zusammenführen. Wenn Sie wirklich ein Chaos anrichten wollen, können Sie alle möglichen Dinge in C++ unterstützen, Sie könnten zum Spaß “x == 6 || 3 || 56” sagen …?

Sie können einen booleschen Ausdruck schreiben als

((18 < age) && (age < 30))

Ein Ausdruck wie der obige kann überall dort verwendet werden, wo ein boolescher Ausdruck akzeptabel ist, zum Beispiel (aber nicht beschränkt auf):

if((18 < age) && (age < 30)) { ... }

oder

bool age_in_range = ((18 < age) && (age < 30));

Beachten Sie, dass der obige Ausdruck verwendet Kurzschlussauswertung von operator &&.

  • Wenn Sie es gewohnt sind, rvalues ​​auf der linken Seite von Operatoren zu platzieren, warum nicht auch für (Alter < 30)?

    – Chubsdad

    1. Oktober 2010 um 8:38 Uhr

  • Ich ziehe es vor, die Vergleiche von Zahlen in der Reihenfolge zu schreiben, in der sie auf dem Zahlenstrahl stehen. en.wikipedia.org/wiki/Number_line

    – Arun

    1. Oktober 2010 um 16:25 Uhr

  • Ich würde der Vorstellung widersprechen, dass die obigen Ausdrücke “Kurzschlussbewertung verwenden”; sie verlassen sich nicht auf dieses Verhalten.

    – Oliver Charlesworth

    1. Oktober 2010 um 19:02 Uhr

  • Vielleicht irre ich mich, aber ich dachte, wenn das Alter so ist, dass der erste Ausdruck ist (18 < age) ist falsedann wird der zweite Ausdruck nicht ausgewertet.

    – Arun

    1. Oktober 2010 um 20:07 Uhr

  • Sie haben Recht, aber da keiner der Ausdrücke Nebenwirkungen hat (vorausgesetzt age ist entweder ein Basistyp oder eine Klasse mit einer vernünftigen Überladung für operator<), das ist völlig egal!

    – Oliver Charlesworth

    1. Oktober 2010 um 21:00 Uhr

1646638212 633 Vergleich einer Variablen mit einem Wertebereich
mmmmmm

Ich kenne keine Möglichkeit, genau das zu tun, was Sie verlangen, aber der normale Weg ist

Verwenden Sie den and-Operator

wenn (Alter > 18 && Alter <30)

  • Wenn Sie es gewohnt sind, rvalues ​​auf der linken Seite von Operatoren zu platzieren, warum nicht auch für (Alter < 30)?

    – Chubsdad

    1. Oktober 2010 um 8:38 Uhr

  • Ich ziehe es vor, die Vergleiche von Zahlen in der Reihenfolge zu schreiben, in der sie auf dem Zahlenstrahl stehen. en.wikipedia.org/wiki/Number_line

    – Arun

    1. Oktober 2010 um 16:25 Uhr

  • Ich würde der Vorstellung widersprechen, dass die obigen Ausdrücke “Kurzschlussbewertung verwenden”; sie verlassen sich nicht auf dieses Verhalten.

    – Oliver Charlesworth

    1. Oktober 2010 um 19:02 Uhr

  • Vielleicht irre ich mich, aber ich dachte, wenn das Alter so ist, dass der erste Ausdruck ist (18 < age) ist falsedann wird der zweite Ausdruck nicht ausgewertet.

    – Arun

    1. Oktober 2010 um 20:07 Uhr

  • Sie haben Recht, aber da keiner der Ausdrücke Nebenwirkungen hat (vorausgesetzt age ist entweder ein Basistyp oder eine Klasse mit einer vernünftigen Überladung für operator<), das ist völlig egal!

    – Oliver Charlesworth

    1. Oktober 2010 um 21:00 Uhr

1646638215 767 Vergleich einer Variablen mit einem Wertebereich
David

Oder schreiben Sie sich selbst einen netten Satz von Funktionen, die dies tun

template <typename type>
bool in_range_[none|both|low|high]<type>( value, min, max )

um allen Arten von Grenzen gerecht zu werden, die enthalten sind oder nicht

(verwenden Sie dies nicht für Fließkommazahlen)

In C++0x könnten Sie alle anderen Möglichkeiten zulassen oder verbieten, indem Sie das Schlüsselwort „delete“ verwenden, das Funktionen für Überladungen wie deaktiviert

963990cookie-checkVergleich einer Variablen mit einem Wertebereich

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

Privacy policy