if else Befehl funktioniert nicht richtig

  • Themenstarter Trollmaster8000
  • Beginndatum
Diskutiere if else Befehl funktioniert nicht richtig im Java Basics - Anfänger-Themen Bereich.
Bitte aktiviere JavaScript!
T

Trollmaster8000

Aloah!

Ich fange gerade mit einem Buch an Java zu lernen und bin schon auf ein Problem gestoßen. Eclipse gibt den Code nicht so aus, wie es das laut Buch sollte.

Code:
package Rechnen1;
import javax.swing.*;
public class Mathe1 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        int Ergebnis = 654165415; //"Ergebnis" wird als Integer gesetzt und weiter unten neu definiert
String Eingabe1 = JOptionPane.showInputDialog("Gib eine Zahl ein;");
String Eingabe2 = JOptionPane.showInputDialog("Gib noch eine Zahl ein;");
String Operator = JOptionPane.showInputDialog("Und jetzt den Operator:");

int Zahl1 = Integer.parseInt(Eingabe1);
int Zahl2 = Integer.parseInt(Eingabe2);

if (Operator.equals("+")) Ergebnis = Zahl1 + Zahl2; //Neudefinition des Integers "Ergebnis"
if (Operator.equals("-")) Ergebnis = Zahl1 - Zahl2; //Neudefinition des Integers "Ergebnis"
if (Operator.equals("*")) Ergebnis = Zahl1 * Zahl2; //Neudefinition des Integers "Ergebnis"
if (Operator.equals("/")) if (Zahl2 != 0) Ergebnis = Zahl1 / Zahl2;
else JOptionPane.showMessageDialog(null, "Division durch null!");

JOptionPane.showMessageDialog(null,  "Ergebnis ist " + Ergebnis);

    }

}

Bis auf "null" verstehe ich alles einigermaßen, aber die letzten zwei Zeilen machen Probleme. Die else-Zeile ist klar, aber danach gibt das Programm auch noch die letzte Zeile aus und genau das soll nicht sein, wenn die else-Zeile zum tragen kommt. Wäre ja blöd, wenn das Programm sagt, dass man nicht durch Null teilen kann und dann einen anderen Wert ausgibt.

OT: Warum wird im Falle des durch Null Teilens der int-Wert ausgegeben, den ich ganz oben deklariert habe?

p.s.: Ich hab das mit Objekt, Methode und diesen ganzen Bezeichnugen noch immer nicht kapiert, also bitte ich nach Möglichkeit um eine Antwort für Dummies. ^^
 
M

mrBrown

Das Problem sieht man recht schnell, wenn man Klammern benutzt und den Code ordentlich einrückt :)

Java:
package Rechnen1;
import javax.swing.*;
public class Mathe1 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
       
        int Ergebnis = 654165415; //"Ergebnis" wird als Integer gesetzt und weiter unten neu definiert
        String Eingabe1 = JOptionPane.showInputDialog("Gib eine Zahl ein;");
        String Eingabe2 = JOptionPane.showInputDialog("Gib noch eine Zahl ein;");
        String Operator = JOptionPane.showInputDialog("Und jetzt den Operator:");

        int Zahl1 = Integer.parseInt(Eingabe1);
        int Zahl2 = Integer.parseInt(Eingabe2);

        if (Operator.equals("+")) {
            Ergebnis = Zahl1 + Zahl2; //Neudefinition des Integers "Ergebnis"
        }
        if (Operator.equals("-")) {
            Ergebnis = Zahl1 - Zahl2; //Neudefinition des Integers "Ergebnis"
        }
        if (Operator.equals("*")) {
            Ergebnis = Zahl1 * Zahl2; //Neudefinition des Integers "Ergebnis"
        }
        if (Operator.equals("/")) {
            if (Zahl2 != 0) {
                Ergebnis = Zahl1 / Zahl2;
            } else {
                JOptionPane.showMessageDialog(null, "Division durch null!");
            }
        }

        JOptionPane.showMessageDialog(null,  "Ergebnis ist " + Ergebnis);
    }
}
 
