C++ Übung aus Buch
-
Hallo, in einem Buch für C++ Anfänger steht folgende Aufgabe:
Schreiben Sie die Funktion namens sign, der Sie einen int-Wert übergeben und die Folgendes zurückliefert: -1, wenn der Wert negativ ist, 0, wenn der Wert null ist, und 1, wenn der Wert positiv ist.
Schreiben Sie dazu auch eine main-Funktion, mit der Sie sign testen können, und die das Ergebnis mit einer entsprechenden Textausgabe quittiert.
Nun habe ich die Aufgabe wie folgt gelöst:
#include <iostream> using namespace std; int sign(int a) { if(a>0) return(1); if(a==0) return(0); if(a<0) return(-1); } int main(void) { int x; cout << "Bitte geben Sie eine Zahl ein: " << endl; cin >> x; if(sign(x)==1) cout << "Die Zahl ist positiv." << endl; if(sign(x)==0) cout << "Die Zahl ist gleich Null." << endl; if(sign(x)==-1) cout << "Die Zahl ist negativ." << endl; }Danach kommt folgende Aufgabe:
Schreiben Sie die Funktion sign aus der vorherigen Übung so um, dass weder if-Anweisungen noch ?:-Operatoren verwendet werden.
Im Buch wird folgende Lösung genannt:
#include <iostream> using namespace std; int sign(int x) { int a; a=2*(x>0); a-=1; a*=!(x==0); return(a); } int main() { int a,erg; cout << "Wert :"; cin >> a; erg=sign(a); if(erg==1) cout << "Der Wert ist positiv." << endl; if(erg==0) cout << "Der Wert ist Null." << endl; if(erg==-1) cout << "Der Wert ist negativ." << endl; return(0); }Ich verstehe die Lösung nicht, und sie wird im Buch auch nicht weiter erklärt. Was genau machen diese paar Zeilen:
a=2*(x>0); a-=1; a*=!(x==0);Wäre nett wenn Ihr meine Frage beantworten könntet, vielen Dank.
Gruß,
Cherry64
-
Am besten probierst du das einfach mal mit 3 Zahlen aus und rechnest nach, dann siehst du, wie das funktioniert.
sagen wir x ist 2:
a=2*(x>0); // x>0 ist wahr, also wird da a 2 * 1, als 2 zugewiesen a-=1; // 2-1 = 1 a*=!(x==0); (1)(1) x ist nicht gleich 0, also ist (x==0) falsch, also 0, aber !0 ist 1. Und jetzt wird a, also 1 mit 1 multipliziert und ergibt dann am Ende 1.
sei x = -2:
a=2*(x>0); // x>0 ist falsch, also 0. 2*0 gibt 0 a-=1; // 0 -1 gibt -1 a*=!(x==0); (1)(1) x ist nicht gleich 0, also wieder !0 = 1. Und somit wird -1 mit 1 multipliziert und ergibt auch wieder -1.
Und wenn x = 0 ist, überlasse ich jetzt mal dir, zum nachvollziehen.

Ist das jetzt klarer geworden?
-
Hallo, Ich versuche auch mal, das zu erklären.
erst einmal die Erklärung zu dieser Zeile: a=2*(x>0);
Der Wert in den Klammern ist ein boolscher Ausdruck welcher entweder true oder false ergibt. Da hier allerdings mit Zahlen gearbeitet werden muss, wandelt der Compiler true zu 1 um und false zu 0.
sollte x also größer als 0 sein, wird a ein wert von 2 zugewiesen, andernfalls ist a 0.Nun diese Zeile: a-=1;
Diese Zeile bedarf egentlich keiner Erklärung. Hier wird a um 1 erniedrigt.
Sollte x größer als 0 sein, is a in diesem Moment 1. Andernfalls ist a zu diesem Zeitpunkt -1.Die letzte Zeile: a*=!(x==0);
Sollte x gleich 0 sein, ergibt der Ausdruck in der Klammer true. Da der Operator ! vor der Klammer steht, wird true zu false (=0). mit diesem Wert wird a multipliziert. a wird also 0. Sollte x ungleich 0 sein, wird die klammer false, !(x==0) ergibt true und der Wert von a bleibt unangetastet.
Alles klar?
Was mich jetzt noch interessiert: In welchem Anfängerbuch steht denn sowas?
Und dann noch ohne Erklärung?MfG, Jochen
-
Ich schlag mal eine Alternative vor.
return (a>0)-(a<0);
-
volkard schrieb:
Ich schlag mal eine Alternative vor.
return (a>0)-(a<0);

Wollt mir auch noch was kürzere überlegen, aber musste einem Kollegen bei seinem Splay Tree helfen.

-
Danke an alle, ich habe die Lösung jetzt verstanden. Wusste vorher nicht, dass z.B. bei x>0 automatisch 1 oder 0 ausgegeben wird; übrigens, ist dies nicht doch eine Art von Bedingung?
Jochen S. schrieb:
Was mich jetzt noch interessiert: In welchem Anfängerbuch steht denn sowas?
Und dann noch ohne Erklärung?C++ Programmierung lernen aus dem Addison-Wesley-Verlag. ISBN 978-3-8273-2674-4.
Gruß,
Cherry64
-
Das ist doch beknackt. Die Lösung soll den ?:-Operator benutzen, aber die Musterlösung benutzt diesen Operator überhaupt nicht.
-
?!
dass weder if-Anweisungen noch ?:-Operatoren verwendet werden.
-
Hups. Lesen bildet.

-
Cherry64 schrieb:
Danke an alle, ich habe die Lösung jetzt verstanden. Wusste vorher nicht, dass z.B. bei x>0 automatisch 1 oder 0 ausgegeben wird; übrigens, ist dies nicht doch eine Art von Bedingung?
Nein, nicht direkt. Das ist lediglich ein Ausdruck, welcher ausgewertet wird, welcher wahr oder falsch sein kann. Und da du da einen int hast, wird true zu 1 und false zu 0 ohne cast umgewandelt.
Umgekehrt wird 0 zu false und alles andere zu true umgewandelt. Du kannst also auch das hier machen:int i = 2; if ( i ) .. // i wird hier zu true ausgewertet