Einführung /Grundbegriffe
Einführung /Grundbegriffe
Einführung /Grundbegriffe
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
3. Datentypen, Ausdrücke und Operatoren<br />
Programm muß i.a. Daten zwischenspeichern<br />
Speicherplatz muß bereitgestellt werden, der ansprechbar, reserviert ist<br />
Ablegen & Wiederfinden<br />
in höheren Programmiersprachen Arbeit mit bestimmten Speicherplätzen über<br />
Vergabe von Namen = Variable<br />
3.1 Variable<br />
im Programm definierter Name für einen (beim Programmlauf) zu<br />
reservierenden Speicherplatz im Arbeitsspeicher für Werte eines bestimmten Typs<br />
Arbeit mit Variablen (Zuweisungen von Werten, Berechnungen) bedeutet<br />
Zugriff auf den zugehörigen Speicherplatz<br />
Deklaration in C:<br />
Beispiel: int i; Deklaration der integerVariablen mit Namen i<br />
d.h. Bereitstellen von i.a. 4 Byte Speicherplatz (=32 bit)<br />
im Arbeitsspeicher<br />
i=3; Speicherung des Wertes 3=2^0+2^1(≙ 11 binär)<br />
auf dem reservierten Speicherplatz<br />
➘<br />
000... ... ... ...0011<br />
i Arbeitspeicher<br />
in vielen höheren Programmiersprachen ist zur Reservierung eines Speicherplatzes, d.h.<br />
der <strong>Einführung</strong> einer neuen Variablen ein Variablentyp mit anzugeben<br />
der Variablentyp sagt dem Compiler wieviel Speicherplatz benötigt wird und wie er<br />
zu strukturieren ist (zu interpretieren)<br />
Variablentyp Variablenname;<br />
1
3.2 Elementare Datentypen<br />
Es gibt drei qualitativ unterschiedliche Basistypen von Daten:<br />
ganze Zahlen, reelle Zahlen und alphanumerische Zeichen<br />
Die Basistypen werden i.a. in eine Reihe von Untertypen ( die sogenannten elementaren<br />
Typen) aufgesplittet.<br />
Die Bezeichnungen der Typen ist sprachabhängig, z.B.<br />
ganze Zahlen : int , long , short (in C)<br />
integer, longint, word (in PASCAL)<br />
INTEGER (in FORTRAN)<br />
reelle Zahlen : float, double (in C)<br />
real, extended (in PASCAL)<br />
REAL, DOUBLE (in FORTRAN)<br />
Zeichen : char (in C und in PASCAL)<br />
(1) Integertypen<br />
in C: int<br />
Speicherbedarf:<br />
CHARACTER (in FORTRAN)<br />
short int kurz: short<br />
long int kurz: long<br />
Speicherplatz für int = Wortlänge des Rechners<br />
heutzutage auf dem PC meist 4 Byte = 32 Bit<br />
⇨ max. bzw. min. darstellbare Zahl:<br />
32 Stellen = 32 Möglichkeiten für 0 oder 1 ⇨ 2^32 verschiedene Zahlen darstellbar<br />
Sinnvolle Möglichkeiten:<br />
(A) das erste Bit gleich 0 bedeutet positive Zahl<br />
1 bedeutet negative Zahl<br />
alle anderen Bits repräsentieren den Betrag der ganzen Zahl<br />
Diese Darstellungsweise ist auf den ersten Blick sehr sympathisch, hat aber praktische<br />
Nachteile, besonders bei der Addition negativeR Zahlen.
(B) Deshalb:<br />
Kodierung in sog. Zweierkomplementdarstellung<br />
Für negative ganze Zahlen bedeutet das:<br />
Die Bitfolge der zugehörigen betragsgleichen positiven Zahl wird logisch<br />
negiert, d.h. aus jeder 0 wird eine 1 und aus jeder 1 wird eine 0.<br />
Anschließend wird zu der so erhaltenen Zahl eine 1 addiert.<br />
Beispiel betrachten hier einen max. Umfang von 4 Bit: < C Typ short<br />
⇨bei 32 Bit ist der Bereich: 2 31 bis 2 31 1<br />
2 31 negative Zahlen, 0 und 2 31 –1 positive Zahlen<br />
Maximale Zahl = 2 31 –1 ~ 2 Mio.<br />
Unterschiede zwischen long int, int, short int sind compilerabhängig<br />
(2) GleitkommaTypen<br />
Darstellung reeller Zahlen<br />
Typen in C: float ... einfache Genauigkeit<br />
double ... doppelte Genauigkeit<br />
Was bedeutet einfach, was bedeutet doppelt genau?<br />
Und was ist eigentlich eine Gleitkommazahl?<br />
anderer Name: Maschinenzahl<br />
Festkommadarstellung z.B. : 321.45<br />
Gleitkommadarstellung : 3.2145*10 2 bzw. 0.32145*10 3<br />
Prinzipielles Problem:<br />
Da nur beschränkte Anzahl an Bytes zur Darstellung zur Verfügung steht, ist in der<br />
Regel eine genaue Darstellung nicht möglich.<br />
Irrationale Zahlen wie 2 oder die Eulersche Zahl e intern nie exakt darstellbar.<br />
aber auch viele andere nicht.
interne Darstellung im Rechner:<br />
x = (1) v 0.m1 m2 mL 2 p<br />
<br />
Vorzeichen<br />
mi ... sind 0 oder 1, m1 = 1<br />
p ... ist der Exponent (selbst wieder intern binär gespeichert),<br />
m p M (d.h. Beschränkt)<br />
v ... ist 0 oder 1<br />
d.h. das Komma wird immer an der selben Stelle plaziert.<br />
Speicherplatz:<br />
Für die Codierung im Computer ist IEEEStandard üblich<br />
● für Gleitkommazahl in einfacher Genauigkeit: 4Byte = 32 Bit<br />
v e7 ... e0 m2 ... ... m24<br />
Vorzeichenbit Exponent Mantisse<br />
m1 muß nicht gespeichert werden, da stets = 1<br />
● für Gleitkommazahl in doppelter Genauigkeit: 8Byte = 64 Bit<br />
v e10 ... ... e0 m2 ... ... ... ... ... m53<br />
Vorzeichenbit Exponent Mantisse<br />
Typ Max. /pos. Min. Rel. Rechengenauigkeit eps<br />
float<br />
double<br />
Mantisse Basis + Exponent<br />
~ 10 38 / ~ 10 38<br />
~ 10 308 / ~ 10 308<br />
z.B. MAXFLOAT ~ 2 M , M = 2 7 = 128 2 M = 2 128 ~ 10 38<br />
⇨Mantisse bestimmt die Rechengenauigkeit<br />
⇨Exponent bestimmt den Wertebereich<br />
~ 0.610 7<br />
~ 1.110 16
Grenzen der Maschinenzahlen:<br />
Unterlauf (underflow): |x| < eps Rundung x=0<br />
Überlauf (overflow) |x| > MAX_Typ compilerabhängige Reaktion<br />
Abbruch + Fehlermeldung<br />
falsches Ergebnis<br />
x=INF oder x=NaN<br />
Bei der Darstellung selbst einfachster Dezimalzahlen treten schon Rundungsfehler auf.<br />
Zusätzlich ergeben sich beim Rechnen weitere Rundungsfehler:<br />
Bei Addition zweier (positiver) Gleitkommazahlen werden folgende Einzelschritte<br />
ausgeführt:<br />
1. Erkennen von Mantisse und Exponent beider Zahlen<br />
2. Vergleichen der Exponenten<br />
3. Angleichen der Exponenten<br />
4. Anpassen der Mantisse der Zahl, deren Exponent bei der<br />
Exponentenanpassung verändert wurde<br />
5. Addition der Mantissen, ggf. Änderung des gemeinsamen Exponenten<br />
(bei Überlauf der Mantisse)<br />
6. Normalisierung des Ergebnisses (gleitendes Komma)<br />
Beispiel: Die Eulersche Zahl e = 2.71828182846 ... ist Grenzwert der Zahlenfolge<br />
a1 , a2 , a3 , .... an , ... mit an = (1 + 1/ n ) n<br />
Es gilt an < an+1 (Monotonie !) und an < e für alle natürlichen Zahlen n.<br />
Folglich erhält man (mathematisch betrachtet) mit wachsendem n einen<br />
immer besseren Näherungswert für e .
(3) Textzeichentyp<br />
char<br />
reserviert (i.a.) 1 Byte = 8 Bit Speicherplatz für genau ein Zeichen<br />
(Erinnerung: z.B. ASCIICode stellt Zeichen auf 8 Bit dar)<br />
ein erster abgeleiteter Variablentyp:<br />
Zeichenkette Aufeinanderfolge von Zeichen (z.B. Wörter)<br />
Deklaration:<br />
dargestellt und gespeichert als<br />
Feld des Typs char<br />
anderer Name: string<br />
dabei ist n die maximale Anzahl Zeichen, d.h. die Feldlänge<br />
durch die Deklaration wird ein Block von n Byte Speicherplatz im<br />
Arbeitspeicher reserviert.<br />
Achtung! Der Name stringname enthält dabei die Speicheradresse, an der<br />
die Zeichenkette im Arbeitspeicher beginnt (stringname ist ein sog. Zeiger)<br />
Zugriff auf die Komponenten, also die einzelnen Zeichen durch<br />
stringname[i]<br />
wobei der Index i das i1 . Zeichen der Zeichenkette bezeichnet, da in C die<br />
Numerierung bei 0 beginnt!<br />
z.B. char str[5]="INFO";<br />
str<br />
➘<br />
I N F O \0<br />
1012 1013 1014 1015 1016 1017 ...<br />
str enthält die Adresse 1015<br />
str[0] = 'I', str[1]='N' , ...<br />
char stringname[n];<br />
<br />
str[0] str[1] str[2] str[3] Endezeichen<br />
gespeichert wird natürlich jedes Zeichen in seiner Binärdarstellung!
es muß stets ein Byte Platz für das Endezeichen eingerechnet werden,<br />
sonst kann es zu Problemen führen<br />
Erreichen des Endezeichens kann z.B. in einer Schleifenanweisung durch<br />
i=0;<br />
while (str[i]!=0)<br />
{<br />
}<br />
tue etwas<br />
i=i+1;<br />
abgefragt werden.<br />
Achtung! Zuweisung eines ganzen Wortes nur in der Deklaration erlaubt<br />
danach nur noch Zugriff auf Einzelkomponenten möglich<br />
(4) leerer Typ void<br />
sinnvoll z.B. Für Funktionen ohne Ergebniswert (sog. Prozeduren oder Subroutinen)<br />
aus diesen Grundtypen lassen sich dann beliebig komplexere Typen selbstdefinieren<br />
(dazu mehr in der 4. Vorlesung)<br />
3.3 Ausdrücke und Operatoren<br />
Ein Ausdruck ist eine Aneinanderreihung von Zahlen, Strings und Operatoren, die sich zu<br />
einem Wert auflösen lassen, sprich: eine mehr oder weniger komplexe Rechenvorschrift<br />
⇨Ausdrücke können über Operatoren miteinander verknüpft werden<br />
⇨Ausdrücke können Variablen zugewiesen werden
Operatoren:<br />
z.B.:<br />
es gibt grundsätzlich unäre, binäre und terniäre Operatoren<br />
(1) unäre Operatoren: (in C) Inkrementoperator ++ausdruck<br />
ausdruck++<br />
Dekrementoperator ausdruck<br />
ausdruck<br />
(2) binäre Operatoren: arithmetische Grundoperationen + , , * , /<br />
(3) terniäre Operatoren: eher selten<br />
Zuweisung: (binärer Operator)<br />
(in allen Programmiersprachen)<br />
in C z.B. Ausdruck1 ? Ausdruck2 : Ausdruck3<br />
ist Ausdruck 1 wahr so berechne Audruck2 sonst berechne Ausdruck3<br />
eine Zuweisung ist selbst wieder ein Ausdruck<br />
die Zuweisung hat den Wert, der der Variablen zugewiesen wird<br />
Vergleiche und logische Operatoren<br />
Vergleiche<br />
Symbolik fürVergleiche in Programmiersprachen ähnlich der aus<br />
der Mathematik bekannten:<br />
< , ><br />
≤ ... =<br />
= ... == doppeltes Gleichheitszeichen, da '=' der Zuweisung entspricht<br />
allgemein ist die Syntax:<br />
liefert wieder einen Ausdruck<br />
Variablenname = Ausdruck<br />
Ausdruck Vergleichsoperator Ausdruck<br />
dieser Ausdruck hat einen intWert, und zwar 0 , falls der Vergleich nicht zutrifft<br />
1, falls der Vergleich zutrifft
Logische Operatoren<br />
Anweisungen<br />
Aussagenlogisches UND ODER VERNEINUNG<br />
Symbolik: && || ! (in C)<br />
liefert wieder einen Ausdruck<br />
.and. .or. .not. (in FORTRAN)<br />
& | ~ (in MATLAB)<br />
dieser Ausdruck hat einen intWert, und zwar 0 , falls der Gesamtausdruck wahr<br />
1, falls der Gesamtausdruck falsch ist<br />
sind in der jeweiligen Programmiersprache erlaubte Ausdrücke, die zeilenweise in den<br />
Programmen geschrieben werden (oder durch entsprechende Zeichen voneinander<br />
abgegrenzt, z.B. ein Komma in FORTRAN oder in MATLAB)<br />
möglicherweise prinzipiell durch ein Zeichen abgeschlossen werden<br />
in C:<br />
Priorität von Operatoren<br />
Ausdruck logischer Operator Ausdruck<br />
Ausdruck ;<br />
(von höchster zu niedrigster Priorität)<br />
Symbol Name/Bedeutung Assoziativität<br />
-----------------------------------------------------------------<br />
++ Erhöhung nach Auswertung von links nach rechts<br />
-- Erniedrigung nach Auswertung<br />
( ) Funktionsaufruf<br />
[ ] Arrayelement<br />
-> Zeiger auf Strukturfeld<br />
. Felder einer Struktur oder Union<br />
-----------------------------------------------------------------<br />
++ Erhöhung vor Auswertung von rechts nach links<br />
-- Erniedrigung vor Auswertung<br />
! logisches NOT<br />
- unäres Minus<br />
+ unäres Plus<br />
& Adresse von<br />
* Dereferenzierung<br />
sizeof Größe in Bytes<br />
(type) Typumwandlung (cast)<br />
-----------------------------------------------------------------<br />
* Multiplikation von links nach rechts<br />
/ Division
% Divisionsrest (modulo)<br />
-----------------------------------------------------------------<br />
+ Addition von links nach rechts<br />
- Subtraktion<br />
-----------------------------------------------------------------<br />
< kleiner als von links nach rechts<br />
größer als<br />
>= größer oder gleich<br />
-----------------------------------------------------------------<br />
== gleich von links nach rechts<br />
!= ungleich<br />
-----------------------------------------------------------------<br />
&& logisches AND von links nach rechts<br />
-----------------------------------------------------------------<br />
|| logisches OR von links nach rechts<br />
-----------------------------------------------------------------<br />
? : Bedingung von rechts nach links<br />
-----------------------------------------------------------------<br />
= Zuweisung von rechts nach links<br />
*= zusammengesetzte Zuweisung<br />
/=<br />
%=<br />
+=<br />
-=<br />
=<br />
&=<br />
^=<br />
|=<br />
-----------------------------------------------------------------<br />
, Komma-Operator von links nach rechts<br />
-----------------------------------------------------------------<br />
Typumwandlung<br />
nötig, falls in einer Operation Operanden verschiedenen Typs beteiligt sind<br />
● implizite Typumwandlung: durch den Compiler<br />
z.B. int i=1, k=3;<br />
float x;<br />
x = i*k; int*int liefert int, in der Zuweisung Umwandlung intfloat<br />
● explizite Typumwandlung: durch einen castOperator<br />
z.B. float y = 6.78;<br />
i = 3 + (int) y;