4. Rechnerübung

Werbung
4. Rechnerübung
Informatik 1 – Programmieren in C
Datentypen in C
In C existieren zwei Grunddatentypen:
• Ganzzahlige Datentypen
• Gleitkomma-Datentypen
=> Alle anderen Datentypen bauen auf diesen auf.
Beispiel:
Zeichenketten sind nur ein Feld des Datentyps “unsigned char“
(=8bit ohne VZ). Die Elemente sind dann die ASCII bzw. ANSICodes der jeweiligen Zeichen (z.B. 65 für „A“)
Ganzzahlige Datentypen
Die ganzzahligen Datentypen unterscheiden sich lediglich in ihrer Länge
und im Vorhandensein eines Vorzeichenbits.
Datentyp
int
unsigned int (= unsigned)
long
unsigned long
short
unsigned short
char
unsigned char
Länge
32bit(*)
32bit(*)
32bit
32bit
16bit
16bit
8bit
8bit
Vorzeichen
ja
nein
ja
nein
ja
nein
ja
nein
Format-String
%i
%u
%i, %li
%u, %lu
%i
%u
%c
%c
(*) Die Länge des Datentyps “int“ ist plattformabhängig und entspricht immer der
Wortbreite des Prozessors. Auf heutigen PCs beträgt sie 32bit.
Gleitkomma-Datentypen
Die Gleitkomma-Datentypen unterscheiden sich nur durch ihre Länge
und damit in ihrer Genauigkeit.
Datentyp
Länge
Vorzeichen
Format-String
float
double (= long float)
long double
32bit
64bit
64/80bit(*)
ja
ja
ja
%f
%lf, %e, %g
%lf(*)
Die Datentypen “float“ und “double“ sind auch als „single-precision“ bzw.
“double-precision“ bekannt. Man kann sich ungefähr merken, dass “float“
6-7 signifikante Dezimalstellen besitzt, bei “double“ sind es 14-15.
(*) compiler-abhängig, mit MS VC++ mit “double“ identisch
Die wichtigsten Datentypen
Symbol
Zahlen
Menge
printfAnweisung
scanfAnweisung
natürliche Zahlen
(engl. unsigned)
0,1,2,3,…
printf(“%u“,u)
scanf(“%u“,&u);
ganze Zahlen
(engl. integer)
-1,-2,0,1,2,…
printf(“%i“,i)
scanf(“%i“,&i);
reelle Zahlen
(engl. float)
rationale und
irrationale Zahlen
printf(“%f“,f)
scanf(“%f“,&f);
=> Von allen möglichen Datentypen werden im wesentlichen nur int, float,
unsigned und char benutzt.
float vs double
Für Variablen vom Typ float werden im Speicher 4 Byte
reserviert und sie können Werte von ~ 1.2*10-38 bis 3.4*1038
annehmen.
Ein weitere Datentyp in C ist double (Formatstring:
„%lf“(„long float“)). Für diesen Typ werden 8 Byte im
Speicher reserviert und es sind Zahlen zwischen
~ 2.22*10-308 und 1.79*10308 erlaubt.
-> Werte vom Typ double haben eine doppelte Genauigkeit!
float vs double
#include <stdio.h>
#include <stdio.h>
int main () {
int main () {
float a = 0.12345678901234567890;
float b = 10;
double a = 0.12345678901234567890;
double b = 10;
printf("%f+%f=%.17f\n", a,b,a+b);
printf("%lf+%lf=%.17lf\n", a,b,a+b);
return 0;
return 0;
}
}
Ergebnis:
0.12345678901234567890+10=
10.12345679104328200
Ergebnis:
0.12345678901234567890+10=
10.12345678901234600
„%.17f“ -> Die Angabe .17 legt fest, dass die Zahl mit 17 Nachkommastellen ausgegeben wird!!!
Aufgabe 1
Erstelle ein C-Programm, welches zunächst eine nicht
negative Zahl einliest (und überprüft, ob es sich
tatsächlich um eine solche handelt) und anschließend
die Wurzel dieser Zahl berechnet und das Ergebnis
mit 9 Stellen hinter dem Komma am Bildschrim
ausgibt!
Hinweis:
in der Headerdatei „math.h“ ist die Wurzelfunktion durch double sqrt(double) definiert
Lösung
#include <stdio.h>
#include<math.h>
main () {
double zahl;
printf("Bitte eine Zahl >= 0 eingeben:\n");
scanf("%lf",&zahl);
if(zahl>=0){
printf("Die Wurzel von %lf lautet %.9lf\n", zahl, sqrt (zahl));
}else{
printf("Die Zahl ist kleiner als 0!\n");
}
return 0;
}
Typ-Umwandlungen
Da oft mit unterschiedlichen Datentypen gearbeitet wird ist es
oft notwendig verschiedene Datentypen ineinander umzuwandeln.
In C/C++ stehen dazu zwei Mechanismen zur Verfügung:
- implizite Typumwandlung
- explizite Typumwandlung (Type-Cast)
Implizite Typ-Umwandlung
Die implizite Typ-Umwandlung findet immer dann statt, wenn ein
binärer Operator zwei Operanden unterschiedlichen Datentyps erhält.
Beispiele:
int i = 7;
long l = i;
float f = i;
/*=> implizite Umwandlung von int nach long*/
/*=> implizite Umwandlung von int nach float*/
Implizite Typ-Umwandlung
Achtung:
Die implizite Typ-Umwandlung ist nur dann möglich, wenn der Zieltyp
die Daten des Quelltyps ohne Informationsverlust aufnehmen kann.
Folgende Umwandlung sind beispielsweise nicht erlaubt:
float f = 2.71;
long int li = f;
int i = 1000000;
short s = i;
int i2 = -7;
unsigned u = i;
/*Fehler: int kann nur ganze Zahlen aufnehmen*/
/*Fehler: short kann nur Zahlen von -32768..32767*/
/*aufnehmen (16bit)*/
/*Fehler: unsigned kann kein Vorzeichen speichern*/
Implizite Typ-Umwandlung
Hinweis:
Ist eine implizite Typ-Umwandlung nicht erlaubt, so endet dies in der
Regel in einer Warnung oder Fehlermeldung beim kompilieren.
An dieser Stelle sollte man einen anderen Zieldatentyp, eine geeignete
Funktion zur Umwandlung oder einen Type-Cast verwenden.
Explizite Typ-Umwandlung
Die explizite Typumwandlung ermöglicht eine gewollte Umwandlung
eines Datentyps in einen anderen. Dazu existiert der so genannte
“cast“-Operator:
Syntax:
(<Typ>) <Ausdurck>
Explizite Typ-Umwandlung
Achtung:
Auch die explizite Typumwandlung kann verlustbehaftet sein. Da sie
jedoch „explizit“, also gewollt, ist, wird keine Warnung ausgegeben.
Beispiel:
float f = 2.71;
int i = (int)f;
/*Umwandlung von float nach int. Die Nachkomma-*/
/*stellen werden „abgeschnitten“ => i = 2 */
Anwendung des Type-Casts
#include <stdio.h>
main () {
int zahl1 = 5, zahl2 = 3;
printf("5 : 3 =\n");
printf("ohne casten: %i\n", zahl1/zahl2);
printf("mit casten: %f\n", (float)zahl1 /zahl2);
return 0;
}
Format-Strings, die Zweite…
Neben der bereits kennen gelernten, unformatierten Benutzung der
Format-Strings können neben dem auszugebenden Datentyp noch
weitere Felder angegeben werden:
- Gesamtbreite der Ausgabe
- Genauigkeit (bei Gleitkommazahlen)
- Wissenschaftliche Notation (bei Gleitkommazahlen)
Format-Strings, die Zweite…
Die allgemeine Syntax eines Format-Strings lautet:
%<len>.<prec><type>
=> Das Feld „len“ bezeichnet die Gesamtlänge der Ausgabe in Zeichen
=> Das Feld „prec“ gibt die Anzahl der auszugebenen Nachkommastellen an
=> Das Feld „type“ entspricht dem bekannten Zeichen für den Datentyp
Beispiele:
printf(“%4i“, 2);
printf(“%7.3f“, 3.141592);
=>
=>
2
3.141
Format-Strings, die Zweite…
Wichtig:
„Passt“ die Ausgabe nicht in die vorgegebene Breite, so wird diese
ignoriert. Man sollte daher auf ausreichende Dimensionierung der
Ausgabebreite achten
Beispiele:
printf(“%3i“, 2048);
printf(“%5.3f“, 13.75);
=> 2048
=> 13.750
Aufgabe 2
Erstelle ein C-Programm, welches zunächst einen
Bruch (Zähler und Nenner) einliest (und überprüft,
ob der Nenner ungleich 0 ist) und diesen dann in
eine Dezimalzahl umwandelt und diese am Bildschrim
ausgibt. Eine Genauigkeit auf 7 Stellen hinter dem
Komma ist diesmal ausreichend!
Lösung
#include <stdio.h>
main () {
int zaehler, nenner;
printf("Bitte Zaehler eingeben:\n");
scanf("%i",&zaehler);
printf("Bitte Nenner eingeben:\n");
scanf("%i",&nenner);
if(nenner!=0){
printf("Der Bruch %i/%i laesst sich durch Casten in eine \
Dezimalzahl umwandeln\n", zaehler, nenner);
printf("%.7f\n", (float) zaehler/nenner);
}else{
printf("Der Nenner darf nicht 0 sein!\n");
}
return 0;
}
Herunterladen