M

M.L.

Das mit dem Einrücken und Formatieren ist natürlich richtig. Z.B. wird Ergebnis mit irgendeinem Wert deklariert und im Fall der Division durch Null gerade nicht verändert.
Zudem läuft das Programm nur einmal durch und macht den Benutzer nicht auf erlaubte Eingaben aufmerksam.
Ich hab das mit Objekt, Methode und diesen ganzen Bezeichnugen
Java ist eine objektorientierte Sprache. Der OOP-Ansatz versucht die menschliche Sicht auf die Welt (man sieht z.B. Tische, Stühle, Lebewesen, Bücher mit 6 kg Gewicht und grünem Buchdeckel, Eltern-Kinder-Enkel-..., Eigenschaften, Attribute, Methoden (z.B. essen, schlafen)...) in die Welt der Programmierung zu übertragen.
Eine Methode ist eine Ansammlung elementarer Java-Befehle und dient idR zum mehrmaligen Ausführen (Ggs.: anonyme Methode). Ein Objekt ist eine Instanz einer x-beliebigen Klasse, z.B. ist Max Mustermann eine Instanz der Klasse Mensch.
Eventuelle Code-Konventionen dienen übrigens für den Menschen (man muss sich nicht dran halten, aber dann sollte gute Erklärungen für die Abweichung davon parat haben)
 
T

Trollmaster8000

@M.L. Ja, das habe ich schon oft gelesen, aber es will irgendwie nicht hängen bleiben. Ich denke, ich werde es eher verstehen, wenn ich mehr in Java drin bin. Ich muss sowas mal "anfassen" um es zu verstehen. Reine Theorie hat bei mir nie funktioniert.

@mrBrown Ui, sexy. ^^ Ich habe den Code kopiert, aber es klappt immer noch nicht. Es wird weiterhin zuerst "Division durch Null" und danach "Ergebnis ist ...." angezeigt.

Edit: Da das Ergebnis auch ohne die geschweiften Klammern das Gleiche ist, nehme ich an, dass diese nur zwecks Optik dienen?
 
M

mrBrown

@mrBrown Ui, sexy. ^^ Ich habe den Code kopiert, aber es klappt immer noch nicht. Es wird weiterhin zuerst "Division durch Null" und danach "Ergebnis ist ...." angezeigt.

Edit: Da das Ergebnis auch ohne die geschweiften Klammern das Gleiche ist, nehme ich an, dass diese nur zwecks Optik dienen?
Ja, das war nur, damit du selbst den Fehler finden kannst :)
 
T

Trollmaster8000

@mrBrown Ich bin erst am Anfang vom Buch und der Text ist 1:1 aus dem Buch kopiert. Mein Wissenstand lässt es nicht zu hier einen Fehler auszumachen. Noch .....

@mihe7 Danke, hat funktioniert, auch wenn ich aus den ganzen Beschreibungen (auch hier im Forum) nicht schlau daraus werde was return macht. Iwie versteh ich das C++ leichter als das Java Buch. ^^
 
mihe7

mihe7

Iwie versteh ich das C++ leichter als das Java Buch.
Dann solltest Du return aber kennen...

return bedeutet "zurückkehren". Mit einem return wird die Ausführung einer Methode (allgemein: eines Unterprogramms) beendet und unmittelbar nach dem Methodenaufruf fortgesetzt. Jede Methode hat ein return, wobei bei Methoden ohne Rückgabewert auf die Anweisung verzichtet werden kann:

Java:
public void sayHello() {
    System.out.println("Hello!");
}
wird automatisch behandelt wie
Java:
public void sayHello() {
    System.out.println("Hello!");
    return;
}
Durch das Einfügen der return-Anweisung im Beispiel oben sagst Du also: gib die Fehlermeldung aus und danach beende die Methode. Dadurch werden die folgenden Anweisungen (die Ausgabe des Ergebnisses) nicht mehr ausgeführt.
 
M

M.L.

