Datentyp- umwandlung. Literale sind: Bezeichner mit einem festen Wert wie z.B:

Slides:



Advertisements
Ähnliche Präsentationen
der Universität Oldenburg
Advertisements

Imperative Programmierung
3. Operatoren und Ausdrücke
Funktionen.
Forschungszentrum caesar
Variablen und Datentypen
der Universität Oldenburg
Indirekte Adressierung
Das Halteproblem. Gibt es einen Algorithmus, mit dem man für jedes beliebig vorgegebene Programm R und für jede beliebig vorgegebene Eingabe E entscheiden.
SWITCH - Anweisung.
SWITCH - Anweisung.
REKURSION + ITERATION. Bemerkung: Die in den folgenden Folien angegebenen "Herleitungen" sind keine exakten Beweise, sondern Plausibilitätsbetrachtungen.
Strukturen. In einer Struktur kann eine beliebige Anzahl von Komponenten (Daten) mit unterschiedlichen Datentypen (im Gegensatz zu Feldern) zusammengefaßt.
ARRAY oder FELD oder VEKTOR
Programmier-sprache Java Weiter mit PP..
Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet.
Klassenvariable. Da man für jede Kuh bzw. jede Henne auf dem Markt den gleichen Preis für ein Liter Milch, bzw. den gleichen Preis für ein Ei bekommt,
Konstruktoren.
Objekte werden als Adressen (Referenzen) übergeben. Dies führt manchmal zu unerwarteten Ergebnissen...
Programmier-sprache C Weiter mit PP..
Polymorphie (Vielgestaltigkeit)
Objekte und Arbeitsspeicher
V AdresseWert public static void main(...){ int[] v; v=new int[2]; } Was veranlasst diese Anweisung im Arbeitsspeicher ? Es wird im Arbeitsspeicher.
Der Präprozessor. Bevor der Compiler das Programm in Maschinencode übersetzt (nur dieser kann von der CPU, dem Herz des Computers, bearbeitet werden)
Dynamischer Speicher. In einer Funktion wird z.B. mit der Deklaration int i; Speicher auf dem sogenannten Stack reserviert. Wenn die Funktion verlassen.
ARRAY oder FELD oder VEKTOR
Basisinformationstechnologie WS 2003/04 T.Schaßan
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 1 Gisbert Dittrich; Claudio Moraga FBI Unido
Imperative Programmierung
PKJ 2005/1 Stefan Dissmann Zusammenfassung Vorwoche Programm besteht aus mehreren Bestandteilen: Schlüsselwörter Sonderzeichen Bezeichner Kommentare Texte.
Zusammenfassung Vorwoche
Das erste Programm (Folie 16)
DVG Methoden 1 Methoden. 2 int dezi = Integer.parseInt(args[0]); boolean vz = (dezi>=0); dezi = Math.abs(dezi); String Bin = ""; do { } while.
Wichtige Fachausdrücke in C
Einführung in die Programmiersprache C 1
Einführung in die Programmiersprache C 3.Tag Institut für Mathematische Optimierung - Technische Universität Braunschweig.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Informatik 1 Letzte Übung.
Informatik I for D-MAVT
Programmierung 1. Einführung Seite 1
Arduino Kurs Abend 2.
Variablen in Programmiersprachen
© 2004 Pohlig - Taulien Explizite Typenumwandlung.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Programmieren in C Grundlagen C 2
BMEVIEEA100 Grundlagen der Programmierung
Hochschule Fulda – FB ET Sommersemester 2014
Hochschule Fulda – FB ET Sommersemester 2014
Programmieren in C Grundlagen C 2
Vordefinierte Datentypen (1)
Kapitel 5Strukturen Information aus der realen Welt werden in einem informationsverarbeitenden System als Daten abgelegt. Diese stellen also eine (vereinfachte)
Sequenzen: Lineare Programme
Variablen und Datentypen
Funktionen. Aufgabe : Eingabe zweier Zahlen ---> Minimum bestimmen Dann nochmals Eingabe zweier Zahlen ---> Minimum bestimmen.
Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet.
Funktionen, Felder und Parameter- übergabe. Funktionsaufruf mit Feld als Parameter: Parameter = Name des Feldes.
Namensräume (namespaces). verwendet man umfangreiche eigene und fremde Bibliotheken (Sammlungen von Funktionen) so ist die Wahrscheinlichkeit groß, daß.
Tutorium Software-Engineering SS14 Florian Manghofer.
FOR Anweisung. Aufgabe : Ausgabe aller ganzen Zahlen von 0 bis 100 auf dem Bildschirm.
Tutorium Software-Engineering SS14 Florian Manghofer.
Konstruktoren.
Datentypen: integer, char, string, boolean
Variable: typ varName = Wert Kiste: Art Aufschrift  Inhalt
SS 04 Christiane Rauh Christian Hellinger
Zufallszahlen in C erzeugen
Datentyp- umwandlung.
Explizite Typenumwandlung
 Präsentation transkript:

Datentyp- umwandlung

Literale sind: Bezeichner mit einem festen Wert wie z.B:

237(dezimale Angabe) 034 (oktale Angabe) 0x51f (hexadezimale Angabe) 3.14(Fließkommazahl) 'x'(Zeichen) "abc"(Zeichenkette)

Literale sind dem Compiler bekannt und müssen nicht - wie Variable - deklariert (angemeldet) werden.

Welchen Datentyp hat ein Literal ?

Welchen Datentyp hat z.B. eine Ganzzahl wie ? Kann diese z.B. den Datentyp int annehmen ?

Dazu muss man sich fragen : 1) Wie viele Bytes werden für int (in MS VC++) reserviert ? 2) Welchen Zahlenbereich umfasst der Datentyp int (in MS VC++) ?

... und stellt dann fest: 4 Bytes reserviert MS VC++ für int. Man kann also 2 32 = Zahlen abspeichern. Da int auch negative Zahlen umfasst, geht der Zahlenbereich von:

Kann also die Ganzzahl mit dem Datentyp int abgespeichert werden ?

Nein, denn int umfasst nur den Zahlenbereich von:

Also wird Ganzzahlen zwischen: der Datentyp int zugeordnet und Ganzzahlen zwischen der Datentyp unsigned int zugeordnet

Ganzzahlen werden also - abhängig vom Wert - folgende Datentypen zugeordnet:

dezimale Ganzzahl: int unsigned int long z.B: 1234 z.B: unsigned long Siehe Hilfe in MS VC++

Einer Fließkommazahl wird der folgende Datentyp zugeordnet: double

Beispiel:... int i,j; double d; i=2*3; d=1.9*2.1; j=4/5;... Welchen Datentyp hat 2*3, 1.9*2.1 und 4/5 ?

Merke:

int + int = int int - int = int int * int = int int / int = int float + float = float float - float = float float * float = float float / float = float double + double = double double - double = double double * double = double double / double = double Weil z.B. 3/10 keine ganze Zahl (integer) ergibt. Welche der Regeln widerspricht unserer Alltagsmathematik?

Welche Datentypen haben also die folgenden Ergebnisse: double 1.9 * 2.1 double Ergebnis: 3.99 double * double = double

double 3.0 / 2.0 double Ergebnis: 1.5 double /double = double

integer 2 * 3 integer Ergebnis: 6 integer * integer = integer

integer 8 / 5 integer Ergebnis: Der Nachkommateil von 8/5 = 1.6 (also 0.6) wird entfernt. Also ist das Ergebnis: 1 integer / integer = integer

Problem: Verschiedene Datentypen in einem Ausdruck Welchen Datentyp hat der gesamte Ausdruck ?

Beispiel:

... int i; double d; double erg; i=2; d=3.14; erg=i*d;... Welchen Datentyp hat i*d ?

Antwort: Gemischte Datentypen werden nicht akzeptiert !!! Deshalb muss vorher eine Datentyp-Umwandlung gemacht werden !!!

Dazu gibt es zwei Möglichkeiten:

Implizite Typumwandlung (macht der Compiler selbst, ohne Zutun des Programmierers) Explizite Typumwandlung mit dem cast-Operator (muss der Programmierer machen ) und

Implizite Typumwandlung: wandelt alle "kleineren" Datentypen in die "grösseren" um.

Tabelle Typumwandlung:

long double double float unsigned long long unsigned int int charsigned char unsigned char shortunsigned short grösser Diese Datentypen werden direkt in integer umgewandelt:

... char c1 = 64; char c2 = 64; int i = c1 * c2;... Welcher Wert wird in i gespeichert ? Was geschieht im Einzelnen ? Laut der "Tabelle Typumwandlung" wird der Wert von c1 und c2 sofort in int umgewandelt, nicht erst das Ergebnis c1*c2 Der Wert von c1 * c2, also 4096 wird dann in i gespeichert.

Beispiel:

... int i; double d; double erg; i=2; d=3.14; erg=i*d;... Welchen Datentyp hat i*d ? //double: erg=6.28 wird umgewandelt in double, also: 2.0 double, also: 3.14 double * double = double

Explizite Typumwandlung (mit cast-Operator): Wandelt mit dem cast- Operator ( ) den Datentyp um.

Beispiel:

... int i; double d; double erg; i=2; d=3.14; erg=d*(double)i;... double, also: 2.0 double, also 3.14 integer, also: 2 double * double = double

Beispiel:

... int i; double d; int erg ; i=2; d=3.14; erg=i*(int)d;... Warum gibt es ein Problem ? Es entsteht ein Datenverlust durch (int) d double, also: 3.14 integer, also: 3

Bei einem möglichen Datenverlust bringt der MS VC++ Compiler eine Warnung, keine Fehlermeldung.

Der Compiler prüft dabei nicht nach, ob es tatsächlich einen Datenverlust gibt, sondern nur, ob ein "größerer Datentyp" in einem "kleineren Datentyp" abgespeichert werden soll und deshalb der dafür vorgesehene Speicherplatz nicht ausreicht.

ACHTUNG: Es ist nicht normiert, wann der Compiler eine Warnung bringen muss.

Problem: Bei der Datentypumwandlung eines größeren Datentyps in einen kleineren Datentyp kann (muß aber nicht) ein Informationsverlust entstehen.

Konkretes Beispiel für einen Informationsverlust

int main(){ int i; char z; i = 321; z = (char) i; printf("z=%c",z); } aus wieviel Bytes besteht i ? 4 Bytes Wie sieht die Dualdarstellung von i aus ? welche Bytes werden abgeschnitten ? die Höherwertigen aus wieviel Bytes besteht z ? 1 Byte

int main(){ int i; char z; i = 321; z = (char) i; printf("z=%c",z); } Welches Zeichen wird ausgegeben ? (siehe ASCII-Tabelle) A entspricht dezimal 65

int main(){ int i; char z; i = 321; z = i; printf("z=%c",z); } Was ist hier anders im Vergleich zum letzten Programm ? Der explizite cast-Operator (char) fehlt. Der Wert von i, nämlich 321 ist zu groß, als dass er in der Variable z gespeichert werden kann. Deshalb wird i implizit in den Datentyp char umgewandelt (Compiler bringt Warnung). Allgemein gilt: Soll bei einer Zuweisung ein größerer Wert in einer Variablen gespeichert werden, als diese aufnehmen kann, so wird vorher eine implizite Typumwandlung gemacht.

int main(){ double d; int i=2; d=i; return 0; } Was ist hier anders im Vergleich zum letzten Programm ? Der Wert von i soll in einem "grösseren" Datentyp abgespeichert werden. Deshalb wird i implizit in den grösseren Datentyp double umgewandelt. Allgemein gilt: Soll bei einer Zuweisung ein kleinerer Wert in einer Variablen eines "grösseren" Datentyps gespeichert werden, so wird vorher eine implizite Typumwandlung in den grösseren Datentyp gemacht.

Noch ein Beispiel:

int main(){ float f; f = ; return 0; } Warnung: double ---> float Ergebnis: f1 = doublefloat Es findet also ein tatsächlicher Datenverlust statt, weil double mehr Nachkommastellen speichert als float.

Grosses Beispiel:

int main(){ float f1, f2; double d1, d2; int i1, i2; f1 = 2.3; i1 = 4; i2 = (float)f1; d1 = 3.14; f1 = 6-1/20*f1; f2 = 6-f1/20; // weiter...

f2 = 6-((float)1/(float)20)*f1; f2 = 6-(1/(float)20)*f1; f2 = 6-(1/20)*f1; f2 = 6-(1.0/20.0)*f1; f2 = *f1; f2 = 0.05*f1; d2 = 6-(1.0/20.0)*f1; d2 = *f1; d2 = 0.05*f1; d2 = 3/5; d2 = 3.0/5.0; }

d2 = i1 * 2.718; }

f1 = 2.3; doublefloat Warnung: double ---> float Ergebnis: f1 = 2.3

i1 = 4; int okay: Ergebnis: i1 = 4

i2 = (float)f1; float int Warnung: float ---> int i2 = 2 cast float

d1 = 3.14; double okay: Ergebnis: d1 = 3.14

f1 = 6 – 1 / 20 * f1; implizit:(float)0 okay: Ergebnis: f1 = 6 float (konkret 2.3) int implizit: (float)6 int / int = int also: 1 / 20 = 0 float int float Punkt vor Strich

f2 = 6 – f1 / 20; okay: Ergebnis: f2 = 5.7 float, konkret 6 int implizit: (float)20 float / int deshalb: float / (float)int = float, also: 6.0 / 20.0 = 0.3 int float int - float deshalb: (float)int – float = float, also: 6.0 – 0.3 = 5.7 implizit: (float)6

f2 = 6-((float)1/(float)20)*f1; 6.0 float / float = float also: 1.0 / 20.0 = 0.05 float float * float = float also: 0.05 * 6.0 = 0.3 int implizit: (float)6 float - float = float also: 6.0 – 0.3 = 5.7 float cast okay: Ergebnis: f2 = 5.7

f2 = 6-(1/(float)20)*f1; 6.0 int / float deshalb: (float)int / float = float float float * float = float also: 0.05 * 6.0 = 0.3 int implizit: (float)6 float - float = float also: 6.0 – 0.3 = 5.7 float cast okay: Ergebnis: f2 = 5.7

f2 = 6-(1/20)*f1; 6.0 int / int = int, also: 1 / 20 = 0 float - float = float also: = 6.0 int float * float = float also: 0.0 * 6.0 = 0.0 float okay: Ergebnis: f2 = 6.0 int float implizit:(float)0 int implizit: (float)6

f2 = 6-(1.0/20.0)*f1; 6.0 double / double = double, also: 1.0 / 20.0 = 0.05 double - double = double also: = 5.7 double * double = double also: 0.05 * 6.0 = 0.3 float Warnung: double --->float Ergebnis: f2 = 5.7 int float implizit: (double)6 double implizit: (double)6

f2 = * f1; 6.0 double * float deshalb: double * (double)float = double double - double = double also: = 5.7 double * double = double also: 0.05 * 6.0 = 0.3 float Warnung: double --->float Ergebnis: f2 = 5.7 int float implizit: (double)6 implizit: (double)6 double

f2 = 0.05*f1; 6.0 double * float deshalb: double * (double)float = double, also: 0.05 * 6.0 = 0.3 float Warnung: double --->float Ergebnis: f2 = 0.3 double implizit: (double)6 float

d2 = 6-(1.0/20.0)*f1; 6.0 double / double = double, also: 1.0 / 20.0 = 0.05 double - double = double also: = 5.7 double * double = double also: 0.05 * 6.0 = 0.3 double okay: Ergebnis: d2 = 5.7 int float implizit: (double)6 double implizit: (double)6

d2 = * f1; 6.0 double * float deshalb: double * (double)float = double double - double = double also: = 5.7 double * double = double also: 0.05 * 6.0 = 0.3 double okay: Ergebnis: d2 = 5.7 int float implizit: (double)6 implizit: (double)6 double

d2 = 0.05 * f1; 6.0 double * float deshalb: double * (double)float = double, also: 0.05 * 6.0 = 0.3 double okay: Ergebnis: d2 = 0.3 double implizit: (double)6 float

d2 = 3 / 5; int / int = int, also: 3 / 5 = 0 double okay: Ergebnis: d2 = 0.0 int

d2 = 3.0 / 5.0; double / double = double, also: 3.0 / 5.0 = 0.6 double okay: Ergebnis: d2 = 0.6 double

d2 = i1 * 2.718; double okay: Ergebnis: d2 = int double 4 int * double deshalb: (double) int * double = double, also: 4.0 * =

Zusammenfassung

int main(){ float f1, f2; double d1, d2; int i1, i2; f1 = 2.3; i1 = 4; i2 = (float)f1; d1 = 3.14; f1 = 6-1/20*f1; f2 = 6-f1/20; // weiter... //Warnung: double ---> float //Warnung: float ---> int // Ergebnis: f1 = 6 // Ergebnis: f2 = 5,7

f2 = 6-((float)1/(float)20)*f1; f2 = 6-(1/20)*f1; f2 = 6-(1.0/20.0)*f1; f2 = *f1; f2 = 0.05*f1; d2 = 6-(1.0/20.0)*f1; d2 = *f1; d2 = 0.05*f1; d2 = 3/5; d2 = 3.0/5.0; d2 = i1 * 2.718; // Warnung: double ---> float // Ergebnis: d2=0.6 // Ergebnis: d2 = 0 //Warnung: double ---> float // Ergebnis: f2 = 6 // Ergebnis: d2 =5,7 // Ergebnis: d2 =0,3 // Ergebnis: d2 =10,872