Transcription

Grundelemente der Programmierung:BasisdatentypenSoftware Entwicklung 1Annette Bieniusa, Mathias Weber, Peter ZellerIn diesem Kapitel werden wir erste Programme in der Programmiersprache Java schreiben. Wir werden die zwei grundlegenden Varianten zur Ausführung von Programmenvorstellen (Übersetzung und direkte Interpretation) und Variante diskutieren, die fürJava gewählt wurde.Im Mittelpunkt stehen dannach die Begriffe Wert, Ausdruck und Typ. Unsere erstenJava-Programme verwenden Datentypen, die in der Sprache integriert sind: primitive Datentypen (int, double, boolean, char) und Strings. Mit Hilfe von mathematischen und logischen Operatoren formulieren wir Ausdrücke und besprechen derenAuswertungssemantik. Als weiteres grundlegendes Programmierkonstrukt führen wiraußerdem Variablen ein.Das Kapitel schließt mit einem Beispielprogramm, die typische Verwendungen dieseKonstrukte illustrieren.1 Erste Schritte in JavaAls erstes Java Programm werden wir hier das “Hello World!” - Programm betrachten.Das Programm soll den Text “Hello World!” auf der Konsole ausgeben. Es wird klassischerweise als Beispiel verwendet, um eine Programmiersprache kurz vorzustellen./* Ausgabe von " Hello World !" auf der Kommandozeile */public class Hello {public static void main ( String [] args ) {System . out . println ( " Hello World ! " ) ;}}Dieses einfache Java-Programm besteht aus den folgenden Elementen: Die erste Zeile /* . */ ist ein Kommentar, der das Programm informell beschreibt. Das Programm besteht aus einer Klasse, die wir Hello genannt haben. Es mussdaher in einer Textdatei namens Hello.java gespeichert werden.1

In dieser Klasse gibt es eine main() - Methode; hier startet die Programmausführung. Das Programm selbst besteht aus einer Sequenz von Anweisungen, die durch ;voneinander getrennt werden. Diese Anweisungen bilden den Rumpf der Methode. Die Anweisung System.out.println() ruft eine Bibliotheksfunktion auf, die einenText auf der Konsole ausgibt. Der auszugebende Text wird dabei zwischen dieKlammern geschrieben. Befehlszeilenargumente können mittels String[] args übergeben werden ( siehe Ende dieses Abschnitts)1.1 Prinzipielle AusführungsvariantenProgramme können auf verschiedene Arten ausgeführt werden:1. Mittels Übersetzung:Dabei wird der Programmtext inMaschinensprache übersetzt unddann direkt vom Prozessor ausgeführt.2. Mittels direkter Interpretation:Hier wird der Programmtext voneinem Interpreter ausgeführt, derwiederum – zusammen mit deminterpretierten Code – vom Prozessor ausgeführt wird.2

Java verwendet eine Mischform aus Übersetzung und Interpretation:Das Programmieren in Java umfasst grob die folgenden Schritte: Programmtext schreiben Programm übersetzen / compilieren Programm Hello, World!”Zwei Schritte haben wir hier zunächst vernachlässigt: Integration/Komposition mehrerer Programmteile, die unabhängig von einanderentwickelt und evtl. übersetzt wurden Installation der Programme auf der Host-MaschineIn der Praxis gewinnen diese Schritte durch die Vielzahl an bereits existierenden TeilProgrammen und Plattformen von Bedeutung.3

2 BasisdatentypenLiteraturhinweis: Kapitel 1.2 aus R. Sedgewick, K. Wayne:Einführung in die Programmierung mit Java. 2011, Pearson Studium.Programme verarbeiten Informationen in Form von Daten. Die Art der Daten wirddurch den entsprechenden Datentyp festgelegt. Ein Datentyp hat einen Wertebereichund eine dazugehörige Menge an OperationenBeispiel: Texte und Zeichenfolgen werden als String behandelt; können z.B. zusammengefügt oder in Großbuchstaben umgewandelt werden. Messwerte werden oft als Zahlen repräsentiert; sie können z.B. addiert, multipliziert, verglichen werden.In Java gibt es zwei Arten von Werten (engl. values): elementare Datenwerte (Zahlen, Wahrheitswerte, Zeichen, . . . ) Referenzen auf Objekte ( näheres dazu im Abschnitt zu “Objekte”)Wie für abstrakte Objekte oder Begriffe typisch, besitzen Werte keinen Ort, keine Lebensdauer, keinen veränderbaren Zustand, kein Verhalten.Ein Typ (engl. type) charakterisiert Werte, auf denen die gleichen Operationen zulässigsind. Typisierte Sprachen besitzen ein Typsystem, das für jeden Wert festlegt, vonwelchem Typ er ist.Ausdrücke sind das Sprachmittel zur Beschreibung von Werten.Ein Ausdruck (engl. expression) in Java ist (u.a.) ein Literal, ein Bezeichner, die Anwendung einer Operation auf einen oder mehrere Ausdrücke, oder aufgebaut aus Sprachmitteln, die erst später behandelt werden.Jeder Ausdruck hat einen Typ: Der Typ eines Literals ergibt sich aus dem Wertebereich.4

