05.03.2013 Aufrufe

Einführung /Grundbegriffe

Einführung /Grundbegriffe

Einführung /Grundbegriffe

MEHR ANZEIGEN
WENIGER ANZEIGEN

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 integer­Variablen 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) Gleitkomma­Typen<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 IEEE­Standard ü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. ASCII­Code 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 i­1 . 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 int­Wert, 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 int­Wert, 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 cast­Operator<br />

z.B. float y = 6.78;<br />

i = 3 + (int) y;

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!