versteh ich das C++ leichter als das Java Buch.
C++ und Java sind syntaktisch weitgehend ähnlich.
ABER: in Java sind Methoden, Variablen,... automatisch Bestandteil irgendeiner (öffentlichen) Klasse. Und Java lässt keine Manipulationen am Speicher (C++-Stichwort: Referenzen und Zeiger. Man beachte auch Weak Reference unter Java) zu. Und die Virtual Machine lässt u.a. den Garbage Collector im Hintergrund laufen (heisst man kann bei einem Java-Programm nicht vorhersagen WIE sich dessen Leistung unter einer anderen System verhält) .
 
T

Trollmaster8000

Dann solltest Du return aber kennen...
Ich glaube mein Wissen wird hier immer noch falsch verstanden. Ich bin bei beiden Büchern erst ca. auf Seite 30 und davor gabs viele Seiten Einrichtung von Eclipse. "Return" habe ich hier in diesem Forum das erste mal gehört.

Durch das Einfügen der return-Anweisung im Beispiel oben sagst Du also: gib die Fehlermeldung aus und danach beende die Methode. Dadurch werden die folgenden Anweisungen (die Ausgabe des Ergebnisses) nicht mehr ausgeführt.
Und die Methode wird nur dann nach Plan beendet, wenn "else" zum Tragen kommt, verstehe ich das richtig? Sollte also die Methode nicht nach Plan beendet und "else" nicht ausgeführt werden, dann erst springt das Programm zum nächsten Unterprogramm?

Die Unterprogramme sind jetzt aber nicht die Codezeilen in geschweiften Klammern, oder? Sonst müsste es nach der schönen Aufgliederung oben ja zig Unterprogramme nur in diesem kleinen Codeblock geben.
 
mihe7

mihe7

Und die Methode wird nur dann nach Plan beendet, wenn "else" zum Tragen kommt, verstehe ich das richtig?
Ich tue mich schwer, hier "Ja" zu schreiben, denn "der Plan" ist, dass entweder nach einer Fehlerausgabe oder nach Ausgabe des Ergebnisses ein Rücksprung erfolgt.

Die Unterprogramme sind jetzt aber nicht die Codezeilen in geschweiften Klammern, oder?
Nein, das sind Anweisungen. Allerdings dienen Anweisungen auch dazu, Unterprogramme aufzurufen. Ein Unterprogramm wird in Java Methode genannt. Sprich: eine Methode ist ein Unterprogramm.

Nehmen wir als Beispiel mal die folgende Zeile:
Java:
String Eingabe1 = JOptionPane.showInputDialog("Gib eine Zahl ein;");
ich trenne die mal auf, dann kann man es besser verstehen:
Java:
String Eingabe1;
Eingabe1 = JOptionPane.showInputDialog("Gib eine Zahl ein;");
Die erste Zeile sagt dem Compiler: hey, ich will eine Variable "Eingabe1" vom Typ String haben. Das nennt man eine Deklaration.

In der zweiten Zeile startest Du mit JOptionPane.showInputDialog zuerst einmal ein Unterprogramm (sprich: Du rufst eine Methode auf). Sobald der Benutzer den Dialog schließt, kehrt das Unterprogramm mit einem Ergebnis (einem String oder null) zurück. Dieses Ergebnis wird anschließend in der Variablen Eingabe1 gespeichert.

Genauso funktioniert Deine main-Methode: diese wird von der Laufzeitumgebung als Unterprogramm aufgerufen. Irgendwann erfolgt ein Rücksprung (return), womit die Kontrolle an die Laufzeitumgebung zurückgegeben wird. Im konkreten Fall wird die Anwendung dann einfach beendet.
 
T

Trollmaster8000

Sorry, ich hab das mit return immer noch nicht so ganz kapiert. Ok, durch return springt das Programm an einen anderen Punkt zurück. Soweit ich es verstanden habe, springt es zur vorherigen Methode zurück.

Hier nochmal der Ort wo ich es eingebaut habe und es funktioniert.

Code:
package rechnen1a;
import javax.swing.*;

public class Mathe1A {

