Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

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

Ähnliche Präsentationen


Präsentation zum Thema: "Datentyp- umwandlung. Literale sind: Bezeichner mit einem festen Wert wie z.B:"—  Präsentation transkript:

1 Datentyp- umwandlung

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

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

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

5 Welchen Datentyp hat ein Literal ?

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

7 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++) ?

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

9 Kann also die Ganzzahl 4 000 000 000 mit dem Datentyp int abgespeichert werden ?

10 Nein, denn int umfasst nur den Zahlenbereich von: -2147483648...2147483647

11 Also wird Ganzzahlen zwischen: -2147483648...2147483647 der Datentyp int zugeordnet und Ganzzahlen zwischen 2147483648...4294967295 der Datentyp unsigned int zugeordnet

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

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

14 Einer Fließkommazahl wird der folgende Datentyp zugeordnet: double

15 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 ?

16 Merke:

17 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?

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

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

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

21 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

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

23 Beispiel:

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

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

26 Dazu gibt es zwei Möglichkeiten:

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

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

29 Tabelle Typumwandlung:

30 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:

31 ... 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.

32 Beispiel:

33 ... 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

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

35 Beispiel:

36 ... 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

37 Beispiel:

38 ... 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

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

40 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.

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

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

43 Konkretes Beispiel für einen Informationsverlust

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

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

46 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.

47 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.

48 Noch ein Beispiel:

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

50 Grosses Beispiel:

51 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...

52 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 = 6-0.05*f1; f2 = 0.05*f1; d2 = 6-(1.0/20.0)*f1; d2 = 6-0.05*f1; d2 = 0.05*f1; d2 = 3/5; d2 = 3.0/5.0; }

53 d2 = i1 * 2.718; }

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

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

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

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

58 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

59 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

60 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

61 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

62 f2 = 6-(1/20)*f1; 6.0 int / int = int, also: 1 / 20 = 0 float - float = float also: 6.0 - 0.0 = 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

63 f2 = 6-(1.0/20.0)*f1; 6.0 double / double = double, also: 1.0 / 20.0 = 0.05 double - double = double also: 6.0 - 0.3 = 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

64 f2 = 6 - 0.05 * f1; 6.0 double * float deshalb: double * (double)float = double double - double = double also: 6.0 - 0.3 = 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

65 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

66 d2 = 6-(1.0/20.0)*f1; 6.0 double / double = double, also: 1.0 / 20.0 = 0.05 double - double = double also: 6.0 - 0.3 = 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

67 d2 = 6 - 0.05 * f1; 6.0 double * float deshalb: double * (double)float = double double - double = double also: 6.0 - 0.3 = 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

68 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

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

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

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

72 Zusammenfassung

73 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

74 f2 = 6-((float)1/(float)20)*f1; f2 = 6-(1/20)*f1; f2 = 6-(1.0/20.0)*f1; f2 = 6-0.05*f1; f2 = 0.05*f1; d2 = 6-(1.0/20.0)*f1; d2 = 6-0.05*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


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

Ähnliche Präsentationen


Google-Anzeigen