Boolesche Werte - Unklarheit

06/16/2012 00:28 aeo#1
Ich bins wieder und mal wieder belästige ich euch mit meinen Fragen & Unklarheiten.

Momentan bin ich an dem Kapitel "Operatoren und ihre elementaren Datentypen" gelangt und am Ende des Kapitels verstehe ich den Quellcode nicht.

Ein kleiner Ausschnitt vom Quellcode

PHP Code:
bool erg false;
int y 5;
erg || (5);
cout << "Wert von (7 || (y = 0 )): " << erg << endl;
cout << "Wert von y: " << << endl
Warum setzt der Autor das Objekt erg auf false und dann weißt später dem Objekt den Wert 7 zu?
Der Ausdruck "7 || y = 0" beinhaltet kein Vergleichsoperator, warum ist aber dann der gesamte Ausdruck true?
Wenn das an der "7" liegt, ich dachte Vergleichsoperatoren, wie &&, || haben eine höhere Priorität als Zuweisungsoperatoren.
Warum hat y am Schluss den Wert 5? Wenn es im Ausdruck den Wert 0 zugewiesen bekommen hat?



Bei der Ausgabe sieht es wie folgt aus:

Quote:
Wert von (7 || ( y = 0 )): true
Wert von y = 5;
Der Autor hat auch keine Bemerkung zu dem Quellcode gegeben.
Ich habe mir gründlich die Seiten angeschaut und sorgfältig durchgelesen.
Wahrscheinlich liegt es hier an der mangelnden Erklärungsweise.

PS: Falls jemand mir seine Hilfe im Bereich C++ anbietet, kann er mir gerne seinen Skype-Namen hinterlassen.
So kann ich mich an jemanden wenden und fragen.
06/16/2012 01:27 Dr. Coxxy#2
sicher, dass du alles richtig abgeschrieben hast?
das da ist nämlich mehr als erbärmlich.

ok, ich erklärs mal zeile für zeile:

Code:
bool erg = false;
hier wird ein bool 'erg' erstellt und mit false initialisiert, die initialisierung ist eigtl unnötig, da nachher sowieso darauf geschrieben wird, ohne dass vorher davon gelesen wird.

Code:
int y = 5;
ein int 'y' wird mit 5 initialisiert.

Code:
erg = 7 || (y = 5);
erste zeile die wenig sinn macht.
dort wird nun folgendes getan:
zuerst wird "7" auf wahrheit überprüft, da es != 0 ist, ist es true.
das ODER wird nun garnicht mehr ausgeführt, da das erste bereits wahr war, d.h. in erg ist nun true.
wenn es weitergegangen wäre, würde nun 5 auf y zugewiesen werden und dies dann ebenfalls auf wahrheit überprüft werden.
Da 5 != 0 ist, wäre dies ebenfalls wahr, spielt aber wie gesagt keine rolle, da der code nie ausgeführt wird.

Code:
cout << "Wert von (7 || (y = 0 )): " << erg << endl;
hier wird auf der console "Wert von (7 || (y = 0 )): " ausgegeben, man beachte, dass es nur eine ausgabe ist, hier wird kein code ausgeführt!
dann wird erg hinterher ausgegeben was wie gesagt true ist.
und noch ein zeilenumbruch hinterher.

Code:
cout << "Wert von y: " << y << endl;
der string "Wert von y: " wird ausgegeben, dann der wert von y, der durch die initialisierung
Code:
int y = 5;
= 5 ist und wieder ein zeilenumbruch.


ka, was dieser merkwürdige code soll, vielleicht demonstrieren wie leicht fehler passieren können wenn man zuweisung und vergleich vertauscht?
06/16/2012 01:33 ms​#3
Zunächst einmal ist in deiner dritten Zeile wahrscheinlich eigentlich "7 || (y = 0)" gemeint.

Quote:
Originally Posted by dunkis View Post
Warum setzt der Autor das Objekt erg auf false und dann weißt später dem Objekt den Wert 7 zu?
Er weißt erg später nicht 7 zu, sondern das Ergebnis von "7 || (y = 5)".