  public static void main(String[] args) {
 
      int Ergebnis = 12345;        //"Ergebnis" wird als Integer gesetzt und weiter unten neu definiert
      
      String Eingabe1 = JOptionPane.showInputDialog("Gib eine Zahl ein;");
      String Eingabe2 = JOptionPane.showInputDialog("Gib noch eine Zahl ein:");
      String Operator = JOptionPane.showInputDialog("Und jetzt einen Operator:");
      
      int Zahl1 = Integer.parseInt(Eingabe1);
      int Zahl2 = Integer.parseInt(Eingabe2);
      
      // "if" und "else" sind Methoden aka Unterprogramme. Zur Übersicht ist es Ratsam diese in {} zu setzen.
      
      if (Operator.equals("+")) {
          Ergebnis = Zahl1 + Zahl2;        //Neudefinition des Integers "Ergebnis"
      }     
      if (Operator.equals("-")) {
          Ergebnis = Zahl1 - Zahl2;
      }
      if (Operator.equals("*")) {
          Ergebnis = Zahl1 * Zahl2;
      }
      if (Operator.equals("/")) {
          if (Zahl2 != 0) {
              Ergebnis = Zahl1 / Zahl2;
          }
          else {
              JOptionPane.showMessageDialog(null, "Disivion durch Null!");
              return;
              // Wenn Zahl1 / Zahl2 geht, wird "else" übersprungen. Wenn "else" zum Tragen kommt,
          }
      // "return" erzielt in dieser Zeile kein Ergebnis, wenn Zahl2 > 0
      }
      
      JOptionPane.showMessageDialog(null,  "Ergebnis ist " + Ergebnis);
      
  }
}

Wir gehen nun davon aus, dass ich nach Aufruf des Programms durch 0 Teilen will.

Da return innerhalb der {} vom else-Befehl steckt, wäre für mich die vorige Methode "if (Zahl2 != 0) {". Sollte das aber so gelten, dass return zur nächst "höheren" Ebene wechselt, wäre das - bildlich betrachtet - "if (Operator.equals("/")) {". Aber egal wo das Programm jetzt landet, wenn es von oben nach unten jede Zeile durch geht, müsste es ja wieder in der else-Zeile landen.

Außerdem wird mir in Eclispe "null" farblich genauso wie "if" und "else" markiert, was dann bedeuten würde, dass "return" in Wirklichkeit zu "null" springt, was mich auf die Frage bringt was "null" macht. Aus dieser Erklärung werde ich jedenfalls nicht schlau.

Daher die große Frage: Wohin springt das Programm nach "return" und warum wird dann die letzte Zeile im Code ignoriert? Und was wäre, wenn unter der letzten Zeile noch mehr Code stehen würde. Wieso würde dieser dann NICHT ignoriert werden?
 
A

abc66

Vorschlag
Java:
public static void main(String[] args) {
	do {
		String eingabe1 = JOptionPane.showInputDialog("Gib eine Zahl ein:");
		String eingabe2 = JOptionPane.showInputDialog("Gib noch eine Zahl ein:");
		String operator = JOptionPane.showInputDialog("Und jetzt einen Operator:");

		if (eingabe1 == null || eingabe2 == null || operator == null) {
			continue;
		}

		int zahl1;
		int zahl2;
		try {
			zahl1 = Integer.parseInt(eingabe1);
			zahl2 = Integer.parseInt(eingabe2);
		} catch (NumberFormatException e) {
			continue;
		}

		if (!List.of("+", "-", "*", "/").contains(operator)) {
			continue;
		}

		int ergebnis = -1;
		switch (operator) {
		case "+":
			ergebnis = zahl1 + zahl2;
			break;
		case "-":
			ergebnis = zahl1 - zahl2;
			break;
		case "*":
			ergebnis = zahl1 * zahl2;
			break;
		case "/":
			try {
				ergebnis = zahl1 / zahl2;
			} catch (ArithmeticException e) {
				JOptionPane.showMessageDialog(null, "Eingabe2 war " + eingabe2);
			}
			break;
		default:
			break;
		}
		
		JOptionPane.showMessageDialog(null, "Ergebnis ist " + ergebnis);
	} while (JOptionPane.showConfirmDialog(null, "Weiter?") == JOptionPane.YES_OPTION);
}
 