Der Typ eines Bezeichners ergibt sich aus dem Wert, den er bezeichnet. Der Typ einer Operation ist der Ergebnistyp der Operation.Wir betrachten zunächst die Basisdatentypen und elementare Operatoren für Elementedieser Datentypen, wie man sie in jeder Programmier-, Spezifikations- und Modellierungssprache findet. Die Basisdatentypen (engl. basic / primitive data types) bildendie Grundlage zur Definition weiterer Typen und Datenstrukturen.2.1 Ganze Zahlen / IntegerDem Typbezeichner int ist in Java eine Wertemenge zugeordnet, die die ganzen Zahlenvon 2147483648 bis 2147483647 enthält.TypbezeichnerWerteTypische LiteraleOperationenintganzen Zahlen von 231 bis 231 11, 0, -99 (Addition)- (Subtraktion)* (Multiplikation)/ (Division)% (Modulo)Beispiele:Ausdruck5-35/35%31/03-5-43 - (5 - 4)3*5-4Wert212-6211HinweisGanzzahlige nnerhalb der Wertemenge [ 231 , 231 1] sind die Operatoren auf beschränkten ganzenZahlen gleich den üblichen mathematischen Operatoren. Außerhalb der Wertemenge istihr Verhalten nicht definiert. So wertet beispielsweise 2147483647 1 zu -2147483648aus (Überlauf ). Weitere Datentypen für ganze Zahlen: long (64-bit Integer), short(16-bit Integer), byte (8-bit Integer).2.2 GleitkommazahlenDem Typbezeichner double ist in Java die (endliche!) Wertemenge der 64-bit Gleitkommazahlen zugeordnet.5

TypbezeichnerWerteTypische LiteraleOperationendoublereelle Zahlen (nach IEEE-Standard 754)3.1415, 1.98e20, -1.0 (Addition)- (Subtraktion)* (Multiplikation)/ (Division)Beispiele:Ausdruck3.14 .035.0 / 3.01.0 / gsfehler möglichspezieller WertMit Gleitkommazahlen sind im Allg. keine beliebig präzisen Berechnungen möglich. Siebieten nur eine Näherung an die reelle Zahlen R, haben aber nur endliche Darstellungmit eingeschränkter Präzision. So sind die Integer sind in der Programmierung in vielen Programmiersprachen keine Teilmenge der Gleitkommazahlen! Nicht alle Integerkönnen z.B. präzise als Gleitkommazahl dargestellt werden. Durch die eingeschränktePräzision kann es leicht zu Rundungsfehlern kommen, die sich akkumulieren könnenund Ergebnisse unter Umständen sogar unbrauchbar machen. Das Fachgebiet der Numerik befasst sich mit dieser Problematik.Die Standardisierung der Gleitkommazahlen nach IEEE-Standard 754 definiert nebenden Zahlenwerten selbst zwei spezielle Werte: Infinity (wenn Darstellung zu groß) NaN (not a number; wenn Berechnung undefiniert)Weiterer Datentyp für Gleitkommazahlen: float (32-bit Gleitkommazahlen)2.3 Boolesche WerteDem Typbezeichner boolean ist die Wertemenge der Wahrheitswerte {true, f alse} oleanwahr, falschtrue, false&& (Und) (Oder)! (Nicht)Semantik der Operationen: a && b ist true, wenn beide Operanden true sind; sonst false6

a b ist false, wenn beide Operanden false sind; sonst true !a ist true, wenn a false ist; und false, wenn true ist Frage 1: Zu welchen Werten ergeben sich folgende Ausdrücke? (7 45) truesein ! seinfür geeignete Variable sein VergleichsoperatorenDie folgenden Operatoren vergleichen primitive numerische Werte gleichen Typs miteinander und liefern als Ergebnis einen boolschen Wert. ! , , GleichheitUngleichheitgrößer bzw. größer gleichkleiner bzw. kleiner gleichWenn unterschiedliche Funktionen oder andere Programmelemente den gleichen Bezeichner haben, spricht man vom Überladen des Bezeichners (engl. overloading).Wie in den obigen Datentypen gezeigt, können Operatorbezeichner in Java überladenwerden, d.h. in Abhängigkeit vom Typ ihrer Argumente bezeichnen sie unterschiedlicheFunktionen.Beispiele: arbeitet z.B. auf int und double arbeitet z.B. auf int und boolean2.4 CharacterDer Datentyp char repräsentiert einzelne Zeichen aus dem Unicode-Zeichensatz, z.B.Ziffern, Groß- und Kleinbuchstaben, Satzzeichen, White space (Leerzeichen, Tabularzeichen, Zeilenumbruchzeichen), etc.TypbezeichnerWerteTypische LiteralecharZeichen'a', '7', 'B'char-Werte stellen die Unicode-Zeichen eigentlich als Zahlen zwischen 0 und 65535(16-bit) dar.Beispiele: ’a’ 97 , ’b’ 98 , ’A’ 65 , ’B’ 66 , ’0’ 48 und ’1’ 49 .Man kann sie daher vergleichen und auch mit ihnen rechnen:boolean istBuchstabe ( c ’a ’ && c ’z ’) ( c ’A ’ && c ’Z ’) ;// Umwandlung von Zeichen ’3 ’ zu Zahl 3:char c ’3 ’;int i c - ’0 ’;7

Spezielle Zeichen:'\”''\’''\n''\t''\b''\\'doppeltes Anführungszeicheneinfaches ckspaceBackslash-Zeichen2.5 StringsDem Typbezeichner String ist in Java die Wertemenge der Zeichenketten ngZeichenketten, Text"Hallo", "Die 7 Zwerge", (Konkatenation, Verkettung)Beispiele:"Hello, " "World!""12 " "34""12" "34""Die " 7 " Zwerge""Hello, World!""12 34""1234""Die 7 Zwerge"Strings sind in Java keine primitiven Datentypen, jedoch in die Sprachdefinition festintegriert. Wenn primitive Datentypen mit einem String konkateniert werden, werdensie automatisch in Strings umgewandelt. Strings können auf der Kommandozeile direktausgegeben oder auch von dort eingelesen werden, wie wir im nächsten Abschnitt sehenwerden. Frage 2: Zu welchen Werten ergeben sich folgende Ausdrücke?"seven" "three" ergibt sich zu"4" "5"ergibt sich zu"" 9 7ergibt sich zu9 7 ""ergibt sich zu"7"ergibt sich zu " " "5" 2.6 Präzedenzregeln bei OperatorenWenn Ausdrücke nicht vollständig geklammert sind, ist im Allgemeinen nicht klar, wieihr Syntaxbaum aussieht und wie die Auswertung zu erfolgen hat.8

Beispiele :3 5 truefalse true truefalse && true truePräzedenzregeln legen fest, wie Ausdrücke zu strukturieren sind: Am stärksten binden unäre Operatoren1 in Präfixform2 . Binäre Infix-Operatoren in Java sind (in der Regel) linksassoziativ. Präzedenzregeln für Infix-Operatoren:– *, / ,% binden stärker als und – ,- binden stärker als , , , – , , , binden stärker als , ! – , ! binden stärker als &&, und && stärker als Boolsche Operatoren && und sind nicht-strikt; d.h. die Auswertung beginntmit dem ersten (linken) Operanden, und nur wenn dieser Wert den Wert desGesamtausdrucks nicht bestimmt, wird der rechte Operand ausgewertet.Beispiel: Die Auswertung des Ausdrucks (x ! 0) && (y / x 5) testet zunächst,ob x ! 0; nur wenn dieser Teilausdruck zu true auswertet, wird der zweite Teilausdruck (y / x 5) ausgewertet. Falls x ! 0 zu false auswertet, ergibt sichder Gesamtausdruck zu false.Wichtig: Die arithmetischen Operatoren sind strikt; d.h. hier werden immer alleOperanden ausgewertet.3 VariablenEine Speichervariable (oder einfach nur: Variable) ist ein Speicher/Behälter für Werte. Dieser Wert kann sich – im Unterschied zur mathematischen Verwendung – im Laufeeines Programms verändern. Charakteristische Operationen auf einer Variablen v sind: Zuweisen eines Werts w an v; Lesen des Wertes, den v enthält/speichert/hat.Der Zustand einer Variablen v ist undefiniert, wenn ihr noch kein Wert zugewiesenwurde; andernfalls ist der Zustand von v durch den gespeicherten Wert charakterisiert.Variablen stellen wir graphisch meist durch Rechtecke dar:1 UnäreOperatoren haben einen Operanden, binäre Operatoren haben zwei Operanden, ternäreOperatoren drei, etc.2 Präfix-Operatoren stehen vor dem Operator, Infix-Operatoren stehen zwischen den Operanden,Postfix-Operatoren hinter den Operanden9

v:truev enthält/speichert den Wert truex:7x enthält/speichert den Wert 7Variablen werden über Bezeichner (engl. identifier ) referenziert. Für Bezeichnermuss in Java gelten: Bezeichner bestehen aus beliebig vielen Unicode-Zeichen (insbesondere Buchstaben, Ziffern und Unterstrich ). Sie starten nicht mit einer Ziffer. Bezeichner dürfen nicht mit Schlüsselwörtern oder Konstanten übereinstimmen. Bezeichner sind case-sensitive, d.h. es wird zwischen Groß- und Kleinschreibungunterschieden.Eine Variablendeklaration hat in Java die Form:V a riablendeklaration Typbezeichner Variablenbezeichner;Sie definiert eine neue Variable vom angegebenen Typ mit dem angegebenem Bezeichner. Variablen müssen immer mit einem Typ deklariert werden und ihnen darf nur einWert mit “kompatiblem” Typ zugewiesen werden. Welche Typen miteinander “kompatibel” sind, werden wir im Laufe der Vorlesung sehen. Der Typ einer Variablen wird beider Deklaration festgelegt und kann sich im weiteren Programmverlauf nicht ändern.Beispiele:int a ;boolean b ;double me in e Gl e it ko m ma v ar ia b le ;3.1 ZuweisungenSyntax in Java:Zuweisung Variable Ausdruck;Semantik: Werte den Ausdruck aus und weise das Ergebnis der Variablen zu.In Java ist eine Zuweisung syntaktisch ein Ausdruck, liefert alsoeinen Wert und zwar das Ergebnis der Auswertung von der rechtenSeite der Zuweisung.Beispiele:ia 27 % 23;b true ;m ei ne G le i tk om m av a ri ab l e 3.14;10

Sprechweise: “Variable b ergibt sich zu true” oder “Variable b wird true zugewiesen”.Variablen in Java müssen vor Verwendung deklariert und initialisiert werden. Andernfalls meldet der Compiler einen Übersetzungfehler.4 Programmbeispiel: SchaltjahreBetrachten wir zunächst ein Programm, dass die bisher vorgestellten Konzept an einempraktischen Beispiel erläutert: Wir wollen Programm schreiben, das für eine eingegebene Jahreszahl bestimmt, ob es sich um ein Schaltjahr handelt.Aus Wikipedia-Artikel Schaltjahr : Die durch 4 ganzzahlig teilbaren Jahre sind Schaltjahre.[.] Die durch 100 ganzzahlig teilbaren Jahre (z.B. 1700, 1800, 1900, 2100 und 2200)sind keine Schaltjahre. [.] Schließlich sind die ganzzahlig durch 400 teilbaren Jahre doch Schaltjahre. Damitsind 1600, 2000, 2400, . jeweils wieder Schaltjahre. [.]Eine mögliche Implementierung in Java ist diese hier (Schaltjahr.java):public class Schaltjahre {public static void main ( String [] args ) {String eingabe ;int jahr ;boolean istSchaltjahr ;eingabe args [0];jahr Integer . parseInt ( eingabe ) ;istSchaltjahr ( jahr % 4 0) && ( jahr % 100 ! 0) ;istSchaltjahr istSchaltjahr ( jahr % 400 0) ;System . out . println ( istSchaltjahr ) ;}}4.1 Eingabe/Ausgabe von DatenIn unseren Beispielen verwenden wir zunächst die Eingabe auf Kommandozeilenebene bei Programmstart. Das erste Argument ist in der main-Methode unter args[0]verfügbar; das zweite Argument unter args[1] verfügbar, etc. Da die Argumente immer als String-Werte übergeben werden, müssen sie evtl. in einen anderen Datentypumgewandelt werden ( siehe Abschnitt 4.2).11

