Samstag, 2. November 2013

Die Entscheidungsanweisung in Java

Wichtig für Smartphonebenutzer

Wir wollen im Beispiel Rechner den Umfang von verschiedenen Formen berechnen können. Dazu machen wir uns jetzt ein kleines Menü für das Konsolenfenster. Dafür können wir die if-Anweisung oder die switch-Anweisung verwenden, um einzelne Menüpunkte auswählen zu können.

Die if-Anweisug
Hier ist das ganze Beispiel:

  1. import java.util.*;
  2. public class Rechner {
  3.         public static void main(String[] args) {
  4.                
  5.                 Scanner eingabe;
  6.                 eingabe = new Scanner(System.in);
  7.                
  8.                 final double PI = 3.141592653589793D;
  9.                 double a, b, c;
  10.                                                
  11.                 // Menü auf der Konsole ausgeben
  12.                 System.out.println("1. Quadrat");
  13.                 System.out.println("2. Rechteck");
  14.                 System.out.println("3. Kreis");
  15.                 System.out.println("-------------");
  16.                 System.out.print(": ");
  17.                
  18.                 // Tastatureingabe abfangen
  19.                 int menueEingabe = eingabe.nextInt();
  20.                
  21.                 System.out.println("-------------");
  22.                
  23.                 // Entscheidungsanweisung
  24.                 if (menueEingabe == 1) {
  25.                         // Abfrage der benötigten Werte
  26.                         System.out.println("Umfangesberechnung 
     eines Quatrats");
  27.                         System.out.print("Länge: ");
  28.                         a = eingabe.nextDouble();
  29.                         // Berechnung
  30.                         c = a * 4;
  31.                         System.out.println("-------------");
  32.                         System.out.println("Der Umfange des 
     Quadrats beträgt: " + c);
  33.                 }
  34.                 else if (menueEingabe == 2) {
  35.                         // Abfrage der benötigten Werte
  36.                         System.out.println("Umfangesberechnung 

           eines Rechtecks");
  37.                         System.out.print("Länge: ");
  38.                         a = eingabe.nextDouble();
  39.                         System.out.print("Breite: ");
  40.                         b = eingabe.nextDouble();
  41.                         // Berechnung
  42.                         c = a * 2 + b * 2;
  43.                         System.out.println("-------------");
  44.                         System.out.println("Der Umfange des 
                            Rechtecks beträgt: " + c);
  45.                 }
  46.                 else if (menueEingabe == 3) {
  47.                         double r;
  48.                         // Abfrage der benötigten Werte
  49.                         System.out.println("Umfangesberechnung 
                            eines Kreises");
  50.                         System.out.print("Radius: ");
  51.                         r = eingabe.nextDouble();
  52.                         // Berechnung
  53.                         c = r * 2 * PI;
  54.                         System.out.println("-------------");
  55.                         System.out.println("Der Umfange des 
     Kreises beträgt: " + c);
  56.                 }
  57.                 else {
  58.                         // Ausgabe bei fehlerhafter Eingabe
  59.                         System.out.println("Ungültige Eingabe!");
  60.                 }
  61.                
  62.                 // Der Eingabestrom wird geschlossen. Es ist
  63.                 // hier zwar nicht unbedingt notwendig, aber
  64.                 // bei Eclipse wird sonst immer eine Warnung
  65.                 // ausgegeben.
  66.                 eingabe.close();
  67.         }
  68. }

Wie man sieht ist es schon einiges an Code, was da zusammenkommt. Gehen wir einfach mal alles der Reihe nach durch.


  1. import java.util.*;

Wir teilen den Konstruktor mit dass wir das Paket java.util, wegen  der Tastatureingabe brauchen.

  1. Scanner eingabe;
  2. eingabe = new Scanner(System.in);

Hier erzeugen wir ein Objekt des Datentypen Scanner und fangen den Eingabestrom ab.

  1. final double PI = 3.141592653589793D;

Mit final deklarieren wir unsere Konstante PI und initialisieren den Wert.

  1. double a, b, c;

Hier deklarieren wir die Variablen a, b und c.

  1. System.out.println("1. Quadrat");
  2. System.out.println("2. Rechteck");
  3. System.out.println("3. Kreis");
  4. System.out.println("-------------");
  5. System.out.print(": ");

Auf der Konsole wird unser Menü ausgegeben.

  1. int menueEingabe = eingabe.nextInt();

In dieser Zeile wird eine Variable des Typs Integer (int) deklariert und der Eingabestrom wird als Integer mit der Methode nextInt() übergeben. Solange die Eingabe einen gültigen Wert hat, wenn nicht gibt der Kompiler eine Fehlermeldung zurück.

  1. if (menueEingabe == 1) {

    // Abfrage der benötigten Werte
  2.      ...
  3. }
  4. else if (menueEingabe == 2) {
  5.      // Abfrage der benötigten Werte
  6.      ...                   
  7. }
  8. else if (menueEingabe == 3) {
  9.      double r;
  10.      ...         
  11. }
  12. else {
  13.      // Ausgabe bei fehlerhafter Eingabe
  14.      System.out.println("Ungültige Eingabe!");
  15. }

In Zeile 1 ist die erste if-Anweisung, die Anweisung zwischen ( und ) bezeichnet man als Ausdruck. Bei dem ausführen des Programmes wird erst der Ausdruck ausgewertet, dessen Ergebnistyp boolean sein muss. Hier im Beispiel wird verglichen ob die Variable menueEingabe gleich 1 ist, wenn ja (also true) werden die Anweisungen die in den folgenden beiden { und } (Block) steht ausgeführt und die beiden else if-Anweisung in Zeile 5 und 9 und die else-Anweisung in Zeile 13 werden nicht ausgewertet, natürlich werden auch nicht dessen Anweisungsblöcke ausgeführt.
Wenn der Ergebnistyp boolean false ist in der if-Anweisung in Zeile 1, wird der dazugehörige Anweisungsblock nicht ausgeführt und die else if-Anweisung in Zeile 5 wird ausgewertet. Ist dieser auch false wird die else if-Anweisung aus Zeile 9 ausgewertet. Wenn keine der Anweisungen true ergeben, wird die else-Anweisung in Zeile 13 ausgeführt.

Wenn der Anweisungsblock der if-, else if- und else-Anweisungen nur eine Anweisung enthält kann die { und } auch weggelassen werden. Hier ein Beispiel:

  1. if (i == 1)
  2.         System.out.println("Nur eine Anweisung für if");
  3. else if (i == 6)
  4.         System.out.println("Nur eine Anweisung für else if");
  5. else
  6.         System.out.println("Nur eine Anweisung für else");

Es ist auch möglich mit Logischen Operatoren mehrere Anweisungen zusammen im Ausdruck auszuwerten.
Hier ein Beispiel:

  1. if (a == 0 && b == 0)
  2.         ...

oder

  1. if (a >= 0 || b <= 8)
  2.         ...

Durch die Logischen Operatoren können auch beliebig viele Anweisungen im Ausdruck zusammen ausgewertet werden nicht nur zwei. Noch ein Beispiel:

  1. if (b == true)
  2.         ...

Die if-Anweisung wird ausgeführt wenn die Variable b true ist. es gibt eine verkürzte Schreibweise dafür:

  1. if (b)
  2.         ...

Wenn der Wert false erwartet werden soll, kann dafür der !-Operator (negiert b) verwendet werden:

  1. if (!b)
  2.         ...

Es ist Geschmackssache des Programmierers, ob er die normale oder die verkürzte Schreibweise verwendet.

Die switch-Anweisung
Hier ist der Teil der Entscheidungsanweisung, dieses Mal mit der switch-Anweisung:

  1. // Entscheidungsanweisung
  2. switch(menueEingabe) {
  3.         case 1:
  4.                 // Abfrage der Benötigten Werte
  5.                 System.out.println("Umfangesberechnung eines 
    Quatrats");
  6.                 System.out.print("Länge: ");
  7.                 a = eingabe.nextDouble();
  8.                 // Berechnung
  9.                 c = a * 4;
  10.                 System.out.println("-------------");
  11.                 System.out.println("Der Umfange des Quadrats 
    beträgt: " + c);
  12.                 break;
  13.         case 2:
  14.                 // Abfrage der Benötigten Werte
  15.                 System.out.println("Umfangesberechnung eines 
    Rechtecks");
  16.                 System.out.print("Länge: ");
  17.                 a = eingabe.nextDouble();
  18.                 System.out.print("Breite: ");
  19.                 b = eingabe.nextDouble();
  20.                 // Berechnung
  21.                 c = a * 2 + b * 2;
  22.                 System.out.println("-------------");
  23.                 System.out.println("Der Umfange des Rechtecks 
    beträgt: " + c);
  24.                 break;
  25.         case 3:
  26.                 double r;
  27.                 // Abfrage der Benötigten Werte
  28.                 System.out.println("Umfangesberechnung eines 
    Kreises");
  29.                 System.out.print("Radius: ");
  30.                 r = eingabe.nextDouble();
  31.                 // Berechnung
  32.                 c = r * 2 * PI;
  33.                 System.out.println("-------------");
  34.                 System.out.println("Der Umfange des Kreises 
    beträgt: " + c);
  35.                 break;
  36.         default:
  37.                 // Ausgabe bei fehlerhafter Eingabe
  38.                 System.out.println("Ungültige Eingabe!");
  39. }

Jetzt zu der ersten Zeile:

  1. switch(menueEingabe) {

In den ( und ) nach switch steht wieder unser Ausdruck. Hier ist des die Variable menueEngabe. Dann folgt ein Anweisungsblock der zwischen { und } steht.

  1. case 1:

Nach dem Schlüsselwort case wird eine Konstante mit Doppelpunkt angegeben, jede case dass im Anweisungsblock von switch steht, ist eine Einsprungsmarke. Wenn also die Variable menueEingabe gleich 1 ist, werden ab dieser Einsprungsmarke die Anweisungen ausgeführt, bis zur nächsten break-Anweisung. Wenn die Variable nicht 1 ist, wird gleich zum nächsten case gegangen. Ist keines der case Konstanten zutreffen werden die Anweisungen die nach der default-Anweisung folgen ausgeführt.

  1.  default:
  2.  // Ausgabe bei fehlerhafter Eingabe
  3.       System.out.println("Ungültige Eingabe!");
     
Nach dem default-Anweisung ist keine break-Anweisung mehr notwendig, weil die default-Anweisung das Ende der switch-Anweisung ist.

Hier noch ein kleine Beispiel:

  1. switch(menueEingabe) {
  2.         case 1:
  3.                 System.out.println("Case 1");
  4.         case 2:
  5.                 System.out.println("Case 2");
  6.                 break;
  7.         case 3:
  8.                 System.out.println("Case 3");  
  9.                 break;
  10.         default:
  11.                 System.out.println("Default");
  12. }

Wenn die Variable menueEingabe gleich 1 ist werden die Anweisungen von der Einsprungsmarke:

  1. case 1:

und von

  1. case 2:

ausgeführt. Warum das? Es ist ganz einfach, wenn keine break-Anweisung gefunden wir bis zur nächsten Einsprungsmarke werden deren Anweisungen auch noch mit ausgeführt bis auf eine break-Anweisung gestoßen wird. Es gibt Situationen bei dem dies beabsichtigt ist.

Montag, 28. Oktober 2013

Konsoleneingabe mit der Klasse Scanner in Java

Wichtig für Smartphonebenutzer

Jetzt wird es etwas kompliziert, ich hoffe ich kann es verständlich erklären, denn Java hat keine einfache Methode um im Konsolenfenster eine Eingabe zu machen. Wir erweitern das Beispiel vom Tutorial "Variablen in Java", es soll natürlich nicht immer der selbe Kreisumfang berechnet werden, der Benutzer soll es im laufenden Programm eingeben. Hier ist einmal das ganze Beispiel:

  1. import java.util.*;
  2. public class Rechner {
  3.         public static void main(String[] args) {
  4.                
  5.                 Scanner eingabe;
  6.                 eingabe = new Scanner(System.in);
  7.                
  8.                 final double PI = 3.141592653589793D;
  9.                 double Radius, Umfang;
  10.                
  11.                 System.out.print("Radius: ");
  12.                 Radius = eingabe.nextDouble();
  13.                                
  14.                 Umfang = PI * Radius * 2;
  15.                
  16.                 System.out.println("Umfang des Kreises: "
  17.                                    + Umfang);
  18.                                        
  19.         }
  20. }

Als erstes sehen wir im Beispiel die import-Anweisung, der Compiler benutzt ein Standartpaket namens java.lang. Einiges ist aber in Pakete (sind mehrere Klassen) ausgelagert wie die Klasse Scanner. Durch die Anweisung

import java.util.*;

teilen wir dem Compiler mit das Paket java.util zu verwenden. Es geht aber auch mit der Anweisung

import java.util.Scanner;

dadurch verwendet der Compiler nur die Klasse Scanner und nicht das gesamte Paket. 

Mit den beiden Zeilen:

Scanner eingabe;
eingabe = new Scanner(System.in);

wird ein Objekt der Klasse Scanner erzeugt, der Operator new reserviert den Speicherplatz dazu. System.in übergibt den Eingabestrom (Tastatureingabe) an das Objekt (eingabe). Mit der Methode nextDouble() aus der Klasse Scanner wird der Eingabestrom als Datentyp double an die Variable Radius übergeben. Achtung, der Eingabewert sollte dem Datentyp entsprechen oder der Compiler gibt einen Fehler zurück.  

Es ist vielleicht etwas schwer zu verstehen, weil ich jetzt Klassen und Methoden im Tutorial habe, die wir noch nicht richtig behandelt haben. Ich musste es jetzt aber machen weil wir die Tastatureingabe für die nächsten Tutorials benötigen. Wer es noch nicht richtig versanden hat macht auch nichts. In späteren Tutorials werde ich es ausführlicher erklären. Die Hauptsache ist jetzt einmal zu wissen wie man eine Tastatureingabe bekommt.


Mittwoch, 23. Oktober 2013

Historyline 14-18

Heute ist es soweit ich stelle mein erstes Retro-Game vor. Für mich ist es jedenfalls ein Meilenstein der Rundenstrategie. Es sagt schon der Name um was es im Spiel geht, nämlich um den 1. Weltkrieg.





Man kann auf deutscher oder französischer Seite spielen, das Ziel ist seinen Gegner zu vernichten oder sein Hauptquartier einzunehmen. Sowas ist leicht gesagt, ist aber auch nicht gerade einfach. Die KI ist zwar nicht schlau und verheizt seine Einheiten regelrecht, aber man merkt schnell dass die KI einen einfach überrent wenn man nicht taktisch geschickt vorgeht.


Depots und Fabriken sollten so schnell es geht eingenommen werden. Meistens sind darin Einheiten die man gut brauchen kann. Die schwer beschädigten Einheiten sollten immer wieder mal im Depot oder der Fabrik repariert werden. Einheiten werden pro Kampf erfahrener und können sehr wertvoll werden um den Angriff zu überstehen. Es kommt öfter vor dass eine erfahrene Einheit eine unerfahrene auf einmal vernichtet. Es sind aber auch die Eigenschaften der Umgebung etwas ausschlaggebend wie ein Kampf ausgehen kann.



Das Spiel macht immer noch sehr viel Spaß, wer Rundenstrategie mag hat hier ein richtige Juwel. Historyline 14-18 lässt sich am flüssigsten mit der Tastatur spielen, mit der Maus ist es einfach zu fummelig. Wer es richtig raus hat mit der Tastatur ist sehr schnell beim ziehen seiner Truppen.


Wie man schon erkennen kann, ist es auch möglich zu zweit gegeneinander an einem PC zu spielen. 







Dienstag, 22. Oktober 2013

Blöcke in Java

Die Anweisungen, die zwischen { und } stehen werden als Block bezeichnet. Ein Block kann bei jeder einzelnen Anweisung verwendet werden. Der Block ist eigentlich eine Anweisung die mehrere zusammengesetzte Anweisungen darstellt. Blöcke können auch ineinander verschachtelt sein. Hier ein kleines Beispiel:


Es ist zu beachten, dass die Variablen außerhalb ihres Blockes in dem sie deklariert wurden nicht gültig sind. Uns ist es also nicht möglich die Variable y und z zu addieren.

Montag, 7. Oktober 2013

Variablen in Java

Eine Variable hat eine Speicheradresse auf einen Speicherort zeigt in der der Inhalt steht, der in der Variable initialisiert wird. Die Größe des Speicherorts entspricht der Größe des angegebenen Datentypes.

Besser kann man es sich so vorstellen. Man steht vor einem Schrank (Arbeitsspeicher)  mit lauter verschieden große Schubläden. Jeder Schubladen hat eine Nummer (Speicheradresse). Wenn wir jetzt etwas darin verstauen wollen, wollen wir natürlich so wenig Platz wie möglich verbrauchen, weil nur ein Gegenstand (Variableninhalt) in eine Schublade darf. Wir suchen sich also die passende Schublade (Größe des Datentyps) aus und legen den Inhalt rein. Natürlich müssen wir uns jetzt die Nummer des Schubladen irgendwie merken, damit wir schnell den richtigen Schubladen wieder finden. Deshalb schreiben wir eine Kurze Notiz (Bezeichner) in der unsere Nummer (Speicheradresse) des Schubladens  steht. Wenn wir jetzt einen Gegenstand suchen Schauen wir unsere Notizen durch und wissen genau in welcher Schublade unser gesuchter Inhalt ist.

Durch dieses Beispiel kann man sich auch viel einfacher vorstellen wie die Typumwandlung geht, die schon im vorherigen Tutorial "Einfache Datentypen in Java" angesprochen wurde. Ein kleiner Inhalt kann in einen grösseren Schubladen ohne Probleme vom Compiler automatisch umgewandelt werden, dies ist die Implizite Datenumwandlung. Wenn aber ein größerer Inhalt in einen kleineren Schubladen soll muss man den Compiler erst angeben, dass man es will und er es einfach sozusagen reinquetschen soll ohne Rücksicht auf Verluste (Rundungsfehler), das ist die Explizite Datenumwandlung.

Jetzt schauen wir uns mal ein Beispiel an:


Wie wir sehen wird hier die Summe von 6 + 8 ausgegeben. Wenn wir jetzt andere Zahlen addieren wollen müssen wir 4 Werte korrigieren (In der Zeichenkette müssen ja auch die passenden Zahlen stehen). Bei großen Programmen kann es dann sehr umfangreich werden wenn man einen Wert ändern möchte. Deshalb deklarieren und initialisieren wir zwei Datentypen. Für den Anfang schaut es nach mehr Arbeit aus, aber dieses bisschen mehr Aufwand ist bei größeren Programmen vorteilhaft und man will auch nicht immer den gleichen Wert berechnen.


Bei diesen Beispiel müssen wir nur noch die beiden Werte initialisieren, also den Datentypen mit den = Operator zuweisen. Damit ist schon einmal der Aufwand zum korrigieren geringer geworden, wie man bestimmt merkt. Jetzt schauen wir uns mal den Code genauer an.

int a, b;

Hier werden die beiden Variablen a und b erzeugt (deklariert), die Bezeichner  haben eine Größe von 4 Byte. Es wird für die beiden Variablen ein Speicherplatz reserviert und jede der beiden Variablen hat eine Speicheradresse für ihren reservierten Speicherplatz.  Mit der angegebenen Speicheradresse zeigt die Variable auf den Speicherplatz. Variablen kann man wie bei dem Beispiel in einer Zeile deklarieren, aber dann nur mit dem Selben Datentyp.

a = 6;
b = 8; 

In den beiden Zeilen werden die Werte 6 und 8 initialisiert (werden die Variablen a und b mit dem Operator = zugewiesen).  

System.out.println( a + " + " + b " = " + (a + b));

Diese Zeile schaut etwas kompliziert aus, als erstes deklariert der Compiler einen String ohne Bezeichner.
Dann wird der Teil a + " + " + b " + " = " in den String initialisiert jetzt schaut es sozusagen so aus:

System.out.println("a + b = " + (a + b);

Jetzt deklariert der Compiler einen int Variable ohne Bezeichner und initialisiert die Summe von a und b.

System.out.println("a + b = " + 14);

Der Compiler fügt dem String die Variable int dem String hinzu und gibt den kompletten String auf der 
Konsole aus.


Achtung: Wenn (a + b) nicht in Klammern steht werden a und b nicht addiert sondern nur dem String hinzugefügt.

Manchmal ist es sinnvoll eine Variable mit einem Wert zu initialisieren der bei dem Programmablauf gleich bleibt. Dafür gibt es die final-Variable (oder symbolische Konstante). Um so eine Konstante zu deklarieren, muss man der üblichen Deklaration mit der Initialisierung das Schlüsselwort final voranstellen.


Unser Programm ist jetzt etwas umgebaut worden, jetzt kann der Umfang eines Kreises berechnet werden. PI ist eine final-Variable, solche Variablen werden nur mit Großbuchstaben geschrieben und die Initialisierung muss in der selben Zeile der Deklaration gemacht werden. Es kann auch kein neuer Wert initialisiert werden, bei einem Versuch einen neuen Wert zu initialisieren, gibt der Compiler eine Fehlermeldung zurück.

Operatoren
Bei den Operatoren gibt es die einstelligen Operatoren (unär bzw. monadisch), die zweistelligen Operatoren (binär bzw. dyadisch) und die dreistelligen Operatoren (ternär bzw. triadisch).

Einstellige Arithmetische Operatoren:


Zweistellige Arithmetische Operatoren:



Der dreistelligen Bedingungsoperator ?: (wird sehr selten benutzt), er ist eigentlich die verkürzte Schreibweise der if-Entscheidungsanweisung. Wir werden sie mit den Entscheidunsanweisungen behandeln.

Die oben aufgeführten Arithmetischen Operatoren können für die Datentypen : byte, short, int, long, float, double oder char verwendet werden. Der Operator + kann auch dazu verwendet werden Zeichenketten zu verbinden (dies haben wir in den vorherigen Tutorials schon verwendet).

Bitoperatoren
Auf diese Operatoren werde ich jetzt nicht eingehen, sie sind auch für Anfänger sehr uninteressant, eventuell werde ich aber diesen Punkt noch ergänzen und doch noch darüber schreiben.

Zuweisungsoperator
Der Zuweisungsoperator = hat eine Sonderstellung. Mit ihm kann man Variablen Werte zuordnen.

x = 7;

Der Variable x wird der Wert 7 zugeordnet. Es kann aber auch eine Variable anstatt eines Konstanten Werts zugeordnet werden.

x = y = z = 9;

Hier wird der konstante Wert 9 z zugeordnet, dann y und danach x zugeordnet.

x = x + 5

Hier wird die Variable x addiert mit dem konstanten Wert 5 und die Summe x zugeordnet.

Es gibt in Java verkürzte Schreibweisen für binäre Operatoren:


Also ist durch die verkürzte Schreibweise:

x += 5; das Selbe wie x = x + 5;

Vergleichsoperatoren und logische Operatoren
Die Vergleichsoberatoren sind immer binär. Es werden zwei Werte (Operanten) miteinander verglichen und gibt ein Ergebnis vom Typ boolean zurück (entweder true oder false).

Vergleichsoperatoren in Java:


Die logischen Operatoren werden oft mit den Vergleichsoperatoren verwendet um komplexere Ausdrücke zu erstellen. Die logischen Operatoren erwarten immer einen Wert vom Typ boolean und gibt auch solchen zurück.

Logisch Und, Oder und die Negation:


Logische Operatoren:


Bei a & b und a | b werden beide Operanten ausgewertet. Bei a && b wird der zweite Operant nur ausgewertet wenn der erste Operant true ist. Bei a || b wird der zweite Operant nur ausgewertet wenn der erste Operant false ist.

Inkrement- und Dekrementoperatoren
Dies Operatoren sind eigentlich auch nur eine verkürzte Schreibweise. Diese beiden Operatoren können aber nur mit Variablen verwendet werden. Wenn man den Wert nur um 1 erhöhen will ist es mit dem Inkrementoperator möglich:

a++;

oder wenn man den Wert um 1 verringern will mit dem Dekrementoperator:

a--;

Es ist möglich den Operator Präfix (vor der Variable) oder Postfix (nach der Variable) zu verwenden. Es gibt bei dem beiden Schreibweisen Präfix und Postfix einen Unterschied bei der Auswertung.

a = 5;
b = ++a;
x = 8;
y = x--;

Die Variable b hat den Wert 6, aber die Variable y hat den Wert 8. Warum ist das so? Ganz einfach, die Variable x wird erst den Wert an die Variable y zuweisen und dann erst wird x um 1 verringert. 

Jetzt sind wir am Ende des dritten Tutorials, es war nicht gerade einfach soviele Informationen zusammenzufassen, es hat aber auch Spaß gemacht.


Donnerstag, 3. Oktober 2013

DOSBox

DOSBox ist ein kostenloser Emulator für BeOs, LinuxBeOS, Linux, Mac Os X und Windows. Dadurch ist es möglich DOS-Spiele zu spielen, die unter den heutigen Betriebssystemen nicht mehr richtig laufen.

Als erstes geht ihr auf http://www.dosbox.com und ladet euch unter Downloads die DOSBox herunter und installiert sie.

Wen man die DOSBox jetzt startet bekommt man  zwei Fenster zu sehen. Da fühlt man sich gleich wie in den guten alten DOS Zeiten.


Jetzt müssen wir ein DOS-Laufwerk emulieren, das geht mit dem Befehl mount.


Nach mount gibt man den Laufwerksbuchstaben der für das emulierte Laufwerk gültig sein soll. Dann gibt man noch das Verzeichnis an welches als DOS-Laufwerk emuliert werden soll, natürlich müssen in den Unterverzeichnissen unsere DOS-Spiele sein.


Mit c: wechseln wir auf das emulierte DOS-Laufwerk.

/
Mit dir kann man den Inhalt des Verzeichnisses anzeigen lassen es geht auch dir /w und dir /p. Mit cd und dem Verzeichnisnamen gehen wir in das Verzeichnis, hier ist es bei mir hl14-18. Mit cd.. wechselt man in das vorherige Verzeichnis zurück und mit cd\ geht man bis zum Laufwerksbuchstaben zurück.


Jetzt suchen wir uns aus dem Spieleverzeichnis die Startdatei mit der Endung EXE oder BAT heraus und geben sie ein.


Hier ist es z.B. die Datei HL.EXE. 

Mit Alt + Enter wechselt man zwischen Fenster- und Vollbildmodus. 

Wünsche jedenfalls viel Spaß beim spielen. Wenn es Probleme gibt helfe ich gerne weiter.





Dienstag, 1. Oktober 2013

Einfache Datentypen in Java

In diesem Tutorial wird es um einfache Datentypen gehen. Es ist zwar ein etwas trockenes Thema, aber es muss einfach sein, damit man etwas mehr Verständnis dafür bekommt, natürlich muss man es nicht auswendig lernen.

Ganzzahlige Datentypen

Ein Computer speichert die ganzen Zahlen in eine Folge von binären Zeichen, also 1 oder 0. Bei 1 Byte haben wir 8 Bits die uns zur Verfügung stehen, also 8 binäre Stellen. Das erste Bit benötigen wir für das Vorzeichen, uns bleiben also 7 Bits um eine Zahl darstellen zu können. Die negativen Zahlen sind durch die rechnerinternen Darstellungen um 1 größer, in diesen Fall -128. Mit 8 Bits sind also 127(positiv) + 128(negativ) + 1(Null) = 256 verschiedene Zahlen möglich darzustellen.

Der Datentyp byte ist genau 8 Bits groß. Im Allgemeinen ist dieser Zahlenbereich (-128 bis 127) viel zu klein um damit vernünftig arbeiten zu können. Deshalb gibt es in Java die weitere Arten von ganzzahligen Datentypen, die zwei, vier oder acht Byte lang sind.

Hier sind alle ganzzahligen Datentypen die es in Java gibt:


Für ganzzahlige Datentypen sind die Ziffern 0 bis 9 verfügbar. Der Compiler geht immer von einer 4 Byte großen Zahl aus, also int. Wenn man die Zahl 214783649 darstellen will muss man der Zahl ein L anhängen für den Datentyp long, also 214783649L. Ohne das L würde der Compiler einen Fehlermeldung ausgeben.

Hier zwei Beispiele:

Es ist aber auch möglich in Java oktale Zahlen (Zahlen im Achter-System) oder als hexadezimale Zahlen (Zahlen im Sechzehner-System) zu schreiben. Oktale Zahlen beginnen mit einer 0 und sind im Ziffernbereich von 0 bis 7. Hexadezimale Zahlen beginnen mit 0x, die Ziffer sind im Bereich 0 bis 9 und von A bis F.

Zwei Beispiele für Oktale und Hexadezimale Zahlen:


System.out.println ist das Selbe wie System.out.print nur mit einen Zeilenumbruch am Ende

Gleitkommatypen

In Java gibt es noch die Datentypen float und double für Gleitkommazahlen. Diese sind intern aus 32 Bits oder 64 Bits aufgebaut. Das Bitmuster ist aber etwas anders aufgebaut als der von den ganzzahligen Datentypen. Für die Gleitkommazahlen nimmt man einen Punkt (keine Komma sonst gibt der Compiler eine Fehlermeldung zurück). Es kann aber auch ein Exponent (bestehend aus einem e oder einem E sowie eine Endung von f, F, d oder D) verwendet werden. Das E steht für die anschließender Zahl X für die Multiplikation mit 10^X, d.h. die Zahl 1.2E3 steht für 1.5 * 10^3, also den Wert 1500. Bei negativen Zahlen wird vor die entsprechende Zahl ein Minuszeichen gesetzt. Bei den Wert 1500, die Zahl 1.5E-3 für 1.5 * 10^3 ergibt 0.0015. Der Compiler geht bei Gleitkommazahlen von den Typ double aus, man kann aber auch ein d oder D anhängen für den Wert double. Für float  wird ein f oder F angehängt. Es muss dazu gesagt werden bei Gleitkommazahlen kann es zu Rundungsfehlern kommen.

Hier sind die Gleitkommazahlen die es in Java gibt:


Der Datentyp char für Zeichen

In Java gibt es den Datentyp char, manchmal ist es notwendig mit Zeichen oder Buchstaben zu arbeiten. Ein Zeichen übergibt man dem Typ char mit Hochkommata, das Zeichen c wird dann so 'c' dargestellt. Der Datentyp char wird mit 16 Bits (also 2 Bytes dargestellt). Jedes Zeichen hat eine bestimmte Nummer (16 Bit Dualzahl), der sogenannte Unicode, das c hat z.B. die Nummer 99. Den Wert char kann man auch als ganzzahligen Wert auffassen, z.B. mit int i = 'c' wird der Wert 99 zugewiesen.
Der Unicode-Zeichensatz enthält auch Zeichen die nicht mit der Tastatur dargestellt werden können. Um diese in Java anzuzeigen, gibt es die Unicode-Schreibweise die mit \u beginnt und vier hexadezimale Ziffern folgen. Damit ist es möglich alle Unicode-Zeichen von \u0000 bis \uffff darstellen. Der hexadezimale Wert 63 entspricht den dezimalen Wert 99. Für Kommando oder Trennzeichen gibt es auch die Escape-Sequenzen, damit kann man statt '\u0009' auch '\t' für den horizontalen Tabulator schreiben oder für den Zeilenvorschub '\n'. Die Symbole " und ' können  nur in der Form '\"' und '\'' geschrieben werden. Das \-Zeichen kann nur in der Form '\\' geschrieben werden.

Zeichenketten

Der String besteht aus mehreren Zeichen des Datentyps char. Dei Zeichen abc können mit doppelten Hochkommata dargestellt werden "abc". 

Der Datentyp boolen für richtig oder falsch

Es gibt auch noch den Datentyp boolean für Wahrheitswerte. Beim diesen Datentyp gibt es nur wahr(true) oder falsch(false).

Implizite Typumwandlungen

Kleine ganzzahlige Datentypen werden automatisch vom Compiler in den größeren Datentyp umgewandelt, wenn sie ihnen zugewiesen werden. Es können auch Gleitkommazahlen in ganzzahlige Datentypen umgewandelt werden, aber es können Rundungsfehler auftreten. Ein float-Wert wird auch automatisch in einen double-Wert umgewandelt, wenn er den größeren Datentyp zugewiesen wird. Es ist auch eine implizite Umwandlung von char nach int, long, float oder double möglich.

Explizite Typumwandlungen

Bei einer Typumwandlung eines größeren in einen kleineren Datentyp haben wir ein Problem. Der Compiler würde uns einen Fehler ausgeben, da es dabei zu Umwandlungsfehlern kommen kann. Um den Compiler mitzuteilen, dass es die Absicht des Programmierers ist, schreibt man dann z.B. (int) 12.56 mit dem (Datentyp in Klammer)  gibt man dem Compiler an, dass das Umwandeln des nachfolgenden Bezeichners gewollt ist.

Beispiele zur expliziten Typenumwandlung:


Wenn man das Beispiel ausführt wird man bemerken dass zwei verschiedene Ergebnisse gibt. Das kommt von der Klammersetzung. In den beiden Kommentaren wird auch schon angedeutet warum es so ist. Am besten probiert man einfach Verschiedene Klammersetzungen aus um zu sehen was passiert und es auch besser verstehen kann.

Jetzt sind wir an das Ende des zweiten Tutorials angelangt. Hoffe ich konnte es verständlich erklären und dass sich kein Fehler eingeschlichen. Wenn jemand Verbesserungsvorschläge hat, kann er es mir ruhig schreiben. Ich bin schon am überlegen was dass nächste Thema ist.