A

abc66

Geht das eigentlich auch mit Streams, oder sind Fallunterscheidungen da eher suboptimal?
 
H

httpdigest

Da return innerhalb der {} vom else-Befehl steckt, wäre für mich die vorige Methode "if (Zahl2 != 0) {".
Nein. Wie @mihe7 schon sagte, sind Zeilen wie etwa "if (Zahl2 != 0) {" keine Methoden, sondern Anweisungen innerhalb einer Methode. Wie @mihe7 ebenfalls sagte, wird deine "main(String[] args)" Methode, in der sich aktuell alles abspielt, von der Laufzeitumgebung aufgerufen. Das ist quasi Code, den wir aktuell nicht sehen. Sobald in deiner "main"-Methode irgendwo eine "return;" Anweisung steht und die Ausführung diese Anweisung erreicht, wird die komplette Ausführung deiner main-Methode an Ort und Stelle beendet und sofort zum (für uns nicht sichtbaren) Aufrufer gesprungen. Kein Code deiner main-Methode wird dann also noch ausgeführt.
Sollte das aber so gelten, dass return zur nächst "höheren" Ebene wechselt, wäre das - bildlich betrachtet - "if (Operator.equals("/")) {".
Auch falsch. Es ist nicht die "nächste höhere" Ebene im Sinne von if-Verschachtelungen gemeint, sondern die aufrufende Methode.
Aber egal wo das Programm jetzt landet, wenn es von oben nach unten jede Zeile durch geht, müsste es ja wieder in der else-Zeile landen.
Nein. Durch ein "return;" wird die gesamte Methodenausführung beendet.
Außerdem wird mir in Eclispe "null" farblich genauso wie "if" und "else" markiert, was dann bedeuten würde, dass "return" in Wirklichkeit zu "null" springt
Diesen Gedankengang kann ich leider nicht nachvollziehen. Die Farbgebung im Eclipse-Editor soll dir nur zeigen, welche Wörter im Quellcode sogenannte Schlüsselwörter sind, die du selber z.B. nicht als Variablennamen oder Methodennamen verwenden kannst. Und da sind if, else, return, null, break, continue, while, do, ... Beispiele für.
Daher die große Frage: Wohin springt das Programm nach "return" und warum wird dann die letzte Zeile im Code ignoriert?
Die Programmausführung springt bei einem return zur aufrufenden Methode (bzw. dem Aufrufer). Kein Code der Methode, in der das "return;" erreicht wurde, wird danach noch ausgeführt.
Und was wäre, wenn unter der letzten Zeile noch mehr Code stehen würde. Wieso würde dieser dann NICHT ignoriert werden?
Da die gesamte Methode bei einem "return;" beendet wird, würde jeder weitere Code in derselben Methode ebenfalls nicht mehr ausgeführt werden. Er würde also "ignoriert" werden.

Ich bin mir nicht ganz sicher, ob es Sinn macht, dass wenn du bei Seite 30 bist und die vorherigen Seiten die Einrichtung von Eclipse beschrieben haben, dann hier schon Fragen zu kompletten Programmschnipseln stellst. Denn dir fehlen so viele grundlegende Konzepte und Begriffsdefinitionen, so dass man sich als Antwortender einen Wolf schreibt, um jeden verwendeten Begriff wie "Methode" und "Aufrufer" erstmal erklären zu müssen. Und dann ist die Wahrscheinlichkeit immer noch sehr groß, dass du viele Dinge missverstehst, was dann noch mehr Erklärung nach sich zieht. Das kannst du bestimmt besser lernen, wenn du erstmal im Buch weiterarbeitest.
 
T

temi

