Division und Rest
-
Hallo,
wenn das Ergebnis der Division von a und b ohne Rest ergibt soll true ausgegeben
werden, andernfalls falseWo liegt der Fehler?
Danke
Lou#include <iostream> using namespace std; int main() { unsigned int a; unsigned int b; bool erg_div = a%b; cout << "Gib zwei Zahlen für Division ein" << endl; cin >> a; cin >> b; cout << boolalpha << a << " ist Teiler von " << b << ":" << (erg_div == true) << endl; return 0; }
-
@Lou-Cyphr3
In C++ werden die Befehle der Reihe nach abgearbeitet.Dort, wo du die Rechnung ausführst (Zeile 9), sind a und b noch nicht initialisiert.
in Zeile 18 greifst du auf das Ergebnis dieser Berechnung zu.
(da wird nicht nochmal gerechnet).
-
Es geht ja primär auch um den Vergleich.
Im übrigen wenn ich erst in Zweile 18 rechnen lasse, bekomm ich nen Error.
Könnte am Compiler liegen.
-
-
Weiters ist auch die Bedingung falsch.
a % bist der Rest der bei der Divisiona / bübrig bleibt, als Ganzzahl. D.h.a % bist Null wenn die Division ohne Rest möglich ist. Und bei der Konvertierung einer Ganzzahl in einen boolschen Ausdruck wird Null zufalsekonvertiert und alles andere zutrue.D.h.
a % b, nachboolkonvertiert, ist immer danntruewenn die Division nicht ohne Rest möglich ist.
-
@Lou-Cyphr3 sagte in Division und Rest:
Im übrigen wenn ich erst in Zweile 18 rechnen lasse, bekomm ich nen Error.
Könnte am Compiler liegen.Na dann probier's mal mit Zeile 15. Oder mit C++ Lernen

-
Okay danke . Ich habs jetzt. Ich bin jetzt den Weg über ungleich true gegangen.
-
Also ich fände ja
(a % b) == 0deutlich besser zu lesen/verstehen. Ganz abgesehen davon dass Vergleiche mittruesowieso ... "gefährlich" sind.
-
@hustbaer sagte in Division und Rest:
.Ganz abgesehen davon dass Vergleiche mit
truesowieso ... "gefährlich" sind.Echt? Das überrascht mich jetzt. Kannst du das näher erklären?
-
In C gilt der Wert 0 als falsch, alles andere als wahr. ( also auch 2 oder -12345)
falseist 0
!false(not false) alsotrueist 1123 % 10 = 3, also wahr. Aber der Vergleich mit
trueist nicht erfolgreich.
-
Ein boolscher Wert ist schon entweder
trueoderfalse, d.h. du brauchst nicht mehr zu vergleichen:cout << erg_div << endl;
-
@Lou-Cyphr3 sagte in Division und Rest:
@hustbaer sagte in Division und Rest:
.Ganz abgesehen davon dass Vergleiche mit
truesowieso ... "gefährlich" sind.Echt? Das überrascht mich jetzt. Kannst du das näher erklären?
Man kann bei Refactorings leicht die Konvertierung nach
boolübersehen.
Beispiel:bool foo = a % b; if (foo != true) { // ... }Refactoring: "unnötige" Variable entfernen. Ergebnis:
if ((a % b) != true) { // ... }Und schwupps haben wir ein gänzlich anderes Verhalten.
Im neuen Code wird jetzttruein einen Integer-Typ mit Wert 1 konvertiert, und dann mit dem Ergebnis vona % bverglichen.
Im alten Code ist die Bedingung wahr wenna % bgleich 0 ist. Im neuen Code ist die Bedingung wahr wenna % bungleich 1 ist.Weiters gibt es etliche APIs die einen wahr/falsch Wert als Integer zurückgeben - die WinAPI ist z.B. voll davon. Auch hier gilt dass 0 für
falsesteht und alles andere fürtrue. Und auch hier ist nicht sicher dass "alles andere" immer nur 1 ist - es kann irgend ein Wert ausser 0 sein.=> Mit
truevergleichen ist potentiell gefährlich.Weiters ist es auch unnötig. Statt
if (x == true)kann man genau so gutif (x)schreiben und stattif (x != true)kann manif (!x)schreiben.
(Vorausgesetztxist ein Ausdruck dessen Wert vom Typboolist. Wenn der Typ nichtboolist macht es natürlich einen Unterschied - genau darum geht's ja.)Vergleiche mit
falsesind weniger problematisch, aber genau so unnötig.
-
Wenn man Spaß daran hat, kann man das sogar weiter treiben (schon so ähnlich im Code gesehen):
bool x; if (functionReturningBool() == true) x = true; else x = false; bool y = x ? true : false; if (y == true) { ... }
-
@hustbaer
Danke für die Ausführung.
Ich bin nur verwirrt weil ich heute explizit meinen Lehrer danach gefragt habe
und er nochmals fürtrueundfalseplädiert hat.
Ich frage mich gerade wann überhaupt bool einsetzten?
-
@Lou-Cyphr3 sagte in Division und Rest:
Ich frage mich gerade wann überhaupt bool einsetzten?
@hustbaer hat ja nicht gesagt, nie bool zu benutzen, sondern die Form des Vergleichs zu vermeiden, die du benutzt hast. Das ist ein ganz großer Unterschied.
Ich zitiere mich mal aus einem anderen Thread von heute: Ein Programm sollte sich wie ein Text lesen lassen.
Welcher Text klingt besser?
"Das Ergebnis ist wahr"
"Das Ergebnis ist gleich der Wahrheit"Generell ist bool aber offensichtlicherweise für die Dinge gut, für die es gemacht ist. Also Dinge, die wahr oder falsch sein können. Als Ergebnis einer Rechenoperation ist das ein ungewöhnlicher Einsatz. Das Ergebnis einer Rechenoperation ist in diesem Fall eine Ganzzahl und du möchtest wissen, ob diese ungleich 0 ist. Dann schreib das doch auch so! Die bool-Trickserei mag letztendlich zwar das gleiche erreichen, aber nur über komische Konvertierungen und es drückt dabei nicht deine Absichten aus. Im Maschinencode schreibt der Compiler am Ende sowieso immer den gleichen Code, aber nur wenn du deine Absichten klar ausdrückst, stellst du sicher, dass andere Menschen deinen Code gut verstehen können, und das dein Code robust gegen unerwartete Änderungen ist. Je klarer du dich ausdrückst, desto besser funktioniert das.
-
@Lou-Cyphr3
Wie @SeppJ schon geschrieben hat:bool,trueundfalsesind alle voll OK und ich verwende sie alle. Z.B.boolParameter/Variablen mit1statttruezu befüllen wäre hochgradig bekloppt. Was ich nur nicht mache ist mittrueoderfalsezu vergleichen.
Und was ich auch nicht mache ist sowas wie...bool var = a % b;...also implizite Konvertierung von einem Integer-Typ nach
bool.
(Ausgenommen in bestimmten Fällen inifStatements - aber das zu erklären würde jetzt zu weit gehen.)Unsere Compiler sind soger so eingestellt dass sie bei
bool var = a % b;ne Warning werfen, und da wir mit "treat warnings as errors" bauen...