Datentypen - Kekziie/Informatik-II-SS-2017 GitHub Wiki
Speicherplatz für eine Variable wird vor der Ausführung der ersten Anweisung reserviert
Wichtig: Der Compiler muss wissen, wie viel Speicherplatz reserviert werden muss!
Konsequenz: Jede Variable hat eine feste Anzahl von Speicherstellen, die durch den ihren Typ festgelegt wird.
Wertebereich für ganze Zahlen
- byte [-128 ... 127]
- short [-32768 ... 32767]
- int [-2.147.483.648 ... 2.147.483.647]
- long [-2^63 ... 2^63 -1]
Vorsicht: Arithmetische Operationen dürfen den Wertebereich des Datentyps nicht überschreiten
Konsequenzen:
- Programmabbruch
- Variable enthält falschen Wert
Folgerung: Datentyp entsprechend wählen und Formeln eventuell umformen
Anzahl darstellbarer Zahlen beschränkt (abhängig von Wortlänge)
Vorzeichenbit:
- erstes Bit ("most significant bit") als Vorzeichen
- 0 -> positiv
- 1 -> negativ
- Probleme:
- es existieren 2 Darstellungen für Null, also 2 unterschiedliche Bitfolgen als Code für eine Zahl
- Addier-/ Subtrahierwerk notwendig -> kein Algorithmus zur Darstellung einer Subtraktion per Addition
- Logik erforderlich zur Erkennung von Addition oder Subtraktion
Einer-Komplement:
- komplementäre Darstellung
- einzelne Bits werden invertiert: 0->1; 1->0
- Problem:
- 2 Repräsentanten für Null
Zweier-Komplement:
- Konvertierung und Addition mit 1
- Eigenschaften:
- eindeutige Repräsentation von Null
Wertebereich für Gleitkommazahlen
- float [-3.402823510^38 ... 3.402823510^38]
- double [-1.79769310^308 ... 1.79769310^308]
Zahlen mit . -> automatisch als double interpretiert (z.B. -1.5 11.0)
Formatangaben:
- Zahlen müssen als float gekennzeichnet werden -> f anhängen (z.B. 1f 3.14f)
- mit d oder D als double gekenzeichnet (z.B. 5d -3.5D)
spezielle Werte:
- Float.NEGATIVE_INFINITY
- Float.POSITIVE_INFINITY
- Float.NaN (Not-a-Number)
Beispiel:
float fva11 = 10.0;
float fva12 = 0.0;
float fva13 = 0.0;
float fres1, fres2;
fres1 = fva11 / fva12; // Ausgabe: Infinity
fres2 = fva12 / fva13; // Ausgabe: NaN
Wertebereich: true & false
logische Operationen:
- Konjunktion &&
- Disjunktion ||
- Negation !
Vergleichsoperationen
- Gleichheit ==
- Ungleichheit !=
- kleiner <
- größer >
- kleiner gleich <=
- größer gleich >=
- boolesche Ausdrücke werden gebildet mithilfe von
- Vergleichsoperationen
- logische Operationen
- boolesche Ausdrücke können mithilfe bestimmter Regeln umgeformt werden (z.B. DeMorgan)
Beispiel:
float x = 5.0 f,
y = 18.0f;
int z = 7;
boolean a,b;
a = true;
b = (x > y) && (x < z) || (x == y) || a; // Ausgabe liefert true
Erklärung: && bindet stärker als || -> Konjunktion hat die höhere Präzedenz
Auswertung:
- boolesche Ausdrücke liefern Wahrheitswerte als Ergebnis
- Ausdrücke können aus mehreren Operanden bestehen
- Auswertung erfolgt sequentiell -> von links nach rechts
- Auswertung ggf. abgebrochen, falls Ergebnis feststeht und sich nicht ändern kann
Beispiel:
int x = 0;
...
... (x != 0) && ( y / x > 1)
Erklärung:
- (x != 0) && ergibt immer false
- Operand ( y / x > 1) nicht mehr ausgewertet -> Division durch 0 verhindert
Datentyp speicher jeweils ein einzelnes Zeichen
Wertebereich:
- Groß-/ Kleinbuchstaben
- Ziffern
- Satzzeichen
- Sonder-/Steuerzeichen
Hinweis: Java verwendet Zeichen vom Unicode (65536 Zeichen)
Notation:
- Zeichen werden mit Hochkomma geschrieben (z.B. 'a', 'D', '!' , '4' , '+', ...)
- Steuerzeichen werden durch back-slash eingeleitet (z.B. '\n' (Zeilenumbruch), '\t' (Tabulator), ...)
- Hilfszeichen ebenfalls mit back-slah eingeleitet (z.B. ''' (Apostroph), '\' (back-slash), ...)
String ist kein primitiver Datentyp!!
Beispiel:
Erzeugung von Strings durch Zeichenketten in Anführungszeichen
String s = "Hallo ",
name = "Peter";
Konkatenation (Aneinanderreihung von Zeichenketten)
String hello = "Hallo " + name;
Format:
- Klasse String stellt Funktionen zu Verfügung
- Aufruf von Funktionen auf Objekte vom Typ String
geg,:
String s1, s2;
int j, k;
char c;
s1.equals(s2); // boolesche Funktion (true: wenn s1 exakt gleich wie s2, sonst false)
s1.equalsIgnoreCase(s2); // boolesche Funktion (Funktion siehe oben, Groß-/Kleinschreibung gleichwertig)
s1.length(); // liefert Ergebnis vom Typ int mit Anzahl der Zeichen in s1
s1.charAt(k); // liefert Ergebnis vom Typ char, entspricht Zeichen an der k-ten Position von s1
s1.substring(j, k); // liefert Ergebnis vom Typ String, String enthält Zeichen von den Position j,j+1 ... k-1
// k wird nicht gelesen
s1.indexOf(s2); // liefert Ergebnis vom Typ int
// wenn s2 Substring von s1 -> liefert Position des Substrings in s1, sonst -1
s1.indexOf(c); // suche nach Zeichen c in s1
s1.indexOf(c,k); // suche nach Zeichen c in s1 ab Position k in s1
s1.toUpperCase();
s1.toLowerCase(); // liefert Ergebnis vom Typ String
// wie s1 im Zeichen konvertiert wurde, die nicht der Zeichenform des Ziels entsprechen
s1.trim(); // liefert Ergebnis vom Typ String,
// neue Zeichenkette, bei der alle leer-druckenden Zeichen (z.B. Leertaste) entfernt wurden
Beispiel:
String a = "text",
b = "text";
String c = new String("text"); // generiert ein neues Objekt vom Typ String
System.out.println(a == b); // Ausgabe liefert true
System.out.println(a.equals(b)); // Ausgabe liefert true
System.out.println(a == c); // Ausgabe liefert false
System.out.println(a.equals(b)); // Ausgabe liefert true
- Operatoren lassen sich nicht nur auf Operanden des selben Datentyps verwenden
- werden typkompatible Operanden durch Operator verknüpft -> implizite Datentyp-Anpassung
- Typkonversion -> auf allgemeineren Datentyp
Konvertierungsschema
byte -> short -> int
char -> int -> long -> float -> double
char/double/boolean ---> String
Besonderheiten:
- Typkonversion zu String ist eigentlich keine implizite Typkonversion
- Reihenfolge der Operatoren muss beachtet werden
Beispiel:
System.out.println(17 + " und " + 4); // Ausgabe liefert: 17 und 4
System.out.println(17 + 4 + " und "); // Ausgabe liefert: 21 und
Typkonvertierung mit Genauigkeitsverlust oder Bedeutungsänderung.
- Umwandlung nicht in implizit möglich
- vom Programmierer explizit vorgenommen
- gewünschte Datentyp in Klammern dem Ausdruck vorangestellt
Beispiel:
double x = 65.2d;
int i = (int) (x / 3.0); // liefert Ergebnis 21
char y = (char) (int) x; // liefert Ergebnis 'A'
Notiz: vorsichtig verwenden -> wenn möglich ganz vermeiden
- Möglichkeit zur Definition neuer Datentypen und Klassen
- Aufzählung enum ist ein Typ mit einer festgelegten Liste der möglichen Werte
- Definition kann nicht innerhalb eines Unterprogramms erfolgen
- sie kann außerhalb der main()-Routine platziert werden
Allgemein:
enum <enum-Typ-Name> {<Werte-Liste>}
Erläuterung:
- : beliebiger einfacher Bezeichner
- : jedes Element einfacher Bezeichner, Listenelemente durch Komma getrennt
- Konvention: Werte der Aufzählung in Großbuchstaben geschrieben
Beispiel:
enum Season {SPRING, SUMMER, FALL, WINTER}
Definition:
- enum ist technisch gesehen eine Klasse
- Werte einer enum-Variable sind technisch gesehen Objekte
- als Objekte können sie Unterprogramme oder Funktionen enthalten, die auf Objekte des Typs enum ausgeführt werden können
Beispiel 1:
enum Day {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY};
// Definition des enum-Typs Day außerhalb der Methode
public static void main (String[] args) {
Day day;
day = Day.SUNDAY // Zuweisung kann nur die in der Typdeklaration definierten Werte verwenden
System.out.println("Tag: " + dy + " ist der " + (day.ordinal()+1) + ". Tag der Woche");
} // end main
Beispiel 2: Aufzählung in switch-Anweisung
enum Season {SPRING, SUMMER, FALL, WINTER};
...
Season currentSeason = Season.FALL;
switch (currentSeason) {
case WINTER: // (nicht Season.WINTER!)
System.out.println("December, January, February");
case SPRING:
System.out.println("March, April, May");
case SUMMER:
System.out.println("June, July, August");
case FALL:
System.out.println("September, October, November");
break;
}
Hinweis: Hier werden die Werte des Aufzählungstyps in den case labels nicht mittels und Selektor . angesprochen!!
Zählschleifen auf Aufzählungsmengen
for (<enum-Typ-Name> <Variable>:
<enum-Typ-Name>.values() )
<Anweisung>;
for (<enum-Typ-Name> <Variable> : <enum-Typ-Name>.values() ) {
<Anweisungen>;
}
Erläuterung:
- : lokal in der for-Schleife definiert (vom Typ )
- .values() : Funktion, die eine Liste der Werte der Aufzählung liefert
- values() ist eine statische Klassenfunktion von enum
Beispiel:
enum Day {MON, TUE, WED, THU, FRI, SAT, SUN};
...
for (day d : Day.values() )
System.out.println (d + " ist der " + (d.ordinal()+1) + ". Tag der Woche");
// liefert Ergebnis: MON ist der 1. Tag der Woche
// TUE ist der 2. Tag der Woche
// usw.