Das kannst du bestimmt besser lernen, wenn du erstmal im Buch weiterarbeitest.
Das ist vermutlich in der aktuellen Situation die beste Lösung.
gibt das Programm auch noch die letzte Zeile aus und genau das soll nicht sein, wenn die else-Zeile zum tragen kommt.
Es ist natürlich nicht so schön, dass die letzte Zeile hier auch noch mit ausgegeben wird, aber offenbar soll es so sein, wenn es korrekt abgetippt wurde.

Warum es so ist, ist klar. Die Anweisung im else-Zweig wird ausgeführt und gibt die entsprechende Meldung aus und danach wird das Programm nach dem else-Zweig fortgesetzt.

Warum wird im Falle des durch Null Teilens der int-Wert ausgegeben, den ich ganz oben deklariert habe?
Das ist auch klar. Du deklarierst eine Variable Ergebnis und initialisierst sie mit einem Wert. Da alle if-Anweisungen nicht zutreffen und auch im else-Zweig dieser Variablen kein anderer Wert zugewiesen wird, wird genau dieser Wert ausgegeben.

Sollten in deinem Buch die Variablen tatsächlich mit Großbuchstaben am Anfang bezeichnet sein, dann spricht das nicht für die weitere Lektüre. Die allgemein gängigen Konventionen für Java sehen vor, dass Klassenamen mit Großbuchstaben beginnen und im sogenannten UpperCamelCase geschrieben werden. Variablen werden im sogenannten lowerCamelCase (Kleinbuchstabe am Anfang) bezeichnet.
 
T

Trollmaster8000

@httpdigest Danke, damit ists geklärt. Return ist also eine Art „Exit“. Damit hab ichs.

Die Klärung hier übers Forum war mir daher wichtig, weil die Ausgabe nicht die war, die es laut Buch geben sollte, obwohl der Code sogar als Download genau so bereit stand.
 
T

Trollmaster8000

Hier der Link zum Buch. Ich hatte noch ein anderes Buch, aber das war so komisch geschrieben, dass ich absolut nichts verstanden habe.
 
A

abc66

Also ohne irgendwem auf den Schlips treten zu wollen, zu den besten Büchern in dem Bereich gehört das nicht.
 
T

Trollmaster8000

Also ohne irgendwem auf den Schlips treten zu wollen, zu den besten Büchern in dem Bereich gehört das nicht.
Kann ich ja nicht wissen. Wenn ihr bessere Vorschläge habt, dann immer her damit. Am Besten wäre DRM frei, damit ichs auch als PDF auf andere Geräte bringen kann *Arbeit* *hüstel* ;)

Ich bin halt eher auch der Typ der einfachere Erklärungen braucht. Ich kann im Endeffekt alles verstehen, brauche aber simple Einführungen und ich muss es mal aktiv angewandt haben, dann sitzt es.

p.s.: Amazon Account habe ich aus Grüden gelöscht. Amazon ist daher keine Option.
 
A

abc66

Kann ich ja nicht wissen. Wenn ihr bessere Vorschläge habt, dann immer her damit. Am Besten wäre DRM frei, damit ichs auch als PDF auf andere Geräte bringen kann *Arbeit* *hüstel* ;)

Ich bin halt eher auch der Typ der einfachere Erklärungen braucht. Ich kann im Endeffekt alles verstehen, brauche aber simple Einführungen und ich muss es mal aktiv angewandt haben, dann sitzt es.

p.s.: Amazon Account habe ich aus Grüden gelöscht. Amazon ist daher keine Option.
Also zwei Dinge, a) das war noch freundlich formuliert, b) mir ist es egal, welches Buch du dir zulegen möchtest, da das c) einfachstes Grundlagenwissen ist.
Und aus welchen Gründen du welchen Account löschst interessiert mich auch nicht.
 
M

M.L.

weil die Ausgabe nicht die war, die es laut Buch geben sollte
...kann ja sein das die Bilder falsch sind, immerhin werden in den Folgekapiteln andere Eingabe- und Abfangoptionen durchgenommen. Weiterhin kann man den Quellcode durchlesen um die beabsichtigte Ausgabe herauszufinden.
 
Thema: 

if else Befehl funktioniert nicht richtig

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben