Primitive Datentypen und Felder (Arrays)

Ähnliche Dokumente
Kapitel 4. Programmierkurs. Datentypen. Arten von Datentypen. Wiederholung Kapitel 4. Birgit Engels, Anna Schulze WS 07/08

1. Referenzdatentypen: Felder und Strings. Referenz- vs. einfache Datentypen. Rückblick: Einfache Datentypen (1) 4711 r

1. Referenzdatentypen: Felder und Strings

5.1 Mehr Basistypen. (Wie viele Werte kann man mit n Bit darstellen?)

Kapitel 3: Variablen

Einstieg in die Informatik mit Java

Variablen. CoMa-Übung VIII TU Berlin. CoMa-Übung VIII (TU Berlin) Variablen / 15

Institut für Programmierung und Reaktive Systeme. Java 2. Markus Reschke

Hello World! Eine Einführung in das Programmieren Variablen

Programmiervorkurs Einführung in Java Tag 1

Informatik Vorkurs - Vorlesung 2

Vorkurs Informatik WiSe 16/17

Martin Unold INFORMATIK. Geoinformatik und Vermessung

Kapitel 3. Grunddatentypen, Ausdrücke und Variable

2.5 Primitive Datentypen

Einstieg in die Informatik mit Java

JAVA-Datentypen und deren Wertebereich

Programmieren 1 C Überblick

Grundlagen der Informatik 2. Operatoren

Vorkurs Informatik WiSe 17/18

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 12/13. Kapitel 3. Grunddatentypen, Ausdrücke und Variable

PROCESSING EINE ZUSAMMENFASSUNG. Created by Michael Kirsch & Beat Rossmy

Prof. Dr. Oliver Haase Karl Martin Kern Achim Bitzer. Programmiertechnik Operatoren, Kommentare, Ein-/Ausgabe

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 1 - Variablen und Kontrollstrukturen

Die Sprache C# Datentypen, Speicherverwaltung Grundelemente der Sprache. Dr. Beatrice Amrhein

Basiswissen in Informatik

4.2 Gleitkommazahlen. Der Speicherbedarf (in Bits) ist üblicherweise. In vielen Anwendungen benötigt man gebrochene Werte. Physikalische Größen

Einfache Rechenstrukturen und Kontrollfluss

Projekt 3 Variablen und Operatoren

Java I Vorlesung Imperatives Programmieren

Java - Zahlen, Wahrheitswerte und Zeichen. Leibniz Universität IT Services Anja Aue

Algorithmen als systematische Vorgehensweisen zur Lösung eines formal definierten Problems

Grundlagen der Informatik Ergänzungen WS 2007/2008 Prof. Dr. Rainer Lütticke

3. Java - Sprachkonstrukte I

Schwerpunkte. 8. Ausdrücke, Operatoren (einfache Typen) Beispiel: Schaltjahr Test. Einführendes Beispiel: Grundprobleme

float: Fließkommazahl nach IEEE 754 Standard mit 32 bit

Algorithmen als systematische Vorgehensweisen zur Lösung eines formal definierten Problems

Die Sprache C# Datentypen, Speicherverwaltung Grundelemente der Sprache. Dr. Beatrice Amrhein

3. Java - Sprachkonstrukte I

Programmierkurs C++ Variablen und Datentypen

Übungen zur Vorlesung Wissenschaftliches Rechnen I

Operatoren und Ausdrücke

2.1 Fundamentale Typen

C-Programmierung: Ausdrücke und Operatoren#Division.2F

Variablen, Konstanten und Datentypen

3.8 Objekttypen und Arrays. Wir werden uns in diesem Kapitel näher mit den Objekttypen in Java beschäftigen.

Programmiertechnik Skalare Typen,Variablen, Zuweisungen

Java - Zahlen, Wahrheitswerte und Zeichen. Leibniz Universität IT Services Anja Aue

Grundlagen der Programmiersprache C für Studierende der Naturwissenschaften

Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen. Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen

Grunddatentypen, Ausdrücke und Variablen Typkonversion, Überprüfen und Auswerten von Ausdrücken

3. Java - Sprachkonstrukte I

4.2 Programmiersprache C

Kapitel 4: Elementare Konzepte von Programmiersprachen. Variablen Referenzen Zuweisungen

Wertebereich und Genauigkeit der Zahlendarstellung

Primitive Datentypen in Haskell

8. Ausdrücke, Operatoren (einfache Typen)

Objekttypen. Referenzen, Objekte, Gleichheit, Wrapper, Arrays, mehr-dimensionale Arrays, Bildbearbeitung, krumme Arrays

Objekte. Theorieteil. Inhaltsverzeichnis. Begriffe. Programmieren mit Java Modul 5. 1 Modulübersicht 3

Java Einführung VARIABLEN und DATENTYPEN Kapitel 2

JAVA BASICS. 2. Primitive Datentypen. 1. Warum Java? a) Boolean (logische Werte wahr & falsch)

3.2 Datentypen und Methoden

Primitive Datentypen, Eingaben, Kontrollstrukturen und Methodendeklaration

5.4 Arrays. Oft müssen viele Werte gleichen Typs gespeichert werden. Idee: Lege sie konsekutiv ab! Greife auf einzelne Werte über ihren Index zu!

Elementare Konzepte von

Kapitel 4. Programmierkurs. Arten von Datentypen. Datentypen

Einstieg in die Informatik mit Java

Operatoren in C/C++ und Java:

Einführung in C. EDV1-04C-Einführung 1

Arrays. Theorieteil. Inhaltsverzeichnis. Begriffe. Programmieren mit Java Modul 3. 1 Modulübersicht 3

Java für Anfänger Teil 5: Basistypen 2. Programmierkurs Manfred Jackel

Abschnitt 2: Daten und Algorithmen

JAVA BASICS. 2. Primitive Datentypen. 1. Warum Java? a) Boolean (logische Werte wahr & falsch)

Kapitel 2: Ausdrücke. 1. Sorten und abstrakte Datentypen. 2. Ausdrücke 2.1 Syntax 2.2 Semantik 2.3 Ausdrücke in Java. 3. Funktionale Algorithmen

Algorithmen zur Datenanalyse in C++

Grundlagen der OO- Programmierung in C#

Organisatorisches. Folien (u.a.) auf der Lva-Homepage Skriptum über MU Online

5.3 Auswertung von Ausdrücken

Transkript:

Primitive Datentypen und Felder (rrays) Primitive Datentypen Java stellt (genau wie Haskell) primitive Datentypen für Boolesche Werte, Zeichen, ganze Zahlen und Gleitkommazahlen zur Verfügung. Der wichtigste Unterschied zu Haskell besteht darin, dass man in Java zwischen vier verschiedenen Typen für ganze Zahlen und zwei verschiedenen Typen für Gleitkommazahlen wählen kann (und darüber hinaus muss man sich daran gewöhnen, dass die Typbezeichnungen mit Kleinbuchstaben beginnen). Diese verschiedenen Typen unterscheiden sich nach Größe des für sie reservierten Speicherplatzes und folglich auch nach dem Bereich der darstellbaren Zahlen. Die folgende Tabelle zeigt die vier Typen von ganzen Zahlen mit Vorzeichen (signed integers): Typbezeichnung Speicherplatz Darstellungsbereich byte 8 Bit = 1 Byte [ 128,127] short 16 Bit = 2 Byte [ 32768,32767] int 32 Bit = 4 Byte [ 2 31,2 31 1] long 64 Bit = 8 Byte [ 2 63,2 63 1] Für Gleitkommazahlen gibt es neben dem bekannten Typ float mit 4 Byte Speicherplatz auch den Typ double mit 8 Byte Speicherplatz. Dieser wird primär zur Verbesserung der Präzision der Darstellung und nur sekundär zur Erweiterung des Darstellungsbereichs verwendet. In der Reihenfolge byte, short, int, long kann der Wert einer Variable eines niederen Typs immer einer Variable des höheren Typs zugewiesen werden. Gleiches gilt für float und double und für die Zuweisung von ganzzahligen Werten auf Gleitkomma Variable. Da der umgekehrte Weg leicht zu Fehlern führen kann, ist eine solche Zuweisung nur dann möglich, wenn diese Typumwandlung (type cast) explizit gefordert wird. Dazu wird, wie das folgende Beispiel zeigt, der Typ, in den umgewandelt werden soll, in Klammern vor den umzuwandelnden usdruck gestellt: int i = 1000; short k = (short)i; Typumwandlungen, bei denen der umzuwandelnde Wert nicht im Darstellungsbereich des neuen Typs liegt, führen zu Fehlern. Für die sechs genannten numerischen Typen kann man die arithmetischen Operationen +,-,* und / verwenden, wobei die Operation / bei allen ganzzahligen Typen auch die ganzzahlige Division ausführt. Der Rest bei der ganzzahligen Division wird mit der Operation % bestimmt. Der Inkrement Operator ++ und der Dekrement Operator -- sind für alle numerische Typen anwendbar und bewirken die ddition bzw. die Subtraktion von 1. Man kann beide in Präfix Notation (vor dem rgument) und Suffix Notation (nach dem rgument) verwenden. Ein Unterschied macht sich dann bemerkbar, wenn der Operator in einer Wertzuweisung angewendet wird: Bei Präfix Notation wird erst die Operation ausgeführt und dann der Wert zugewiesen, bei Suffix Notation erfolgt zuerst die Wertzuweisung und dann die Operation. Das folgende Beispiel verdeutlicht diesen Unterschied: int i = 20; ink k = i++; // aktuelle Werte: k=20 und i=21 int l = --k; // aktuelle Werte: k=19 und l=19

Die Vergleichsoperationen ==,!=,<,<=,>,>= liefern auf allen numerischen Typen Boolesche Werte. Variable vom Typ boolean können nur die Werte true und false annehmen. ls Operationen auf Booleschen Werten kann man die Negation! (einstellig), die Konjunktion && sowie die Disjunktion verwenden. Der Typ char verfügt (wie in Haskell) über 16 Bit, mit denen alle Unicode Zeichen dargestellt werden können. Werte vom Typ char können ohne explizite Typumwandlung auf Variable der Typen int, long, float, double zugewiesen werden, für die Gegenrichtung ist eine explizite Typumwandlung erforderlich. Zu jedem primiten Datentyp ist eine sogenannte Wrapper Klasse definiert. Mit zwei usnahmen (int, char) tragen diese Klassen jeweils den gleichen Namen, aber mit Großbuchstaben am nfang: Byte, Short, Integer, Long, Float, Double, Boolean, Character Wie ein kurzer Blick in daie Systembeschreibung PI (pplication Programming Interface, zu finden unter -> http://java.sun.com/j2se/1.5.0/docs/api/) verrät, stellen die Wrapper Klassen eine Reihe nützlicher Funktionen zur Verfügung. Darüber hinaus bieten sie aber auch die Möglichkeit, Zahlen oder Zeichen wie ein Objekt (-> nächste Themen) zu behandeln. Bei der Deklaration einer Variablen eines primitiven Typs wird (bei der Programmausführung) ein ensprechend großer bschnitt im Speicher reserviert, der mit dem Namen der Variablen assoziiert ist. Wenn mit der Deklaration noch keine Wertzuweisung erfolgt, wird der Speicherplatz mit einem sogenannten Default Wert belegt, nämlich 0 für alle ganzzahligen Typen, 0.0 für Gleitkommatypen, false für boolean und das durch 16 Nullen codierte Zeichen NUL für den Typ char. Bei einer Zuweisung der Form x = ausdruck; wird der Wert von ausdruck auf den Speicherplatz von x kopiert. Variable eines primitiven Typs haben also immer einen Wert und können deshalb auch als Werttypen bezeichnet werden. Im Gegensatz dazu sind alle anderen Datentypen in Java sogenannte typen, d.h. ihr Name ist nicht mit einem konkreten Objekt dieses Typs, sondern mit einer (Verweis) assoziiert, die auf solch einen Objekt oder aber auf null (ein symbolischer usdruck für NICHTS) verweist. Mit einer Zuweisung wird in einem solchen Fall nicht das Objekt kopiert, sondern nur die auf dieses Objekt. en sind mehr als nur ein einfacher Zeiger, aber man kann sich eine gut als einen Zeiger auf einen bestimmten Speicherinhalt vorstellen. Das Prinzip kommt bereits bei einem Datentyp zum Tragen, der eine Zwitterstellung zwischen primitiven Datentypen und Objekten einnimmt, dem sogenannten Feld (rray). Felder Ein Feld oder rray repräsentiert einen Folge von Daten gleichen Typs und belegt dabei einen zusammenhängenden Speicherabschnitt. Die Daten in einem Feld der Länge n sind von 0 bis n 1 nummeriert. Es gibt zwei Möglichkeiten, ein rray zu deklarieren, in der Vorlesung bevorzugen wir die Varainte typename [ ] arrayname; aber alternativ kann auch typename arrayname [ ]; verwendet werden. Die Leerzeichen zwischen dem Namen und der öffnenden Klammer bzw. zwischen den Klammern wurden nur zur besseren Lesbarkeit gesetzt, man kann auf beide verzichten. Mit einer solchen Deklaration wird eine angelegt, die auf null, also auf nichts verweist. Wie bei primitiven Datentypen kann man die Deklaration auch mit einer Zuweisung verbinden. Dazu muss das zugewiesene rray

entweder schon deklariert sein, oder es muss im Speicher angelegt werden. uch für das Neuanlegen gibt es zwei Möglichkeiten, nämlich nur die Feldlänge anzugeben (und damit alle Speicherzellen mit Default Werten zu füllen) oder alle Daten, die im rray gespeichert werden sollen, direkt aufzulisten (womit die Feldlänge implizit festgelegt wird). Das folgende Beispiel demonstriert diese Varainten: int[] a1; // a1 ist ( auf) null int[] a2 = new int[4]; /* a2 ist ( auf) ein int-rray der Laenge 4, in dem alle Eintraege den Default-Wert 0 haben */ int[] a3 = {1,2,3}; // a3 ist ( auf) ein int-rray der Laenge 3 int[] a4 = a2; // a4 ist ( auf) auf gleiches rray wie a2 int[] a5 = a1; // a5 ist ( auf) null Wie man sieht, wird bei einer Zuweisung nur die übertragen, es erfolgt keine Kopie des eigentlichen Feldes im Speicher. uf den i ten Eintrag eines rrays a kann man mit a[i] zugreifen, die Länge steht als Eigenschaft a.length zur Verfügung. Wir illustrieren das an einer Fortsetzung des obigen Beispiels: int i = a3[1]; // i hat den Wert 2, denn die Nummerierung beginnt mit 0 a2[3] = 5; // eine 0 wird mit 5 ueberschrieben int j = a4[3] /* j hat den Wert 5 weil a2 und a4 auf das gleiche rray verweisen */ Die letzte Zeile macht noch einmal deutlich, dass nach Zuweisung von rray Variablen (wie in unserem Beispiel a4=a2;) jede Änderung an dem durch die eine Variable referenzierten Objekt auch für die andere Variable wirksam ist. Das ist ein fundamentaler Unterschied zu Variablen für primitiven Datentypen: int n1 = 3; // int n2 = n1; // beide haben den Wert 3 n1 = 5; // n1 hat den Wert 5, aber n2 hat immer noch den Wert 3 Bei der Verwendung des Operators == auf Variable eines nichtprimitiven Typs muss man beachten, dass die en auf Gleichheit getestet werden und es nicht darauf ankommt, ob die referenzierten Objekte gleich sind oder nicht. uch diesen Effekt kann man an einem einfachen Beispiel demonstrieren: int[] = {2,3,4} // ein erstes rray mit Eintraegen 1,2,3 wir angelegt int[] B = ; // B ist auf das gleiche rray int[] C = {2,3,4} // ein zweites rray mit Eintraegen 1,2,3 wir angelegt boolean c = ( == C); /* c ist false, denn die en verweisen auf zwei verschiedene Speicherabschnitte */ boolean b = ( == B); // b ist true, beide en verweisen auf erstes rray In der folgenden Grafik ist dargestellt, wie die usführung der ersten drei Zeilen des Codes im Speicher realisiert wird.

Code Variable Speicher int[ ] = {2,3,4}; int[ ] B = ; B int[ ] C = {2,3,4}; B C

Um eine wirkliche Kopie eines rrays zu erzeugen, verwendet man die Funtion clone(). us Gründen, die erst später klar werden, muss aber zusätzlich noch eine Typumwandlung erfolgen: int[] = {1,2,3} // ein erstes rray mit Eintraegen 1,2,3 wird angelegt int[] B = (int[]).clone(); /* ein zweites rray mit Eintraegen 1,2,3 wird als Kopie des ersten rrays angelegt */ boolean b = ( == B); /* b ist false, en sind verschieden Durch die Verwendung von mehreren Klammerpaaren können höherdimensionale rrays, mit anderen Worten Felder von Feldern, angelegt werden. Das folgende Beispiel zeigt wieder die verschiedenen Möglichkeiten auf, solche rrays zu deklarieren und zu definieren. int[][] ; // auf null int[][] B = new int[3][]; /* auf Feld der Laenge 3, dessen Eintraege jeweils en auf null sind */ int[][] C = new int[3][2]; /* auf Feld der Laenge 3, dessen Eintraege jeweils en auf int-felder der L\"ange 2 sind */ int[][] D = new int[][2]; // Fehler int[][] E = {{1,2}{2,2,5}{4}}; // gueltig trotz verschiedener Laengen Bei der Verwendung der Methode clone() ist wieder volle ufmerksamkeit geboten. Entwerfen Sie für das folgende Beispiel ein grafischen Schema nach obigem Vorbild, um sich die in den Kommentaren genannten Fakten klar zu machen. int[][] data = {{1,2,3}{4,5}}; int[][] copy = (int[][]) data.clone(); copy[0][0] = 100; // data[0][0] hat auch den Wert 100 copy[1] = new int[] {7,8,9}; // data[1] hat sich nicht geaendert