Beispiel Compilieren und Ausführen von Schaltjahr mit Parameter: javac Schaltjahr.java java Schaltjahr 2004true java Schaltjahr 1900falseFehlt der Parameter beim Aufruf, wird ein Fehler ausgegeben!4.2 TypumwandlungenBisweilen muss man Werte eines Types in Werte eines anderen Typs umwandeln. Sowurde im Programmbeispiel zur Ermittlung von Schaltjahren in Abschnitt 4 das Kommandozeilenargument args[0], das vom Typ String ist, in einen Integer umgewandelt.Zur Umwandlung von Strings in numerische Werte gibt es spezielle Bibliotheksmethoden:int Integer.parseInt(String s)double Double.parseDouble(String s)boolean Boolean.parseBoolean(String s)Wandelt s in int-Wert umWandelt s in double-Wert umWandelt s in boolean-Wert umExpliziter Typumwandlung (Cast) Java hat auch Typumwandlungen für primitive Datentypen vorgesehen. Dieser muss explizit im Programm angegeben werden, indem der Typname in Klammern einem Ausdruck vorangestellt wird. Dabei muss manverstärkt auf die Klammerung achten, da Casts stärker binden als die arithmetischenund logischen Operatoren.Achtung: Bei dieser Art von Typumwandlung kann es zu Informationsverlust kommen. Beispiel: (int)2.71828 ergibt den int-Wert 2, (int)-2.9472 ergbit den int-Wert-2. Der Nachkomma-Teil wird dabei “abgeschnitten”.iAlternativ kann man Runden mittels der Bibliotheksfunktionlong Math.round(double d) und explizitem Cast von long auf int.Beispiel: (int) Math.round(2.71828) liefert 3.Automatische Promotion von Zahlen Daten von primitiven numerischen Typenkönnen in einem Kontext verwendet werden, wenn in diesem ein Wert eines Datentyps verwendet wird, der einen größeren Wertebereich abdeckt. Dabei ensteht keinInformationsverlust!Beispiel: Bei der Auswertung von 4.0 * 3 wird 3 zunächst automatisch in einen double-Wert umgewandelt; dannach wird die Multiplikation auf double durchgeführt.Um die Ausgabe von Werten primitiven Datentyps zu erleichtern, wandelt Java dieseautomatisch in Strings um, wenn diese Werte mit anderen Strings konkateniert werden.Beispiel: Bei der Auswertung von "Ocean’s " 11 wird 11 zunächst automatisch ineinen String-Wert "11" umgewandelt, dannach wird die Konkatenation auf Stringdurchgeführt.12

Hinweise zu den FragenHinweise zu Frage 1: Der Ausdruck (7 45) true ergibt sich zu false, da7 45 sich zu false ergibt und false true sich zu false ergibt.Für den Ausdruck sein !sein betrachten wir die zwei möglichen Fälle: Falls die Variable sein den Wert true hat, ergibt sich der Ausdruck zu true !true, was sich zu true ergibt. Falls die Variable sein den Wert false hat, ergibt sich der Ausdruck zu false !false, was sich ebenfalls zu true ergibt.Daher ergibt sich der Ausdruck sein !sein in jedem Fall zu true.Hinweise zu Frage 2:"seven" "three" ergibt"4" "5"ergibt"" 9 7ergibt9 7 ""ergibt"7" " " ""45""97""16""7 5"13

Programme k onnen auf verschiedene Arten ausgef uhrt werden: 1. Mittels Ubersetzung: Dabei wird der Programmtext in Maschinensprache ubersetzt und dann direkt vom Prozessor aus-gef uhrt. 2. Mittels direkter Interpretati-on: Hier wird der Programmtext von einem Interpreter ausgefuhrt, der wi