Quote:
Originally Posted by dunkis View Post
Der Ausdruck "7 || y = 0" beinhaltet kein Vergleichsoperator, warum ist aber dann der gesamte Ausdruck true?
Du meinst "7 || (y = 0)".
Der ||-Operator ist ein logisches OR. Das heißt, wenn entweder der linke oder der rechte Operand ("7" ist der linke Operand; "y = 0" ist der rechte Operand) oder alle beide true sind, ist der gesamte Ausdruck true. Bei beiden Operanden handelt es sich um Integer-Werte, d.h. 0 wird als false gewertet, alles andere ist true. Zuweisungen wie "y = 0" haben als Resultat den Wert, der dem Objekt zugewiesen wird (in diesem Fall die 0). Vereinfacht ist also der Ausdruck "7 || 0", bzw. "true || false". Deswegen wird erg true zugeordnet.

Quote:
Originally Posted by dunkis View Post
Wenn das an der "7" liegt, ich dachte Vergleichsoperatoren, wie &&, || haben eine höhere Priorität als Zuweisungsoperatoren.
Da hast du Recht. Durch die Klammern bekommt "y = 0" allerdings - wie in mathematischen Formeln - eine höhere Priorität.

Quote:
Originally Posted by dunkis View Post
Warum hat y am Schluss den Wert 5? Wenn es im Ausdruck den Wert 0 zugewiesen bekommen hat?
Das liegt daran, dass sowohl "||", als auch "&&" in C/C++ sogenannte "Short-Circuit-Operatoren" sind. Das heißt, wenn aus dem linken Operanden schon das Ergebnis hervorgeht, wird der rechte Operand gar nicht erst evaluiert.
In unserem Beispiel ist der linke Operand "7" und der rechte Operand "y = 0". Schwammig formuliert heißt das, das Programm schaut sich zunächst nur den linken Operanden an, sieht dass er "true" ist und überspringt den rechten Operanden einfach. Wenn der linke Operand beim logischen OR "true" ist, ist nämlich der gesamte Ausdruck auch immer "true".
06/17/2012 18:52 Mikesch01#4
Quote:
Originally Posted by Metin2Spieler97 View Post
Das liegt daran, dass sowohl "||", als auch "&&" in C/C++ sogenannte "Short-Circuit-Operatoren" sind. Das heißt, wenn aus dem linken Operanden schon das Ergebnis hervorgeht, wird der rechte Operand gar nicht erst evaluiert.
In unserem Beispiel ist der linke Operand "7" und der rechte Operand "y = 0". Schwammig formuliert heißt das, das Programm schaut sich zunächst nur den linken Operanden an, sieht dass er "true" ist und überspringt den rechten Operanden einfach. Wenn der linke Operand beim logischen OR "true" ist, ist nämlich der gesamte Ausdruck auch immer "true".
Genau, wenn du diese Verarbeitung trotzdem haben möchtest, musst du den einfachen ODER-Operator verwenden. Dies schaut dann so aus:

Code:
erg = 7 | (y = 0)
Hier erfolgt die Zuweisung, auch wenn der erste Wert bereits true ist.
06/18/2012 13:41 aeo#5
PHP Code:
bool erg false
int y 5
erg || (0); 
cout << "Wert von (7 || (y = 0 )): " << erg << endl
cout << "Wert von y: " << << endl
Der Code ist nun definitiv richtig. Es handelte sich hierbei um einen kleinen Fehler beim Abschreiben.
Anstatt erg = 7 || (y=5); waren das: erg = 7 || (y=0);

Der Autor meint das anscheinend ernst aber manchmal kann ich seinen Gedanken nicht ganz folgen und haare dort einige Stunden an einer Lektion.

Ich habe das Problem nun ignoriert auch wenn es mich im Unterbewusstsein weiterhin nervt.
Edit:// Hab es nun verstanden - Bedanke mich an allen die mir das im Detail erklärt haben.
Off-Topic:

PHP Code:
int main()
{
    
cout << "Dieses Programm entaehlt \"for\"-Schleifen" << endl;
    
int eingabezaehler 1grenze 5;
    for(; 
cin >> eingabe &&  !(zaehler == grenze); ++zaehler);
    {
        
cout << "Das war eine erfolgreiche Eingabe " << zaehler << endl;

    }
    
cout << "Hallo" << endl;
    return 
0;


Wenn ich keine eingabe mache z.B. einen anderen Datentyp eingebe.
Da es den Return-Wert int erwartet, gebe ich a ein.
Der Zaehler ist dann auf 1, dass liegt dann daran das die Zuweisung auf 1 ist.
Aber wenn ich sie auf "0" stelle erwartet er 6 Angaben.

Kann ich den Wert von Zaehler nicht auf "0" stellen so dass er 5 Angaben erwartet?
06/18/2012 15:06 2n0w#6
!(zaehler == grenze - 1) ? ^^
06/18/2012 15:47 phreeak#7
Quote:
Originally Posted by 2n0w View Post
!(zaehler == grenze - 1) ? ^^

this.

wenn du von 0 anfängst, zählt er 0,1,2,3,4,5. Somit wären es 6 Angaben. Ist der Anfang auf 1 wären es 5 Angaben, da er 1,2,3,4,5 zählt.

Also Entweder grenze einen Runter oder so wie es im Quote steht, was wohl eleganter ist, meiner Meinung nach. So kann man später an der Variable direkt noch nachvollziehen, was es macht.
06/18/2012 16:12 Nightblizard#8
Darf ich fragen welches Buch du nutzt und aus welchem Kapitel du das Beispiel entnommen hast?
erg = 7 || (y=0); ist nämlich absoluter Schwachsinn. :/
06/18/2012 16:46 2n0w#9
Also für mich sieht es so aus als sollte das Beispiel Short-Circuit-Operatoren demonstrieren, also könnte das ja schon Sinn haben, meiner Meinung nach.
Wäre halt nicht schlecht vom Autor gewesen das auch im Buch zu erklären.
06/18/2012 19:44 MrSm!th#10
Quote:
Originally Posted by Mikesch01 View Post
Genau, wenn du diese Verarbeitung trotzdem haben möchtest, musst du den einfachen ODER-Operator verwenden. Dies schaut dann so aus:

Code:
erg = 7 | (y = 0)
Hier erfolgt die Zuweisung, auch wenn der erste Wert bereits true ist.
Nein, das ist die binäre Oder-Verknüpfung :facepalm:

Quote:
Also für mich sieht es so aus als sollte das Beispiel Short-Circuit-Operatoren demonstrieren, also könnte das ja schon Sinn haben, meiner Meinung nach.
Wäre halt nicht schlecht vom Autor gewesen das auch im Buch zu erklären.
Dennoch sieht es ziemlich schlecht aus, denn so ein geniales Beispiel könnte Anfänger auch direkt mal in Sachen Zuweisung <-> Vergleich verwirren, da dort ja y 0 zugewiesen wird und man in booleschen Ausdrücken normalerweise vergleicht.
06/18/2012 20:46 Nightblizard#11
Quote:
Originally Posted by 2n0w View Post
Also für mich sieht es so aus als sollte das Beispiel Short-Circuit-Operatoren demonstrieren, also könnte das ja schon Sinn haben, meiner Meinung nach.
Wäre halt nicht schlecht vom Autor gewesen das auch im Buch zu erklären.
Jup, ich wollte das oben noch erwähnen, aber dann bekam ich dieses "juckt ja eh keinen"-feeling und habe es einfach sein gelassen. Daher auch die Frage nach dem Kapitel.

Naja, mal schauen ob dunkis nochmal antwortet, das würde mich jetzt wirklich interessieren.
06/18/2012 21:06 2n0w#12
Quote:
Originally Posted by MrSm!th View Post
Nein, das ist die binäre Oder-Verknüpfung :facepalm:
Die durchaus den gewünschten Effekt hat. ^^
06/18/2012 21:38 MrSm!th#13
Quote:
Originally Posted by 2n0w View Post
Die durchaus den gewünschten Effekt hat. ^^
Aber nicht, weil da Ausrücke ausgewertet werden und im Gegenteil zu || der zweite auch noch, wenn der erste schon true ist, sondern einfach weil nunmal die Werte binär verknüpft werden und da braucht er logischerweise beide Operanden.
06/18/2012 21:54 Mikesch01#14
Quote:
Originally Posted by MrSm!th View Post
Aber nicht, weil da Ausrücke ausgewertet werden und im Gegenteil zu || der zweite auch noch, wenn der erste schon true ist, sondern einfach weil nunmal die Werte binär verknüpft werden und da braucht er logischerweise beide Operanden.
Da muss ich mich entschuldigen. Ich habe nicht vermutet, das die Syntax von c++ in dieser Hinsicht zu Java so abweicht. In Java wäre meine Aussage vollkommen richtig. Sorry ;(
06/18/2012 22:45 MrSm!th#15
Kein Problem, im Grunde hat es, wie 2n0w schon sagte, trotzdem letztendlich dieselbe Wirkung. Habe da nicht sofort dran gedacht.