C++ Verständnisfrage zu logischem Operator
-
Hi Leute,
ich bin schon länger auf der Suche nach einer Erklärung für das Verhalten von folgendem Code:
#include <iostream> using namespace std; int x, y, Variable; char ende; int main () { do { cout << "Bitte x eingeben: "; cin >> x; cout << "Bitte y eingeben: "; cin >> y; Variable = x > 3 && y < 4; cout << Variable << endl; cout << "Beenden mit <e> oder <E>" << endl; cin >> ende; } while (ende != 'e' || ende != 'E');Mir geht es jetzt um die do-while Schleife. Nach meiner Logik müsste das Programm nach der Eingabe von <e> oder <E> abbrechen.
Das Programm läuft aber weiter. Ich weiß, daß das Programm mit einer && Verknüpfung so funktionieren würde wie ich es geplant hatte.
Mir geht es jetzt darum das Verhalten zu verstehen:
bei einer und-Verknüpfung müssten ja beide Bedingungen zutreffen, aber das kann ja nie der Fall sein, Variable "ende" kann nicht e und E gleichzeitig sein.
Umgekehrt bei der oder-Verknüpfung muß ja nur eine Bedingung zutreffen. Das ist doch im oberen Beispiel der Fall. Wie gesagt nach meinem Verständnis...
Kann mich bitte bitte irgendwer aufklären,warum die oder-Verknüpfung im Beispiel oben so nicht funktioniert???
Das wär echt supernett.Danke

-
Mindestens einer der beiden Ver(un)gleiche ist wahr für jeden beliebigen Wert von 'ende' (falls ende gleich 'e' dann ist es auf jeden Fall ungleich 'E' und andersherum). Der Gesamtausdruck (durch logische Oder-Verknüpfungen) ist dann auch immer wahr und damit entsteht eine Endlosschleife.
-
Okay, also ich hab deine Antwort einige Male durchgelesen, halt mich jetzt nicht für doof, aber ich habs noch nicht verstanden... Ich werd's später nochmal lesen, ich glaub ich steh am Schlauch(vielleicht sollt ich mehr schlafen
)Aber besten Dank für die schnelle Antwort!!!
-
(ende != 'e' || ende != 'E')Die Schleife wird solange durchlaufen, wie
endeungleich 'e' oderendeungleich 'E' ist. Diese Bedingung ist logisch äquivalent zu Folgendem (De Morgan)!(ende == 'e' && ende == 'E')Also solange, wie nicht beide Bedingungen wahr sind. Und da dieser Fall nie eintritt, hast du eine Endlosschleife.
-
Besten Dank Nexus,
mittlerweile hats klick gemacht
Hab ja schon langsam an meinem Verstand gezweifelt...
Ist ja eigentlich logisch, aber ab und zu sieht man den Baum vor lauter Wäldern nicht
Nochmals Danke!
-
waildo schrieb:
mittlerweile hats klick gemacht
Hab ja schon langsam an meinem Verstand gezweifelt...
Ist ja eigentlich logisch, aber ab und zu sieht man den Baum vor lauter Wäldern nicht
Nicht desto trotz:
a) globale Variablen sollte man in der Regel meiden
b) Sinnvolle Einrückungen auf Scopeebene machen das lesen ungemein leichter
-
Alternativ geht auch folgendes:
#include <locale> //... do { //... } while(std::tolower(ende, std::locale()) != 'e');So wirde
endeimmer in Kleinbuchstaben gewandelt, und Du bist losgelöst von Groß- und Kleinschreibung.
-
asc schrieb:
waildo schrieb:
mittlerweile hats klick gemacht
Hab ja schon langsam an meinem Verstand gezweifelt...
Ist ja eigentlich logisch, aber ab und zu sieht man den Baum vor lauter Wäldern nicht
Nicht desto trotz:
a) globale Variablen sollte man in der Regel meiden
b) Sinnvolle Einrückungen auf Scopeebene machen das lesen ungemein leichter@ asc :
Hi asc,
zu b): da hast natürlich recht die Einrückungen erhöhen die Lesbarkeit, im Original ist es auch eingerückt, hab da wahrscheinlich was falsch gemacht beim einfügen in den "Nachrichtentext"
zu a): Welchen Vorteil bringt es wenn ich die Variablen erst im scope deklariere? Hab erst vor kurzem mit C++ angefangen (ist wahrscheinlich eh offensichtlich)

Ich bin für jeden Tipp dankbar.
@ Tachyon :
Interessant,
danke für die Alternative
-
waildo schrieb:
zu a): Welchen Vorteil bringt es wenn ich die Variablen erst im scope deklariere?
Die Variablen sind dann auch nur innerhalb des Scopes bekannt. Also falls zum Beispiel noch irgendwelche anderen Funktionen vorkommen sollten, kennen sie die Variablen nicht.
In C++ versucht man oft, die Rechte möglichst einzuschränken und somit Fehlerquellen zu vermeiden. Das wirst du auch später bei den Klassen, Kapselung und Const-Correctness sehen. Gleiches gilt hier: Da du die Variablen nur in
main()brauchst, sollten sie auch nur dort bekannt sein. Bei deinem kleinen Programm spielt diese Thematik vielleicht noch nicht so eine Rolle, aber besser, du gewöhnst sie dir gleich an.
-
Werd' ich künftig so machen, find ich ja gut wenn ich zukünftige Fehler vermeiden bzw. verringern kann !

-
waildo schrieb:
Werd' ich künftig so machen, find ich ja gut wenn ich zukünftige Fehler vermeiden bzw. verringern kann !

Ich habe noch weitere Gründe:
1. Die Reihenfolge der Initialisierung globaler Objekte ist nicht immer sicher (Dies ist wichtig wenn es eine Abhängigkeit zwischen globalen Variablen unterschiedlicher Übersetzungseinheiten gibt).Nehmen wir folgendes an:
Du hast in einer Übersetzungseinheit eine globale Variable deklariert, in einer anderen Übersetzungseinheit deklarierst du eine globale Variable die du direkt über den Wert der anderen initialisierst.Da die Reihenfolge undefiniert ist, kann es sein, das erstere noch gar nicht initialisiert wurde (Gab mal einen sehr schwere Fehlersuche in einem Projekt - danach konnte ich den Projektleiter ENDLICH davon überzeugen das globale Variablen gefährlich sein können).
2. Unkontrollierbarer Zugriff. Jeder kann sie ändern, du hast keine Kontrollmöglichkeit. Es mag zwar vielleicht eine Zeit gewünscht sein, aber die Umstellung kann komplizierter sein, als wenn man von vorne herein eine gewisse Kapselung macht.
usw.