13.10.2013 Aufrufe

1. Was ist eine Header – Datei? Was darf in einer Header-Datei ...

1. Was ist eine Header – Datei? Was darf in einer Header-Datei ...

1. Was ist eine Header – Datei? Was darf in einer Header-Datei ...

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.

Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

<strong>1.</strong> <strong>Was</strong> <strong>ist</strong> <strong>e<strong>in</strong>e</strong> <strong>Header</strong> <strong>–</strong> <strong>Datei</strong>? <strong>Was</strong> <strong>darf</strong> <strong>in</strong> <strong>e<strong>in</strong>e</strong>r <strong>Header</strong>-<strong>Datei</strong> nicht<br />

dr<strong>in</strong>nen stehen?<br />

<strong>Header</strong> <strong>–</strong> <strong>Datei</strong>en be<strong>in</strong>halten Bekanntmachungen (Deklarationen) und Informationen über<br />

den strukturellen Aufbau von neu def<strong>in</strong>ierten Datentypen. <strong>Header</strong> <strong>–</strong> <strong>Datei</strong>en werden zur<br />

Übersetzung der Quelltextdateien benötigt.<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Des Weiteren enthalten <strong>Header</strong>dateien Def<strong>in</strong>itionen von Präprozessorkonstanten, Typ- und<br />

Strukturdef<strong>in</strong>itionen und Funktionsdeklarationen. Sie haben das Suffix .h und heißen so, weil<br />

sie zur Übersetzungszeit im Kopf des Programms dazugeladen werden.<br />

<strong>Header</strong>dateien können entweder selbst geschrieben werden oder sie werden aus den<br />

verschiedenen mit dem Compiler mitgelieferten Bibliotheken bezogen.<br />

2. <strong>Was</strong> s<strong>in</strong>d Qualifizierer?<br />

Werden dem Datentyp <strong>in</strong>t Qualifizierer vorangestellt, so wird der Wertebereich verändert.<br />

Datentyp Bits Wertebereich<br />

short <strong>in</strong>t 16 0…65535<br />

long <strong>in</strong>t 32 0…4294967295<br />

signed short <strong>in</strong>t 16 -32768…+32767<br />

unsigned short<br />

<strong>in</strong>t<br />

Signed long <strong>in</strong>t 32<br />

16 0…+65535<br />

1<br />

-<br />

2147483648…+2147483647<br />

unsigned long<br />

<strong>in</strong>t<br />

32 0…+4294967295<br />

Diese Angaben gelten bei 32 Bit Architektur!<br />

3. <strong>Was</strong> s<strong>in</strong>d Datentypen?<br />

Datentypen s<strong>in</strong>d Def<strong>in</strong>itionsmengen von Daten <strong>in</strong>klusive aller Operatoren und Funktionen,<br />

welche auf dieser Menge def<strong>in</strong>iert s<strong>in</strong>d.<br />

4. <strong>Was</strong> <strong>ist</strong> der ASCII <strong>–</strong> Code?<br />

Der ASCII <strong>–</strong> Code legt die Codierung der im englischen Sprachraum gebräuchlichen<br />

Buchstaben fest. Hierbei handelt es sich um <strong>e<strong>in</strong>e</strong>n 7-bit <strong>–</strong> Code. Der Wertebereich liegt<br />

zwischen 0 und 127. Er enthält im Bereich 1 bis 32 Steuercodes. Die nächsten 96 Codes<br />

be<strong>in</strong>halten Buchstaben des englischen Sprachraums sowie diverse Sonderzeichen. Dieser<br />

Bereich <strong>ist</strong> genormt. Die Umlaute des deutschen Sprachraumes sowie zusätzliche<br />

Sonderzeichen s<strong>in</strong>d im erweiterten ASCII-Code im Bereich von 128 bis 255 enthalten. Dieser<br />

Bereich <strong>ist</strong> nicht genormt.


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Zeichen ASCII-Code - Bereich<br />

0…9 48…57<br />

A…Z 65…90<br />

a…z 97…122<br />

5. Wie viele Gleitpunktdatentypen gibt es <strong>in</strong> C und wie unterscheiden<br />

sich diese?<br />

Das e<strong>in</strong>fach genaue Zahlenformat mit 32 Bit Länge <strong>ist</strong> als Datentyp float <strong>in</strong> C implementiert.<br />

Das doppelt genaue Zahlen Format von 64 Bit Länge <strong>ist</strong> durch den Datentyp double<br />

implementiert.<br />

Datentyp Bits Genauigkeit<br />

float 32 7 Stellen<br />

double 64 15Stellen<br />

long<br />

double ≥64 18 Stellen<br />

2<br />

kle<strong>in</strong>ste<br />

darstellbare<br />

Zahl<br />

Die Gleitpunktdatentypen unterscheiden sich durch die Größe des zur Verfügung stehenden<br />

Speicherplatzes.<br />

5.<strong>1.</strong> float:<br />

Bei diesem Datentyp stehen <strong>in</strong>sgesamt 32 Bit zur Datenspeicherung zur Verfügung. Bit<br />

Nummer 31 be<strong>in</strong>haltet das Vorzeichen (1… negativ, 0… positiv). Die Bits 23-30 be<strong>in</strong>halten<br />

den Exponenten zur Basis 2. Die restlichen 23 Bit be<strong>in</strong>halten die eigentliche Zahl<br />

(Mantisse) mit <strong>e<strong>in</strong>e</strong>r Genauigkeit von 7 signifikanten Stellen.<br />

5.2. double:<br />

Beim Datentyp double stehen zur Datenspeicherung 64 Bit zur Verfügung. Die Bits 0 bis<br />

51 s<strong>in</strong>d die Mantisse, die Bits 52 <strong>–</strong> 62 der Exponent und Bit 63 das Vorzeichen. Aufgrund<br />

der 52 Bit langen Mantisse erreicht dieser Datentyp die doppelte Genauigkeit des Typs<br />

float. Die Genauigkeit beträgt hier 15-16 Stellen. Die Genauigkeit kann mittels<br />

berechnet werden. Länge der Mantisse <strong>in</strong> Bit. Beim Typ double 52 und bei float<br />

23 Bit.<br />

Es gibt des Weiteren auch noch den Datentyp long double, welcher je nach<br />

Rechnerarchitektur >= 64 Bit <strong>ist</strong>.<br />

Es gibt unterschiedliche Datentypen, da nicht jede zu speichernde Zahl gleich große<br />

Genauigkeiten aufweisen muss. Höhere Genauigkeit erfordert höheren Be<strong>darf</strong> an<br />

Speicherplatz.


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

6. Wie kann scanf() ohne den „&“ <strong>–</strong> Operator verwendet werden?<br />

Der „&“ <strong>–</strong> Operator liefert die Adresse <strong>e<strong>in</strong>e</strong>s Objektes. E<strong>in</strong> Zeiger <strong>ist</strong> bereits e<strong>in</strong> Objekt,<br />

welches die Adresse <strong>e<strong>in</strong>e</strong>s anderen Objektes (z.B.: <strong>e<strong>in</strong>e</strong>r Variable) enthält. Daher kann der<br />

Funktion scanf() direkt e<strong>in</strong> Zeiger als Parameter übergeben werden, da dieser bereits <strong>e<strong>in</strong>e</strong><br />

Adresse enthält.<br />

7. Wie lautet die Deklaration von pr<strong>in</strong>tf() und scanf()?<br />

<strong>in</strong>t=pr<strong>in</strong>tf(char*,…);<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

<strong>in</strong>t=scanf(char*, void*);<br />

char* <strong>ist</strong> <strong>e<strong>in</strong>e</strong> Zeichenkette, ja nach Anzahl der Platzhalter im char* muss man nach dem<br />

Komma die entsprechenden Variablen anführen. Die Anzahl der Parameter <strong>ist</strong> 1+n, n…Anzahl<br />

der Parameter.<br />

8. <strong>Was</strong> s<strong>in</strong>d Zeiger?<br />

E<strong>in</strong> Zeiger <strong>ist</strong> e<strong>in</strong> Objekt (! KEINE VARIABLE!), welches <strong>e<strong>in</strong>e</strong> Adresse enthält. Zeiger können<br />

auf die Adresse von Objekten gesetzt werden. Dazu wird der Adressoperator & verwendet.<br />

ptr = &a Adresse von a.<br />

Mit Hilfe des Dereferenzierungsoperators „*“ kann man dann über den Zeiger auf das Objekt<br />

zugreifen.<br />

wert = *ptr Wert, welcher an der <strong>in</strong> ptr gespeicherten Adresse steht.<br />

Wird e<strong>in</strong> Zeiger auf „0“ (Null) gesetzt, so wird dieser dadurch ungültig gemacht. (ptr = 0;)<br />

Soll <strong>e<strong>in</strong>e</strong> Funktion mehr als <strong>e<strong>in</strong>e</strong>n Rückgabewert haben, so übergibt man der Funktion Zeiger<br />

als Parameter (Call by Reference).<br />

Zeiger auf Funktionen:<br />

Typ (*Funktionsname) (Parameterl<strong>ist</strong>e)<br />

Ist das „*“ außerhalb der Klammer, dann <strong>ist</strong> der Ausdruck <strong>e<strong>in</strong>e</strong> Funktionsdeklaration<br />

(Rückgabewert: Zeiger vom Typ long).<br />

9. Zeiger <strong>–</strong> Feld <strong>–</strong> Dualität:<br />

Der Name <strong>e<strong>in</strong>e</strong>s Feldes steht auch für die Adresse, an der sich das Feld im Speicher bef<strong>in</strong>det.<br />

Der Feldname könnte somit direkt <strong>e<strong>in</strong>e</strong>m Zeiger zugewiesen werden, was allerd<strong>in</strong>gs zu<br />

schlechtem Programmierstil und Unübersichtlichkeit führt.<br />

long feld[10];<br />

long *ptr;<br />

ptr = feld; //gültig, aber unübersichtlich<br />

ptr = &feld[0]; //korrekt<br />

3


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Hier wird der Zeiger auf das erste Feldelement gesetzt.<br />

Von Zeiger-Feld-Dualität kann auch gesprochen werden, wenn e<strong>in</strong> Feld als Parameter an <strong>e<strong>in</strong>e</strong><br />

Funktion übergeben wird. Wie <strong>in</strong> Kapitel 13.5 erwähnt, wird e<strong>in</strong> Feld nicht als Kopie an <strong>e<strong>in</strong>e</strong><br />

Funktion übergeben. Es wird nur die Adresse des Feldes übergeben. Dies kann mit der<br />

sizeof<strong>–</strong> Anweisung überprüft werden.<br />

Zeigerschreibweise Feldschreibweise<br />

Adresse ptr + n &feld[n]<br />

Objekt *(ptr + n) feld[n]<br />

Softwaretechnisch gesehen s<strong>in</strong>d Felder und Zeiger total verschiedene Konstrukte. Felder s<strong>in</strong>d<br />

beim Übergeben an <strong>e<strong>in</strong>e</strong> Funktion e<strong>in</strong> Zeiger auf das Feld (Call by Reference). Der Feldname<br />

kann wie e<strong>in</strong> Zeiger verwendet werden.<br />

10. <strong>Was</strong> s<strong>in</strong>d Zeiger auf Zeiger? Wann werden sie verwendet?<br />

Zeiger können auf jeden beliebigen Datentyp zeigen, daher <strong>ist</strong> es auch möglich Zeiger auf<br />

Zeiger zu def<strong>in</strong>ieren. Zeiger auf Zeiger werden hauptsächlich verwendet um zwei Zeiger zu<br />

tauschen (Swap-Zeiger).<br />

SwapZeiger(long **p1, long **p2)<br />

{<br />

long *h;<br />

h=*p1;<br />

*p1=*p2;<br />

*p2=h;<br />

}<br />

Das Haupte<strong>in</strong>satzgebiet von Zeigern auf Zeiger <strong>ist</strong> die dynamische Erzeugung von<br />

mehrdimensionalen Arrays wie beispielsweise Matrizenberechnungen.<br />

1<strong>1.</strong> Kann <strong>e<strong>in</strong>e</strong> Funktion <strong>e<strong>in</strong>e</strong>r Funktion übergeben werden?<br />

E<strong>in</strong>e Funktion kann mittels <strong>e<strong>in</strong>e</strong>s Zeigers auf <strong>e<strong>in</strong>e</strong> Funktion an <strong>e<strong>in</strong>e</strong> andere Funktion<br />

übergeben werden.<br />

12. Wie def<strong>in</strong>iert und verwendet man Zeiger auf Funktionen?<br />

In C können Zeiger auf Funktionen vere<strong>in</strong>bart werden. Sie werden hauptsächlich bei der<br />

Verwendung von externen Bibliotheken, z.B. bei grafischen Benutzerschnittstellen<br />

e<strong>in</strong>gesetzt.<br />

Um die Adresse <strong>e<strong>in</strong>e</strong>r Funktion zu erhalten, wird wie bei Po<strong>in</strong>tern auch hier der<br />

Adressoperator „&“ verwendet.<br />

4


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

12.<strong>1.</strong> Def<strong>in</strong>ition:<br />

Typ (*Funktionsname) (Parameterdatentyp);<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Mittels <strong>e<strong>in</strong>e</strong>r „normalen“ Zuweisung wird dem Po<strong>in</strong>ter die Adresse der Funktion<br />

zugewiesen.<br />

long *fptr(long, long);<br />

fptr=&function;<br />

12.2. Verwendung:<br />

Zeiger auf Funktionen können ähnlich zu „normalen“ Zeigern gesetzt und kopiert werden.<br />

Bei der Verwendung <strong>ist</strong> auf die Übere<strong>in</strong>stimmung der Datentypen zu achten.<br />

Funktionsaufruf:<br />

long x;<br />

x=fptr(Variablenl<strong>ist</strong>e);<br />

Zeiger auf Funktionen werden bei „call-back“ <strong>–</strong> Funktionen, die beim E<strong>in</strong>treten von<br />

bestimmten Ereignissen vom Betriebssystem aufgerufen werden.<br />

E<strong>in</strong>e weitere Anwendung <strong>ist</strong> bei Menüs. Hierbei werden die s<strong>in</strong>d die e<strong>in</strong>zelnen E<strong>in</strong>träge<br />

des Menüs <strong>in</strong> Strukturen beschrieben, die jeweils <strong>e<strong>in</strong>e</strong>n Zeiger auf die Menüfunktion<br />

speichern. Bei der Auswahl <strong>e<strong>in</strong>e</strong>s Menüpunktes wird dann diese Funktion aufgerufen.<br />

13. Erklärung typedef:<br />

Mittels typedef können neue Typnamen für Variablen, Funktionen und Strukturen selbst<br />

def<strong>in</strong>iert werden.<br />

Dies br<strong>in</strong>gt <strong>e<strong>in</strong>e</strong> Vere<strong>in</strong>fachung, wenn längere Datentypbezeichnungen öfter verwendet<br />

werden.<br />

13.<strong>1.</strong> Abgeleitete Datentypen:<br />

Mit der typedef <strong>–</strong> Vere<strong>in</strong>barung können neue Typnamen erzeugt werden. Diese s<strong>in</strong>d<br />

äquivalent mit der Bezeichnung wofür sie stehen.<br />

typedef char *str<strong>in</strong>g;<br />

Damit wurde e<strong>in</strong> neuer Typname str<strong>in</strong>g def<strong>in</strong>iert. Dieser Typname <strong>ist</strong> identisch zu<br />

handhaben wie alle anderen Datentypen.<br />

char *text1 = “Hallo“;<br />

str<strong>in</strong>g text2 = „Welt“;<br />

Beide Variablendef<strong>in</strong>itionen s<strong>in</strong>d vollkommen identisch.<br />

5


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

13.2. Strukturen:<br />

Typedef kann auch bei Strukturen verwendet werden.<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

typedef struct Punkt_s<br />

{<br />

struct Punkt_s *naechster;<br />

double x, y;<br />

}Punkt_t;<br />

Hier kann jetzt anstatt der Struktur <strong>e<strong>in</strong>e</strong> neu Variable e<strong>in</strong>fach über den Typnamen Punkt_t<br />

erstellt werden.<br />

13.3. Funktionen:<br />

Mit typedef können auch Typnamen für Zeiger auf Funktionen generiert werden.<br />

typedef long Funktion_t(long, long);<br />

Hier wird allgeme<strong>in</strong> <strong>e<strong>in</strong>e</strong> Funktion Funktion_t erzeugt, welche als Parameter zwei long <strong>–</strong><br />

Variable erwartet. E<strong>in</strong>e Funktionsdef<strong>in</strong>ition sieht wie folgt aus:<br />

Funktion_t *function;<br />

14. Unterschied zwischen Def<strong>in</strong>ition und Deklaration:<br />

14.<strong>1.</strong> Deklaration:<br />

14.<strong>1.</strong><strong>1.</strong> Variablen:<br />

Die Deklaration <strong>e<strong>in</strong>e</strong>r Variablen, <strong>ist</strong> deren Bekanntmachung an den Compiler. Es<br />

werden der Name und der Datentyp bekannt gegeben. Wichtig: Es wird KEIN<br />

Speicher reserviert!<br />

Es können nur globale Variablen deklariert werden. Alle anderen Variablen müssen<br />

def<strong>in</strong>iert werden.<br />

14.<strong>1.</strong>2. Funktionen:<br />

Die Deklaration <strong>e<strong>in</strong>e</strong>r Funktion funktioniert gleich wie bei Variablen. Es Handelt sich<br />

hierbei nur um <strong>e<strong>in</strong>e</strong> Bekanntmachung des Funktionsnamen, der<br />

Parameterdatentypen und des Datentyps des Rückgabewertes.<br />

long Funktionsname(long, long,…);<br />

Die Namen der Parameter können dabei weggelassen werden. Nur die Anzahl der<br />

Übergabeparameter muss richtig se<strong>in</strong>.<br />

14.2. Def<strong>in</strong>ition:<br />

14.2.<strong>1.</strong> Variablen:<br />

6


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Die Def<strong>in</strong>ition <strong>e<strong>in</strong>e</strong>r Variablen <strong>ist</strong> deren vollständige Beschreibung. Das bedeutet, es<br />

muss der Datentyp und der Variablenname bekannt gegeben werden. Der<br />

Unterschied zur Deklaration liegt dar<strong>in</strong>, dass bei der Def<strong>in</strong>ition der Speicherplatz<br />

reserviert wird. Es müssen alle Variablen def<strong>in</strong>iert werden, lediglich globale<br />

Variablen können deklariert werden.<br />

14.2.2. Funktionen:<br />

Die Def<strong>in</strong>ition <strong>e<strong>in</strong>e</strong>r Funktion umfasst deren vollständige Beschreibung. Anders als<br />

bei der Deklaration müssen hier der Funktionsname, der Datentyp des<br />

Rückgabewertes, die Namen der Übergabeparameter, sowie der Funktionsrumpf<br />

angegeben werden.<br />

E<strong>in</strong>e Funktion kann auch def<strong>in</strong>iert werden, ohne vorher deklariert zu werden. Dafür<br />

muss die Funktionsdef<strong>in</strong>ition vor dem Hauptprogramm (ma<strong>in</strong>()) und vor allem vor<br />

dem ersten Funktionsaufruf erfolgen. Also dort, wo sonst die Deklaration zu f<strong>in</strong>den<br />

wäre.<br />

long ergebnis(long wert1, long wert2)<br />

{<br />

return wert1+wert2;<br />

}<br />

15. Wie funktioniert die Parameterübergabe <strong>in</strong> C? Welche Arten der<br />

Parameterübergabe gibt es?<br />

Beim Funktionsaufruf werden die <strong>in</strong> runder Klammer () angegebenen Parameter an die<br />

Funktion übergeben. Die e<strong>in</strong>zelnen Objekte <strong>in</strong> der Parameterl<strong>ist</strong>e werden durch Komma (,)<br />

getrennt. Die Objekte werden <strong>in</strong> Form <strong>e<strong>in</strong>e</strong>r Kopie an die Funktion übergeben (Call by Value).<br />

long function(long var1, long var2);<br />

ergebnis= function(wert1, wert2);<br />

Die Variablen var1 und var2 werden mit den <strong>in</strong> den Variablen wert1 und wert2<br />

gespeicherten Daten <strong>in</strong>itialisiert. Innerhalb der Funktion kann mit diesen Variablen ganz<br />

normal gearbeitet werden.<br />

Bei Feldern würde diese Art der Parameterübergabe sehr viel Speicherplatz <strong>in</strong> Anspruch<br />

nehmen. Daher wird bei Feldern die Adresse des ersten Feldelementes übergeben. Es wird<br />

also e<strong>in</strong> Zeiger übergeben (Call by Reference). Im Endeffekt wird mit dem Orig<strong>in</strong>alfeld<br />

gearbeitet.<br />

long AusgabeFeld(long feld[], long len)<br />

Der erste Parametererwartet e<strong>in</strong> Feld mit beliebiger Länge. Um der Funktion die Länge des<br />

Feldes mitzuteilen <strong>ist</strong> der zweite Parameter len erforderlich.<br />

7


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

16. <strong>Was</strong> s<strong>in</strong>d mehrdimensionale Felder und wie werden sie im<br />

Speicher repräsentiert?<br />

Mehrdimensionale Felder, s<strong>in</strong>d Felder bei denen jedes Element wieder e<strong>in</strong> Feld <strong>ist</strong>. Sie haben<br />

daher mehrere Indizes.<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

long feld[a][b][c]…;<br />

long matrix[i][j];<br />

Letztes Beispiel def<strong>in</strong>iert <strong>e<strong>in</strong>e</strong> Matrix mit i Zeilen und j Spalten. Um die e<strong>in</strong>zelnen Elemente<br />

ansprechen zu können, werden auch wie bei e<strong>in</strong>dimensionalen Feldern die Indizes für i<br />

( ) und j ( )verwendet.<br />

Im Speicher werden die Elemente h<strong>in</strong>tere<strong>in</strong>ander wie bei e<strong>in</strong>dimensionalen Feldern angelegt.<br />

matrix[i][j]<br />

j<br />

i 0 E[0][0] E[0][1] E[0][2]<br />

im Speicher<br />

1 E[1][0] E[1][1] E[1][2]<br />

i=0,j=0<br />

0 1 2<br />

i=0,j=3 FEHLER<br />

i=1,j=0<br />

E[0][0] E[0][1] E[0][2] E[1][0] E[1][1] E[1][2]<br />

Die Nummerierung der Elemente von ( ) <strong>ist</strong> wichtig. Würde das dritte Element der<br />

ersten Zeile mit matrix[0][3] angesprochen werden, würde auf den Speicherplatz des<br />

Elementes matrix[1][0] zugegriffen werden.<br />

17. Wie kann e<strong>in</strong> Feld elegant an <strong>e<strong>in</strong>e</strong> Funktion übergeben werden?<br />

E<strong>in</strong> Feld kann elegant als rekursive Struktur an <strong>e<strong>in</strong>e</strong> Funktion übergeben werden. Dies hat vor<br />

allem den Vorteil, dass die Anzahl der Elemente unbegrenzt und variabel <strong>ist</strong>.<br />

struct E<strong>in</strong>trag_s<br />

{<br />

struct E<strong>in</strong>trag_s *nächster;<br />

long wert;<br />

};<br />

18. Sortierverfahren:<br />

18.<strong>1.</strong> M<strong>in</strong>imum <strong>–</strong> Suche (Selection <strong>–</strong> Sort):<br />

M<strong>in</strong>imum- und Maximum <strong>–</strong> Suche arbeiten mit demselben Verfahren.<br />

8


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Es <strong>ist</strong> e<strong>in</strong> e<strong>in</strong>faches aber sehr langsames Verfahren. Es wird <strong>in</strong> <strong>e<strong>in</strong>e</strong>r Folge von Zahlen das<br />

kle<strong>in</strong>ste bzw. größte Element gesucht und gegen das Element an der Stelle 0 getauscht.<br />

Dann wird das nächst größere bzw. kl<strong>e<strong>in</strong>e</strong>re Element gesucht und gegen Das Element an<br />

der Stelle 1 getauscht. Dieses Verfahren wird solange ausgeführt, bis alle Elemente<br />

geordnet s<strong>in</strong>d. Zum Umsortieren wird der Dreieckstausch verwendet.<br />

long feld[4]={2,1,4,7};<br />

long x;<br />

x=feld[0];<br />

feld[0]=feld[3];<br />

feld[3]=x;<br />

18.2. Bubble <strong>–</strong> Sort:<br />

Bei diesem Verfahren werden immer zwei benachbarte Elemente mite<strong>in</strong>ander verglichen.<br />

Ist das l<strong>in</strong>ke Element größer als das Rechte, so werden die zwei Elemente getauscht. Je<br />

größer <strong>e<strong>in</strong>e</strong> Zahl <strong>ist</strong>, desto weiter nach rechts wandert sie <strong>in</strong> der Zahlenfolge. Da dieser<br />

Vorgang dem Aufsteigen <strong>e<strong>in</strong>e</strong>s Bläschens im <strong>Was</strong>ser gleicht, wird dieses Verfahren<br />

Bubble-Sort genannt.<br />

Im schlechtesten Fall s<strong>in</strong>d N-1 Sortierdurchläufe notwendig. Je öfter das Verfahren<br />

durchlaufen wurde, desto kürzer werden die nächsten Durchläufe.<br />

18.3. Quicksort:<br />

Quicksort <strong>ist</strong> e<strong>in</strong> sehr schnelles Sortierverfahren. Es erwartet die zu sortierenden Daten <strong>in</strong><br />

<strong>e<strong>in</strong>e</strong>m Feld. Dieses Verfahren arbeitet rekursiv.<br />

Quicksort br<strong>in</strong>gt <strong>in</strong> jedem Schritt e<strong>in</strong> Element an s<strong>e<strong>in</strong>e</strong> korrekte Position.<br />

FORTSETZEN!!<br />

18.4. Heap <strong>–</strong> Sort:<br />

Betrachtet man Heaps, so <strong>ist</strong> k<strong>e<strong>in</strong>e</strong> aufsteigende sequenzielle Sortierung der Elemente<br />

erkennbar. Dennoch ermöglichen Heaps das effiziente Sortieren von Feldern <strong>in</strong> ungefähr<br />

( ) Schritten. Der Sortieralgorithmus lautet:<br />

Entferne die Wurzel aus dem Heap. Widerhohle den Vorgang solange, bis der Heap leer <strong>ist</strong>.<br />

Die Elemente liegen dann <strong>in</strong> sortierte Reihenfolge im Feld vor.<br />

Entfernt man <strong>e<strong>in</strong>e</strong>n beliebigen Knoten aus dem Heap, so wird dieser zunächst mit dem<br />

letzten Element des Heaps getauscht. Nach dem Entfernen muss die Heapstruktur wieder<br />

repariert werden. Entfernt man alle Wurzeln, so wird das Element mit dem größten<br />

Schlüssel nach h<strong>in</strong>ten gestellt. Diese Tatsache nutzt Heap <strong>–</strong> Sort aus.<br />

9


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

19. <strong>Was</strong> <strong>ist</strong> e<strong>in</strong> Str<strong>in</strong>g?<br />

Literale von Zeichenketten s<strong>in</strong>d Zeichenfolgen, welche <strong>in</strong> doppelte Anführungszeichen<br />

gesetzt s<strong>in</strong>d.<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

„Hallo Welt!“<br />

Zeichenketten <strong>in</strong> C s<strong>in</strong>d „nullterm<strong>in</strong>ierte“ Folgen von Zeichen, welche <strong>in</strong> Feldern von Zeichen<br />

gespeichert werden.<br />

„Nullterm<strong>in</strong>iert“ bedeutet, dass <strong>e<strong>in</strong>e</strong> Zeichenkette mit <strong>e<strong>in</strong>e</strong>r ‚\0‘ abgeschlossen wird. Das<br />

bedeutet weiter, dass <strong>e<strong>in</strong>e</strong> Zeichenkette mit 5 Zeichen 6 Speicherplätze benötigt.<br />

‘H‘ ‘A‘ ‘L‘ ‘L‘ ‘O‘ ‘\0‘<br />

Das Null-Byte <strong>ist</strong> das Zeichen mit dem ASCII-Code 0. Es <strong>ist</strong> also die Zahl „0“ (\0), nicht zu<br />

verwechseln mit dem Zeichen „0“ (Null).<br />

Dieses Null-Byte wird automatisch an den Text angehängt.<br />

Dies hat den Vorteil, dass beliebig lange Texte abgespeichert werden können. Der Text endet<br />

immer mit dem Null-Byte.<br />

Zum Feststellen der Länge <strong>e<strong>in</strong>e</strong>r Zeichenkette wird die Funktion strlen() verwendet.<br />

19.<strong>1.</strong> Welche Funktionen s<strong>in</strong>d auf Zeichenketten def<strong>in</strong>iert?<br />

Funktion Beschreibung<br />

strcat(s1,s2) Anhängen von s2 an s1<br />

strcmp(s1,s2) Lexikographischer Vergleich der Str<strong>in</strong>gs s1 und s2<br />

strcpy(s1,s2) Kopiert s2 nach s1<br />

strlen(s) Anzahl der Zeichen <strong>in</strong> Str<strong>in</strong>g s ( = sizeof(s1)-1 )<br />

strchr(s, c) Sucht Character c <strong>in</strong> Str<strong>in</strong>g s<br />

strstr(s, t)<br />

Sucht Zeichenkette t <strong>in</strong> s und liefert den Zeiger auf das erste<br />

Zeichen Vorkommnis<br />

Es gibt noch weitere Funktionen auf Zeichenketten.<br />

20. <strong>Was</strong> s<strong>in</strong>d variante Strukturen?<br />

Variante Strukturen haben große Ähnlichkeit mit regulären Strukturen, die mit struct<br />

def<strong>in</strong>iert werden. Während jedoch die Attribute von regulären Strukturen im Speicher<br />

h<strong>in</strong>tere<strong>in</strong>ander liegen, belegen die Attribute von varianten Strukturen denselben<br />

Speicherbereich, sie liegen quasi übere<strong>in</strong>ander.<br />

Dies bed<strong>in</strong>gt, dass beim Schreiben <strong>e<strong>in</strong>e</strong>s Attributs alle anderen überschrieben werden und<br />

somit ungültig werden. Die Werte der überschriebenen Attribute s<strong>in</strong>d somit nicht mehr<br />

def<strong>in</strong>iert.<br />

Variante Strukturen werden dort verwendet, wenn mehrere Attribute zu <strong>e<strong>in</strong>e</strong>r Struktur<br />

zusammengefasst werden sollen, welche nicht gleichzeitig auftreten können. Zum Beispiel<br />

e<strong>in</strong> geometrisches Objekt kann entweder e<strong>in</strong> Kreis oder e<strong>in</strong> Rechteck se<strong>in</strong>, aber nie beides<br />

gleichzeitig.<br />

10


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Def<strong>in</strong>iert werden variante Strukturen mit dem Schlüsselwort union. Die Def<strong>in</strong>ition erfolgt<br />

äquivalent zu Strukturen mit struct.<br />

Union Unionname_u<br />

{<br />

Typ Attribute;<br />

};<br />

2<strong>1.</strong> <strong>Was</strong> s<strong>in</strong>d rekursive Strukturen?<br />

Rekursive Strukturen s<strong>in</strong>d Strukturen, welche Attribute enthalten, die auf Strukturen<br />

desselben Typs verweisen.<br />

struct E<strong>in</strong>trag_s<br />

{<br />

struct E<strong>in</strong>trag_s *nächster;<br />

long wert;<br />

};<br />

Das Attribut *nächster <strong>ist</strong> e<strong>in</strong> Zeiger auf e<strong>in</strong> weiteres Objekt dieser Struktur.<br />

Rekursive Strukturen können sehr s<strong>in</strong>nvoll im Bereich der dynamischen Speicherverwaltung<br />

e<strong>in</strong>gesetzt werden.<br />

22. <strong>Was</strong> s<strong>in</strong>d rekursive Funktionen? <strong>Was</strong> passiert wenn die<br />

Abbruchbed<strong>in</strong>gung erfüllt <strong>ist</strong>?<br />

Funktionen, welche sich selbst aufrufen nennt man rekursiv.<br />

Jeder Durchlauf der Funktion trägt zur Gesamtlösung bei.<br />

22.<strong>1.</strong> Rekursive Algorithmen:<br />

Viele Algorithmen lassen sich <strong>in</strong> gleichartige Teilprobleme zerlegen. Kennzeichen<br />

rekursiver Algorithmen <strong>ist</strong>, dass die Gesamtlösung durch lösen gleichartiger Teilprobleme<br />

erreicht wird.<br />

Regeln für rekursive Algorithmen:<br />

Die Aufgabe wird <strong>in</strong> gleichartige Teilprobleme zerlegt. Die Teilprobleme werden<br />

Rekursiv gelöst<br />

Jede Rekursion trägt zur Gesamtlösung bei.<br />

Für m<strong>in</strong>destens <strong>e<strong>in</strong>e</strong> Komb<strong>in</strong>ation der Funktionsparameter muss die Rekursion<br />

beendet werden. Dieser Fall muss auch tatsächlich auftreten, sonst term<strong>in</strong>iert der<br />

Algorithmus nicht und <strong>ist</strong> daher per Def<strong>in</strong>ition ke<strong>in</strong> Algorithmus mehr.<br />

In C werden rekursive Funktionen mittels <strong>e<strong>in</strong>e</strong>s Stapels realisiert, wobei jede<br />

Rekursionsebene ihr eigenes Variablenset am Stapel bekommt.<br />

11


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Durch jeden Selbstaufruf der Funktion wird der Stapel (Stack) größer, <strong>ist</strong> <strong>e<strong>in</strong>e</strong><br />

Abbruchbed<strong>in</strong>gung erfüllt, also wenn <strong>e<strong>in</strong>e</strong> Funktion beendet wird, wird die zugehörige<br />

Rekursionsebene zerstört und zur vorherigen Ebene zurückgekehrt.<br />

Verwendet werden rekursive Algorithmen zum Beispiel bei Quicksort und beim Traversieren<br />

von Bäumen.<br />

23. <strong>Was</strong> <strong>ist</strong> <strong>e<strong>in</strong>e</strong> e<strong>in</strong>fach verkettete L<strong>ist</strong>e und wie <strong>ist</strong> diese aufgebaut?<br />

Unter <strong>e<strong>in</strong>e</strong>r L<strong>ist</strong>e versteht man <strong>e<strong>in</strong>e</strong> sequenzielle Ane<strong>in</strong>anderreihung von Elementen, deren<br />

Reihenfolge explizit festgehalten wird. E<strong>in</strong>e L<strong>ist</strong>e besteht aus Knoten, dar<strong>in</strong> werden<br />

<strong>e<strong>in</strong>e</strong>rseits die zu speichernden Daten und andererseits die Verkettung zum nächsten Knoten.<br />

Der Anfang der L<strong>ist</strong>e, der L<strong>ist</strong>enkopf, wird separat behandelt.<br />

In C wird e<strong>in</strong> sogenannter Knoten durch <strong>e<strong>in</strong>e</strong>n Verbunddatentyp realisiert, welcher die Daten<br />

und <strong>e<strong>in</strong>e</strong>n Verweis auf das nächste L<strong>ist</strong>enelement be<strong>in</strong>haltet. Der Kopf verwe<strong>ist</strong> auf das erste<br />

L<strong>ist</strong>enelement. E<strong>in</strong> Feld von Knoten muss nur noch <strong>in</strong>itialisiert werden und die Verkettungen<br />

erstellt werden.<br />

Der letzte Knoten muss speziell gekennzeichnet se<strong>in</strong>, damit das Ende der L<strong>ist</strong>e erkannt<br />

werden kann. Hierfür wird der Verweis auf das nächste L<strong>ist</strong>enelement im letzten Element auf<br />

NULL gesetzt.<br />

24. Wie funktioniert das „E<strong>in</strong>fügen“ <strong>in</strong> L<strong>ist</strong>en?<br />

Um e<strong>in</strong> neues Element <strong>in</strong> <strong>e<strong>in</strong>e</strong> bestehende L<strong>ist</strong>e e<strong>in</strong>zufügen, muss diese L<strong>ist</strong>e an der<br />

gewünschten Stelle aufgebrochen werden und der neue Datensatz dort e<strong>in</strong>gefügt werden.<br />

E<strong>in</strong> neues Element am L<strong>ist</strong>enanfang e<strong>in</strong>zufügen <strong>ist</strong> sehr e<strong>in</strong>fach, solange die Feldgrenze dabei<br />

nicht überschritten wird. Soll e<strong>in</strong> Element an <strong>e<strong>in</strong>e</strong>r anderen Stelle <strong>in</strong> der L<strong>ist</strong>e e<strong>in</strong>gefügt<br />

werden, so muss die L<strong>ist</strong>e aufgebrochen werden. Der zukünftige Vorgänger des neuen<br />

Elements muss auf das neue Element verkettet werden und das neue auf das<br />

Nachfolgerelement vom Vorgänger.<br />

25. <strong>Was</strong> <strong>ist</strong> <strong>e<strong>in</strong>e</strong> R<strong>in</strong>gl<strong>ist</strong>e?<br />

E<strong>in</strong>e R<strong>in</strong>gl<strong>ist</strong>e <strong>ist</strong> <strong>e<strong>in</strong>e</strong> sehr selten verwendete Form von L<strong>ist</strong>en. Dabei speichert der letzte<br />

Knoten <strong>e<strong>in</strong>e</strong>n Verweis an den L<strong>ist</strong>enanfang, wodurch <strong>e<strong>in</strong>e</strong> Rekursion ermöglicht wird.<br />

26. Erklärung Datenstruktur Schlange:<br />

Die Datenstruktur Schlange arbeitet nach dem Pr<strong>in</strong>zip FIFO (first <strong>in</strong> first out). Mit den<br />

Methoden put und get können Elemente <strong>in</strong> die Schlange gestellt werden und wieder<br />

entnommen werden. Das als erstes e<strong>in</strong>gefügte Element wird auch als erstes wieder<br />

entnommen. Schlangen s<strong>in</strong>d vorzugsweise mit L<strong>ist</strong>en implementiert.<br />

12


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

27. <strong>Was</strong> <strong>ist</strong> e<strong>in</strong> Zirkularpuffer?<br />

E<strong>in</strong> Zirkularpuffer <strong>ist</strong> <strong>e<strong>in</strong>e</strong> Implementierung der Schlange und arbeitet nach demselben<br />

Pr<strong>in</strong>zip. E<strong>in</strong> Unterschied zur Schlange <strong>ist</strong> jener, dass Zirkularpuffer <strong>in</strong> Feldern implementiert<br />

s<strong>in</strong>d. Die E<strong>in</strong>füge- und Entnahmeposition s<strong>in</strong>d durch die Indizes im Feld gegeben. Nach dem<br />

E<strong>in</strong>fügen <strong>e<strong>in</strong>e</strong>s neuen Elements wird der Index der E<strong>in</strong>fügeposition erhöht. Ebenso wird bei<br />

der Entnahme verfahren. Nach dem Entnehmen <strong>e<strong>in</strong>e</strong>s Elements wird der Index der<br />

Entnahmeposition erhöht. Wird die Feldlänge überschritten, so wird der jeweilige Index auf<br />

den Feldanfang gesetzt (Herkunft des Namens: Zirkularpuffer).<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Zirkularpuffer werden gerne zur asynchronen Kommunikation zweier Prozesse verwendet.<br />

Problemsituationen: overflow, underflow<br />

28. Wie funktioniert <strong>e<strong>in</strong>e</strong> doppelt verkettete L<strong>ist</strong>e (DLL):<br />

DLL … double l<strong>in</strong>ked l<strong>ist</strong><br />

Im Gegensatz zu e<strong>in</strong>fach verketteten L<strong>ist</strong>en wird bei DLL auch die Verkettung zum Vorgänger<br />

gespeichert.<br />

Der Vorteil dieser Art von L<strong>ist</strong>en liegt dar<strong>in</strong>, dass e<strong>in</strong> Rückwärtsbewegen <strong>in</strong> der L<strong>ist</strong>e möglich<br />

<strong>ist</strong>, da der Vorgänger bekannt <strong>ist</strong>. Somit kann mit Referenzen auf Knoten sehr effektiv<br />

gearbeitet werden.<br />

E<strong>in</strong> Nachteil von doppelt verketteten L<strong>ist</strong>en <strong>ist</strong>, dass beim E<strong>in</strong>fügen von neuen Elementen<br />

oder beim Umsortieren zusätzlich zum Nachfolger auch noch der Vorgänger richtig gesetzt<br />

werden muss. Dies <strong>ist</strong> <strong>e<strong>in</strong>e</strong> zusätzliche Fehlerquelle.<br />

29. Wie funktioniert das E<strong>in</strong>fügen <strong>in</strong> <strong>e<strong>in</strong>e</strong> doppelt verkettete L<strong>ist</strong>e?<br />

Wie implementiert man diese Funktion?<br />

E<strong>in</strong> Knoten <strong>in</strong> <strong>e<strong>in</strong>e</strong>r doppelt verketteten L<strong>ist</strong>e wird als Verbunddatentyp realisiert. E<strong>in</strong> Knoten<br />

speichert die Daten, <strong>e<strong>in</strong>e</strong>n Verweis auf den Vorgänger und <strong>e<strong>in</strong>e</strong>n Verweis auf den Nachfolger.<br />

Es handelt sich hierbei also um <strong>e<strong>in</strong>e</strong> rekursive Struktur.<br />

Wird e<strong>in</strong> neues Element <strong>in</strong> die L<strong>ist</strong>e e<strong>in</strong>gefügt, so müssen die Verweise von 3 Knoten<br />

verändert werden.<br />

E<strong>in</strong> Beispiel:<br />

Konten: x, y<br />

x->Nachfolger =y<br />

y->Vorgänger =x<br />

Neuer Knoten: z wird zwischen x und y e<strong>in</strong>gefügt<br />

z-> Vorgänger =x<br />

z-> Nachfolger = y<br />

x->Nachfolger = z<br />

y->Vorgänger = z<br />

13


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

30. Erklärung Bäume:<br />

Bäume werden beim Programmieren häufig verwendet. Es gibt unterschiedlichste Arten<br />

davon, wie etwa Bäume zur Speicherung von Daten, Bäume zum Sortieren, Bäume für<br />

Syntaxanalyseprobleme, geometrische und mathematische Probleme oder für die<br />

Datenkomprimierung.<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

L<strong>ist</strong>en stellen <strong>e<strong>in</strong>e</strong> e<strong>in</strong>dimensionale Datenstruktur, im Gegensatz dazu können Bäume als<br />

mehrdimensionale „Erweiterungen“ gesehen werden. E<strong>in</strong> Knoten hat bei <strong>e<strong>in</strong>e</strong>m Baum nicht<br />

nur <strong>e<strong>in</strong>e</strong>n Nachfolger, sondern kann auch mehrere haben. Die Verknüpfung zweier Knoten<br />

wird Kante genannt, Knoten ohne Nachfolger heißen Endknoten. Als Wurzel <strong>e<strong>in</strong>e</strong>s Baumes<br />

wird jener Knoten genannt, der k<strong>e<strong>in</strong>e</strong> Vorgänger hat.<br />

Bäumen könne auch rekursiv def<strong>in</strong>iert werden. Dabei besteht e<strong>in</strong> Baum aus mehreren<br />

Subbäumen, deren Wurzeln durch <strong>e<strong>in</strong>e</strong>n geme<strong>in</strong>samen Knoten verkettet s<strong>in</strong>d.<br />

Es gibt verschiedene Knoten:<br />

Wurzel: dieser Knoten hat k<strong>e<strong>in</strong>e</strong>n Vorgänger<br />

Parent: Ist der Vorgängerknoten <strong>e<strong>in</strong>e</strong>s weiteren Knoten<br />

Endknoten, äußerer Knoten: hat k<strong>e<strong>in</strong>e</strong> Nachfolger<br />

Innerer Knoten<br />

E<strong>in</strong> allgem<strong>e<strong>in</strong>e</strong>r Baum mit Knoten hat Kanten.<br />

3<strong>1.</strong> <strong>Was</strong> <strong>ist</strong> e<strong>in</strong> b<strong>in</strong>ärer Baum?<br />

E<strong>in</strong> b<strong>in</strong>ärer Baum hat pro Knoten genau 2 Nachfolger. Die Knoten <strong>e<strong>in</strong>e</strong>s solchen Baumes<br />

be<strong>in</strong>halten die Daten und die Verkettungen zu den Nachfolgern.<br />

E<strong>in</strong> b<strong>in</strong>ärer Baum mit <strong>in</strong>neren Knoten hat maximal äußere Knoten.<br />

Bei <strong>e<strong>in</strong>e</strong>m vollständigen Baum s<strong>in</strong>d die Blätter von l<strong>in</strong>ks nach rechts angefügt.<br />

32. B<strong>in</strong>äre Suchbäume:<br />

E<strong>in</strong> b<strong>in</strong>ärer Suchbaum <strong>ist</strong> e<strong>in</strong> b<strong>in</strong>ärer Baum, bei dem jeder Knoten <strong>e<strong>in</strong>e</strong> besondere Bed<strong>in</strong>gung<br />

erfüllt. Alle Knoten im l<strong>in</strong>ken Unterbaum <strong>e<strong>in</strong>e</strong>s Knotens haben kl<strong>e<strong>in</strong>e</strong>re Schlüssel. Alle Knoten<br />

im rechten Unterbaum <strong>e<strong>in</strong>e</strong>s Knoten haben größere Schlüssel.<br />

Für gleiche Schlüssel wurde die Vere<strong>in</strong>barung getroffen, dass diese am l<strong>in</strong>ken Unterbaum<br />

angehängt werden.<br />

Es <strong>ist</strong> nicht möglich <strong>e<strong>in</strong>e</strong>n Baum <strong>in</strong> <strong>e<strong>in</strong>e</strong>n vollständigen b<strong>in</strong>ären Baum umzuwandeln und<br />

gleichzeitig die Bed<strong>in</strong>gung für b<strong>in</strong>äre Suchbäume zu erfüllen. Da <strong>in</strong> <strong>e<strong>in</strong>e</strong>m Baum mehrere<br />

Knoten mit dem gleichen Schlüssel vorkommen können, <strong>ist</strong> dies nicht möglich.<br />

14


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

33. <strong>Was</strong> versteht man unter Traversierung?<br />

Die Traversierung <strong>e<strong>in</strong>e</strong>s Baumes beschreibt, wie dieser durchlaufen <strong>–</strong> traversiert- werden<br />

kann. Dieser Aufgabe <strong>ist</strong> besonders schön rekursiv zu lösen.<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Es gibt verschiedene Methoden, die Traversierung vorzunehmen:<br />

Level <strong>–</strong> Order<br />

Preorder- Traversierung: B-A-C<br />

Inorder- Traversierung: A-B-C<br />

Postorder <strong>–</strong> Traversierung: A-C-B<br />

Die Methoden Preorder, Inorder und Postorder s<strong>in</strong>d sehr ähnlich. Unterschiedlich <strong>ist</strong> nur die<br />

Reihenfolge, <strong>in</strong> der die Knoten durchlaufen werden.<br />

Die Methode Level <strong>–</strong> Order kommt bei Heap-Strukturen zum E<strong>in</strong>satz. Dabei werden die<br />

Element zeilenweise durchlaufen von l<strong>in</strong>ks nach rechts.<br />

34. Suchen <strong>e<strong>in</strong>e</strong>s Elements <strong>in</strong> <strong>e<strong>in</strong>e</strong>m b<strong>in</strong>ären Suchbaum:<br />

Soll <strong>in</strong> <strong>e<strong>in</strong>e</strong>m Baum nach <strong>e<strong>in</strong>e</strong>m bestimmten Element gesucht werden, so muss dieser<br />

traversiert werden. Die günstigste Reihenfolge der Abfrage:<br />

Ist der gesuchte Schlüssel kl<strong>e<strong>in</strong>e</strong>r als jener des aktuellen Knoten, wird nach l<strong>in</strong>ks<br />

verzweigt.<br />

Ist der gesuchte Schlüssel größer als jener des aktuellen Knoten, wird nach rechts<br />

verzweigt.<br />

Ist der gesuchte Schlüssel gleich dem aktuellen, so <strong>ist</strong> der Knoten gefunden.<br />

Bei gleichverteilten Schlüsseln, werden bei erfolgreicher Suche <strong>in</strong> <strong>e<strong>in</strong>e</strong>m vollständigen Baum<br />

etwa ( ) Vergleiche durchgeführt.<br />

E<strong>in</strong>e erfolglose Suche wird erst festgestellt, wenn e<strong>in</strong> Endknoten erreicht <strong>ist</strong>. Es s<strong>in</strong>d zirka<br />

Vergleiche notwendig.<br />

35. E<strong>in</strong>fügen <strong>e<strong>in</strong>e</strong>s neuen Elements <strong>in</strong> <strong>e<strong>in</strong>e</strong>n b<strong>in</strong>ären Suchbaum:<br />

Um <strong>e<strong>in</strong>e</strong>n Knoten <strong>in</strong> <strong>e<strong>in</strong>e</strong>n b<strong>in</strong>ären Suchbaum e<strong>in</strong>zufügen, wird das Element „erfolglos“<br />

gesucht, das bedeutet, dass die Suche erst abbricht, wenn e<strong>in</strong> Endknoten erreicht <strong>ist</strong>.<br />

Das erste Element <strong>in</strong> <strong>e<strong>in</strong>e</strong>n Suchbaum e<strong>in</strong>zufügen <strong>ist</strong> trivial. Beim nächsten Element muss<br />

ermittelt werden, ob der Schlüssel des neuen Elements größer oder kl<strong>e<strong>in</strong>e</strong>r <strong>ist</strong> als der des<br />

bereits vorhandenen Knoten.<br />

Ist der Schlüssel kl<strong>e<strong>in</strong>e</strong>r, so wird der Knoten L<strong>in</strong>ks angehängt, <strong>ist</strong> er größer wird er rechts<br />

angehängt.<br />

15


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

36. Löschen <strong>e<strong>in</strong>e</strong>s Elements <strong>in</strong> <strong>e<strong>in</strong>e</strong>m b<strong>in</strong>ären Suchbaum:<br />

E<strong>in</strong> Element aus <strong>e<strong>in</strong>e</strong>m b<strong>in</strong>ären Suchbaum zu löschen <strong>ist</strong> etwas aufwändiger als nur zu<br />

sortieren, <strong>e<strong>in</strong>e</strong>n Knoten e<strong>in</strong>zufügen, traversieren oder zu suchen. Die Schlüssel s<strong>in</strong>d me<strong>ist</strong><br />

untrennbar mit der Struktur von Bäumen verbunden.<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Beim Löschen <strong>e<strong>in</strong>e</strong>s Knotens kommt es zu <strong>e<strong>in</strong>e</strong>r Beschädigung der Baumstruktur. Diese muss<br />

anschließend wieder repariert werden.<br />

Wird e<strong>in</strong> Knoten gelöscht, so muss e<strong>in</strong> anderer gefunden werden, der den Platz des<br />

gelöschten Knotens e<strong>in</strong>nimmt, um die Baumstruktur zu erhalten.<br />

Dieser Knoten muss so gewählt werden, dass die Bed<strong>in</strong>gungen für <strong>e<strong>in</strong>e</strong>n b<strong>in</strong>ären Suchbaum<br />

erhalten bleiben. Somit <strong>ist</strong> der gesuchte Knoten jener mit dem nächst kl<strong>e<strong>in</strong>e</strong>rem oder<br />

größerem Schlüssel. Dies garantiert, dass ke<strong>in</strong> anderer Schlüssel dazwischen liegt.<br />

36.<strong>1.</strong> Algorithmus zum Löschen <strong>e<strong>in</strong>e</strong>s Knotens:<br />

Buch Seite 285.<br />

37. <strong>Was</strong> <strong>ist</strong> e<strong>in</strong> Heap und für welche Operationen <strong>ist</strong> er gut geeignet?<br />

E<strong>in</strong>e Heap <strong>–</strong> Struktur <strong>ist</strong> <strong>e<strong>in</strong>e</strong> sogenannte Prioritätswarteschlange, die es ermöglicht den<br />

größten E<strong>in</strong>trag zu f<strong>in</strong>den, zu löschen und neue Elemente e<strong>in</strong>zufügen.<br />

Es <strong>ist</strong> <strong>e<strong>in</strong>e</strong> besondere Art <strong>e<strong>in</strong>e</strong>s b<strong>in</strong>ären Baumes, der als Feld gespeichert wird. Jeder Knoten<br />

muss dabei die sogenannte Heap <strong>–</strong> Bed<strong>in</strong>gung erfüllen:<br />

37.<strong>1.</strong> Heap <strong>–</strong> Bed<strong>in</strong>gung:<br />

Der Schlüssel jedes Knoten <strong>e<strong>in</strong>e</strong>s Heaps <strong>ist</strong> größer als se<strong>in</strong> Nachfolger. Falls auch gleiche<br />

Schlüssel auftreten können muss der Schlüssel jedes Knotens größer oder gleich dem<br />

s<strong>e<strong>in</strong>e</strong>r Nachfolger se<strong>in</strong>.<br />

E<strong>in</strong> Heap <strong>ist</strong> e<strong>in</strong> vollständiger b<strong>in</strong>ärer Baum. Im Unterschied dazu lautet die Bed<strong>in</strong>gung für<br />

b<strong>in</strong>äre Suchbäume, dass der Schlüssel des l<strong>in</strong>ken Nachfolgers kl<strong>e<strong>in</strong>e</strong>r und der Schlüssel des<br />

rechten Nachfolgers größer <strong>ist</strong>. Daher s<strong>in</strong>d die Elemente <strong>in</strong> <strong>e<strong>in</strong>e</strong>m Baum vollständig anders<br />

verteilt.<br />

Jedem Knoten wird e<strong>in</strong> fortlaufender Index zeilenweise zugewiesen. Diese Indizes<br />

entsprechen den Feld<strong>in</strong>dizes. Der Index „0“ ex<strong>ist</strong>iert nicht.<br />

Die Implementierung im Feld br<strong>in</strong>gt mehrere Vorteile:<br />

Heaps speichern k<strong>e<strong>in</strong>e</strong> expliziten Verknüpfungen, wodurch zum Feststellen des<br />

Vorgängers oder Nachfolgers nur e<strong>in</strong>fache arithmetische Operationen durchgeführt<br />

werden müssen.<br />

Die Nachfolger <strong>e<strong>in</strong>e</strong>s Elements mit dem Index haben die Indizes und .<br />

Umgekehrt s<strong>in</strong>d die Vorgänger zu ermitteln. Der Index <strong>e<strong>in</strong>e</strong>s Vorgängers ergibt sich<br />

zu:<br />

⁄ . Jede Ebene hat 1 Element mehr als alle höheren Ebenen. Jede vollständige<br />

Ebene hat doppelt so viele Elemente als die vorhergehende.<br />

16


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Der Nachteil der Feldimplementierung <strong>ist</strong> die starre Struktur, da explizite<br />

Verknüpfungen fehlen. Heaps bieten jedoch so viel Flexibilität, um effiziente<br />

Algorithmen für Prioritätsschlangen implementieren zu können.<br />

37.2. Methoden für Heaps:<br />

E<strong>in</strong>fügen <strong>e<strong>in</strong>e</strong>s neuen Elements: Um e<strong>in</strong> neues Element <strong>in</strong> den Heap e<strong>in</strong>zufügen,<br />

wird es an die nächste freie Position gestellt, also an die Stelle nach dem letzten<br />

E<strong>in</strong>trag. Dadurch wird höchst wahrsche<strong>in</strong>lich die Heapbed<strong>in</strong>gung verletzt. Der<br />

Heap muss neu sortiert werden.<br />

Traversieren über <strong>e<strong>in</strong>e</strong>n Heap <strong>ist</strong> trivial, da durch e<strong>in</strong>fache arithmetische<br />

Berechnungen der Nachfolger und auch der Vorgänger berechnet werden kann.<br />

Hauptsächlich werden die Level <strong>–</strong> Order- oder Preorder <strong>–</strong> Methode angewendet.<br />

Entfernen <strong>e<strong>in</strong>e</strong>s Elements: Es wird e<strong>in</strong> Trick angewandt. Das zu löschende Element<br />

wird mit dem letzten Element getauscht und dann dieses gelöscht. Dadurch wird<br />

e<strong>in</strong> aufreißen der Heapstruktur verh<strong>in</strong>dert und der Heap um e<strong>in</strong> Element verkürzt.<br />

Das bedeutet die Feldgröße wird um 1 verr<strong>in</strong>gert.<br />

Nach dem Löschen oder E<strong>in</strong>fügen <strong>e<strong>in</strong>e</strong>s neuen Elementes <strong>in</strong> den Heap, muss dieser wieder<br />

repariert werden. Zum Reparieren des Heaps gibt es die Funktionen UpHeap und<br />

DownHeap.<br />

37.2.<strong>1.</strong> UpHeap:<br />

Mit dieser Methode wird e<strong>in</strong> Heap repariert. Es wird am Ende des Heaps (ganz<br />

h<strong>in</strong>ten, am unteren Ende) begonnen. Die Funktion arbeitet von Unten nach Oben,<br />

daher auch der Name. Es wird verglichen, ob der Schlüssel des Vorgängers kl<strong>e<strong>in</strong>e</strong>r<br />

<strong>ist</strong>. Ist dies der Fall werden die Elemente getauscht. Das Element steigt somit im<br />

Heap h<strong>in</strong>auf. Diese Aktion wird solange wiederholt, bis der Heap durchsortiert und<br />

die Heapbed<strong>in</strong>gung erfüllt <strong>ist</strong>. Diese Methode wird beim E<strong>in</strong>fügen von neuen<br />

Elementen <strong>in</strong> <strong>e<strong>in</strong>e</strong>n Heap verwendet.<br />

37.2.2. DownHeap:<br />

Diese Methode arbeitet top down, also von Oben nach Unten. Dabei wird e<strong>in</strong><br />

Element mit s<strong>e<strong>in</strong>e</strong>m Nachfolger verglichen. Ist der Schlüssel von <strong>e<strong>in</strong>e</strong>m der beiden<br />

Nachfolger größer, so wird das Element mit s<strong>e<strong>in</strong>e</strong>m Nachfolger getauscht. S<strong>in</strong>d<br />

beide Nachfolger größer, so wird das Element mit dem Nachfolger, der den größten<br />

Schlüssel hat getauscht. Haben beide Nachfolger gleiche oder größere Schlüssel, so<br />

wird je nach Implementierung mit dem l<strong>in</strong>ken oder rechten Nachfolger getauscht.<br />

Diese Methode setzt <strong>e<strong>in</strong>e</strong>n korrekten Heap voraus, bis auf e<strong>in</strong> Element, welches<br />

richtig e<strong>in</strong>geordnet werden soll. Sie wird beim Löschen oder Ersetzten <strong>e<strong>in</strong>e</strong>s<br />

E<strong>in</strong>trages verwendet.<br />

38. Erklärung Hash:<br />

E<strong>in</strong> Hash eignet sich besonders gut zum effizienten Speichern und Suchen von Datensätzen.<br />

Das Verfahren beruht auf dem Pr<strong>in</strong>zip des Feldes, <strong>in</strong> welchem die Datensätze geeignet<br />

gespeichert und mittels <strong>e<strong>in</strong>e</strong>s generierten Index gesucht werden.<br />

17


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Der Schlüssel wird dabei <strong>in</strong> <strong>e<strong>in</strong>e</strong> Tabellenadresse umgewandelt. Dadurch kann bei <strong>e<strong>in</strong>e</strong>r<br />

Suche sofort auf diese Tabellenadresse, ohne den vollständigen Datensatz zu durchlaufen,<br />

zugegriffen werden.<br />

Ziele dieses Verfahrens s<strong>in</strong>d <strong>e<strong>in</strong>e</strong> effizientere Nutzung der verfügbaren Speicherkapazität und<br />

e<strong>in</strong> schnellerer Zugriff.<br />

Der Index wird von der Hash-Funktion generiert.<br />

38.<strong>1.</strong> Hash-Funktion:<br />

Die Hash-Funktion hat die Aufgabeumfangreiche Daten(z.B.: Texte) <strong>in</strong> kurze, möglichste<br />

e<strong>in</strong>deutige Identifikationen (den Hash-Wert des Textes) umzuwandeln. Dazu berechnet<br />

die Funktion über <strong>e<strong>in</strong>e</strong>n Suchschlüssel den Index für die Hash-Tabelle.<br />

Es empfiehlt sich, die maximale Größe des Hashes (Anzahl der möglichen Schlüssel)<br />

mitanzugeben, da die Funktion für verschiedene Hashes verwendbar se<strong>in</strong> soll.<br />

38.2. Hashtabelle:<br />

In der Hashtabelle bef<strong>in</strong>den sich die e<strong>in</strong>deutigen Adressen. E<strong>in</strong>e Suchanfrage wird<br />

zunächst mit Hilfe der Hash-Funktion <strong>in</strong> <strong>e<strong>in</strong>e</strong> Tabellenadresse umgewandelt. Mit dieser<br />

e<strong>in</strong>deutigen Adresse wird der Datensatz <strong>in</strong> der Hash-Tabelle gesucht. In der Praxis wird die<br />

Tabelle <strong>in</strong> <strong>e<strong>in</strong>e</strong>m Feld implementiert. Die Hashtabelle wird dynamisch erzeugt, damit sie<br />

vielseitig verwendbar <strong>ist</strong>. Die Länge des Feldes muss für die Hash <strong>–</strong> Funktion gespeichert<br />

werden. Aus praktischen Gründen sollte die Feldlänge <strong>e<strong>in</strong>e</strong> Primzahl se<strong>in</strong>. E<strong>in</strong>e spätere<br />

Änderung der Feldlänge hat nicht triviale Folgen. neue Indizes werden anders<br />

berechnet alte E<strong>in</strong>träge s<strong>in</strong>d nicht mehr auff<strong>in</strong>dbar.<br />

38.3. Kollisionsbeseitigung:<br />

Da Hash-Funktionen im Allgem<strong>e<strong>in</strong>e</strong>n nicht e<strong>in</strong>deutig s<strong>in</strong>d, können unterschiedliche<br />

Schlüssel zum selben Hash-Wert, also zum selben Feld <strong>in</strong> der Tabelle führen. Dieses<br />

Ergebnis wird als Kollision bezeichnet. In diesem Fall muss die Tabelle mehrere Werte an<br />

der selben Stelle aufnehmen. E<strong>in</strong>e Möglichkeit zur Kollisionsbeseitigung <strong>ist</strong> es, Datensätze<br />

mit gleichem Index <strong>in</strong> L<strong>ist</strong>en zusammenzufassen. (getrennte Verkettung)<br />

39. Für welche Operationen <strong>ist</strong> e<strong>in</strong> Hash besonders gut geeignet?<br />

Wie groß sollte die Hashlänge gewählt werden?<br />

Hashes eignen sich besonders gut zum Suchen von Daten und somit zur Datenerhaltung. Die<br />

Qualität von Hashes hängt stark von der Hash-Funktion, der Feldlänge und den Schlüsseln der<br />

zu speichernden Daten ab. Sie speichern k<strong>e<strong>in</strong>e</strong> Reihenfolgen, Hierarchien oder sonstige<br />

Abhängigkeiten von Daten. Ist die Datenmenge bekannt, so sollte man die Hashlänge stets<br />

größer wählen.<br />

als Primzahl von Vorteil.<br />

40. Wie löscht man Elemente aus <strong>e<strong>in</strong>e</strong>m Hash?<br />

18


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

In der L<strong>ist</strong>e werden die Zeiger auf den Nachfolger des zu löschenden Elements gesetzt und<br />

anschließend wird der E<strong>in</strong>trag als ungültig markiert.<br />

4<strong>1.</strong> <strong>Was</strong> wird aus dem Hash, wenn man bei getrennter Verknüpfung<br />

Hashlänge 1 wählt.<br />

Verkettete L<strong>ist</strong>e<br />

42. Erklärung dynamische Speicherverwaltung <strong>in</strong> C<br />

Die Speicherverwaltung <strong>ist</strong> der untersten Ebene im Aufbau <strong>e<strong>in</strong>e</strong>s Programmes zuzuordnen.<br />

Dabei wird der vergebene Speicher <strong>in</strong> geeigneten Datenstrukturen erfasst und verwaltet. Aus<br />

<strong>e<strong>in</strong>e</strong>m Programm wird Speicher <strong>e<strong>in</strong>e</strong>r bestimmten Größe angefordert, im Programm<br />

verwendet und nach dem Gebrauch wieder retourniert. Das Betriebssystem rundet die<br />

angeforderte Speichergröße auf durch 8 teilbare Längen auf, um Zerstückeln des Speichers <strong>in</strong><br />

viele kl<strong>e<strong>in</strong>e</strong> Blöcke zu verh<strong>in</strong>dern.<br />

43. Welche Funktionen werden <strong>in</strong> C angeboten und wie<br />

funktionieren sie?<br />

43.<strong>1.</strong> malloc():<br />

Mit der Funktion malloc() <strong>ist</strong> es möglich Speicher anzufordern. Als e<strong>in</strong>ziger Parameter<br />

muss die benötigte Speichergröße <strong>in</strong> Byte angegeben werden. Um die benötigte<br />

Speichergröße herauszuf<strong>in</strong>den wird die Funktion sizeof() verwendet. Wird dieser<br />

Funktion e<strong>in</strong> Datentyp übergeben, so liefert sie dessen Speicherplatzbe<strong>darf</strong> <strong>in</strong> Byte.<br />

sizeof(long) liefert 4Byte (32Bit), ebenso kann mit jedem anderen Datentyp<br />

vorgegangen werden, auch mit selbst def<strong>in</strong>ierten Datentypen und Strukturen.<br />

Werden zum Beispiel 4 Speicherplätze vom Datentyp long benötigt, so muss der Funktion<br />

malloc() folgendes übergeben werden:<br />

4*sizeof(long)<br />

ptr= malloc(4*sizeof(long));<br />

Die Funktion malloc() liefert bei erfolgreicher Speicherplatzreservierung <strong>e<strong>in</strong>e</strong>n Po<strong>in</strong>ter<br />

auf die Adresse des ersten Speicherplatzes. Werden mehrere Speicherplätze desselben<br />

Typs reserviert, so wird auch immer nur der Zeiger auf den ersten geliefert. Die weiteren<br />

reservierten Plätze haben <strong>e<strong>in</strong>e</strong> um 1 höhere Adresse als der vorhergehende. Konnte der<br />

angeforderte Speicherplatz nicht reserviert werden, so liefert die Funktion „0“. Der<br />

Po<strong>in</strong>ter <strong>ist</strong> also ungültig.<br />

43.2. calloc():<br />

Die Funktion calloc() funktioniert genau gleich wie die Funktion malloc(). Der<br />

e<strong>in</strong>zige Unterschied <strong>ist</strong> der, dass sie anstatt <strong>e<strong>in</strong>e</strong>m Argument zwei erwartet. Sie erwartet<br />

die Argumente:<br />

19


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Anzahl der Speicherplätze<br />

Größe <strong>e<strong>in</strong>e</strong>s Speicherplatzes.<br />

ptr=calloc(4, sizeof(long));<br />

Auch diese Funktion liefert bei erfolgreicher Reservierung den Zeiger auf den ersten<br />

Speicherplatz. Bei nicht erfolgreicher Reservierung liefert sie „0“.<br />

43.3. realloc():<br />

Mit dieser Funktion können Speicherplätze nicht nur erzeugt werden, sondern auch <strong>in</strong><br />

ihrer Größe verändert werden. Sie erwartet daher 2 Argumente:<br />

den alten Speicherblock<br />

die neue Größe des gesamten Speicherblockes.<br />

ptr=calloc(4, sizeof(long));<br />

ptrneu=realloc(ptr, 8*sizeof(long));<br />

Schlägt der Aufruf fehl, so liefert auch diese Funktion „0“. Des Weiteren <strong>ist</strong> nicht<br />

gewährle<strong>ist</strong>et, dass der Speicherplatz nach dem Verändern der Größe noch an derselben<br />

Adresse wie vor der Reallozierung steht. Die Verwendung dieser Funktion <strong>ist</strong> daher oft<br />

Problematisch. Zeigt e<strong>in</strong> Zeiger auf <strong>e<strong>in</strong>e</strong>n Speicher der von realloc() verändert wird,<br />

kann es zu Fehlern kommen, da dieser Zeiger bei Verschiebung des Speichers ungültig<br />

wird.<br />

43.4. free():<br />

Wird e<strong>in</strong> dynamischer Speicher nicht mehr benötigt oder das Programm beendet, so sollte<br />

dieser wieder freigegeben werden. Hierfür gibt es <strong>in</strong> C die Funktion free(). Auf <strong>e<strong>in</strong>e</strong>n<br />

Speicher, der bereits freigegeben wurde, <strong>darf</strong> nicht mehr zugegriffen werden. Außerdem<br />

<strong>darf</strong> e<strong>in</strong> bereits freigegebener Speicher ke<strong>in</strong> zweites Mal freigegeben werden, da es<br />

dadurch zu Programmabstürzten kommen kann.<br />

Nach dem Freigeben <strong>e<strong>in</strong>e</strong>s Speichers sollte der Zeiger auf den Speicher ungültig gemacht<br />

werden, <strong>in</strong>dem er auf „0“ gesetzt wird.<br />

if(ptr)<br />

{<br />

free(ptr);<br />

ptr = 0;<br />

}<br />

Wird die Funktion free() auf <strong>e<strong>in</strong>e</strong>n ungültigen Zeiger angewandt, so ergibt das k<strong>e<strong>in</strong>e</strong>n<br />

Fehler sondern wird ignoriert.<br />

Um mit diesen allozierten Speichern arbeiten zu können sollte <strong>e<strong>in</strong>e</strong> Abfrage gemacht werden,<br />

ob die Speicherallozierung erfolgreich war.<br />

z.B.:<br />

if(ptr=calloc(4, sizeof(long)))<br />

20


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

{<br />

}<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

//Verwendung des Speichers<br />

44. <strong>Was</strong> s<strong>in</strong>d Memory - Leaks?<br />

Memory <strong>–</strong> Leaks entstehen, wenn e<strong>in</strong> Programm dynamisch Speicher alloziert und diese<br />

Speicherressourcen nicht mehr an das System zurückgibt. Durch diese Memory <strong>–</strong> Leaks wird<br />

der Speicher immer ger<strong>in</strong>ger und es kann zu langsameren Reaktionen von Programmen und<br />

vom Betriebssystem kommen.<br />

Memory <strong>–</strong> Leaks können durch folgende Fehler auftreten:<br />

Verlust <strong>e<strong>in</strong>e</strong>s Zeigers auf <strong>e<strong>in</strong>e</strong>n Speicher, weil dieser Zeiger überschrieben wurde<br />

Verlust des Speichers durch Verlust des Zeigers<br />

Verlust des Zeigers durch Rücksprung<br />

Verlust des Zeigers bei der Rückgabe von Funktionen<br />

45. Welche Fehlerarten gibt es (Numerik)?<br />

45.<strong>1.</strong> Modellfehler:<br />

Bei jeder Modellbildung wird <strong>e<strong>in</strong>e</strong> Abstraktion der Realität durchgeführt, dabei werden<br />

bekannte und unbekannte Größen vernachlässigt und Vere<strong>in</strong>fachungen der tatsächlichen<br />

Verhältnisse vorgenommen. Der Fehler, der dadurch entsteht, wird Modellfehler genannt.<br />

Der Beitrag dieses Fehlers zum Gesamtfehler kann aufgrund der Vernachlässigung<br />

unbekannter Größen nicht abgeschätzt werden. Es kann lediglich der Fehler der<br />

vernachlässigten bekannten Größen abgeschätzt werden.<br />

45.2. Datenfehler:<br />

Datenfehler entstehen durch Ungenauigkeiten bei der Erfassung von Daten, da diese nur<br />

bis zu <strong>e<strong>in</strong>e</strong>r gewissen Genauigkeit erfasst werden können. Der dadurch entstehende<br />

Fehler lässt sich me<strong>ist</strong> abschätzten. Dies <strong>ist</strong> jedoch von der Messmethode abhängig (z.B.:<br />

bei Längen, Geschw<strong>in</strong>digkeiten,…). Die Auswirkung dieser Fehler können mittels<br />

Konditionsuntersuchungen abgeschätzt werden.<br />

45.3. Verfahrensfehler:<br />

Mathematische Probleme werden oftmals mit iterativen Näherungsverfahren<br />

durchgeführt, welche sich an die Lösung herantasten. Ist die Lösung h<strong>in</strong>reichend genau, so<br />

wird das Verfahren abgebrochen und es entsteht der Abbruchfehler.<br />

Diskretisierungsfehler entstehen bei <strong>e<strong>in</strong>e</strong>m Übergang von <strong>e<strong>in</strong>e</strong>m kont<strong>in</strong>uierlichen auf e<strong>in</strong><br />

diskretes System. E<strong>in</strong> Intergral wird beispielsweise numerisch durch Summation<br />

durchgeführt. Hierbei entsteht gegenüber der tatsächlichen Lösung des Integrals e<strong>in</strong><br />

Fehler.<br />

21


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Verfahrensfehler lassen sich durch erhöhten Aufwand oft beliebig verkl<strong>e<strong>in</strong>e</strong>rn, da aber<br />

jedes Verfahren nach <strong>e<strong>in</strong>e</strong>r bestimmten Zeit abgebrochen werden muss entstehen immer<br />

Abbruchfehler. Dieser <strong>ist</strong> im günstigsten Fall die Darstellungsgenauigkeit des <strong>in</strong>ternen<br />

Datentyps.<br />

45.4. Rundungsfehler:<br />

Punktzahlen können auf <strong>e<strong>in</strong>e</strong>m Computer bis zu <strong>e<strong>in</strong>e</strong>r bestimmten Genauigkeit dargestellt<br />

werden. Diese Genauigkeit <strong>ist</strong> vom Datentyp abhängig. Bei jeder Rechenoperation wird<br />

das Ergebnis auf <strong>e<strong>in</strong>e</strong>n darstellbaren Wert abgebildet <strong>–</strong> gerundet. Der Unterschied<br />

zwischen dem exakten Wert und dem gerundetem Wert <strong>ist</strong> der Rundungsfehler oder<br />

Rechenfehler.<br />

46. Wie kann der relative Fehler berechnet werden?<br />

Der absolute Fehler ergibt sich zu:<br />

Der relative Fehler <strong>e<strong>in</strong>e</strong>r numerischen Berechnung ergibt sich aus:<br />

Die Bezugsgröße <strong>ist</strong> me<strong>ist</strong> der exakte Wert. Man erhält folgende Gleichung:<br />

47. <strong>Was</strong> sagt die Konditionszahl aus? <strong>Was</strong> <strong>ist</strong> die ideale<br />

Konditionszahl?<br />

Die Konditionszahl gibt Auskunft über die Empf<strong>in</strong>dlichkeit <strong>e<strong>in</strong>e</strong>s Systems auf Änderungen<br />

der E<strong>in</strong>gangsdaten.<br />

E<strong>in</strong> System mit kl<strong>e<strong>in</strong>e</strong>r Konditionszahl <strong>ist</strong> Änderungen gegenüber unempf<strong>in</strong>dlicher als e<strong>in</strong><br />

System mit großer Konditionszahl.<br />

Die ideale Konditionszahl <strong>ist</strong>:<br />

48. <strong>Was</strong> <strong>ist</strong> die kle<strong>in</strong>ste mögliche Zahl?<br />

Die <strong>Header</strong>-<strong>Datei</strong> limits.h gibt Auskunft über Grenzen ganzzahliger Zahlentypen. Diese<br />

Grenzen s<strong>in</strong>d <strong>in</strong> Konstanten gespeichert:<br />

22<br />

Blauenst<strong>e<strong>in</strong>e</strong>r


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

LONG_MAX: größte positive Zahl<br />

LONG_MIN: kle<strong>in</strong>ste negative Zahl<br />

Die <strong>Header</strong>-<strong>Datei</strong> float.h gibt die Schranken für die Datentypen float, double und long<br />

double an:<br />

DBL_MAX: größte positive Zahl<br />

DBL_MIN: kle<strong>in</strong>ste(normalisierte) positive Zahl >0<br />

DBL_EPSILON: Differenz zwischen 1 und der kle<strong>in</strong>sten Zahl größer als 1<br />

Die kle<strong>in</strong>ste denormalisierte Zahl ergibt sich mit:<br />

Normalisiert heißt, dass <strong>e<strong>in</strong>e</strong> 1 direkt h<strong>in</strong>ter dem Komma steht.<br />

49. <strong>Was</strong> passiert bei der Summation von 2 Doubles? Welche Fehler<br />

können dabei auftreten?<br />

Bei der Summation von zwei Punktzahlen werden die beiden Mantissen addiert. Hierfür<br />

müssen allerd<strong>in</strong>gs die Exponenten gleich se<strong>in</strong>. Ist die Zahl um den Faktor größer, so wird<br />

0 addiert. In der Computerarithmetik gilt weder das Assoziativgesetz noch das<br />

D<strong>ist</strong>ributivgesetz. Der Exponent der kl<strong>e<strong>in</strong>e</strong>ren Zahl wird auf den Exponenten der größeren<br />

gebracht. Dabei wird die Mantisse nach rechts verschoben, wobei gesetzte Bits rechts<br />

herausfallen können Datenverlust.<br />

E<strong>in</strong> häufiger Fehler bei der Summation von Punktzahlen <strong>ist</strong> der Auslöschungseffekt. Dieser<br />

tritt auf, wenn zwei annähernd gleich große Zahlenwerte addiert oder subtrahiert werden.<br />

Unterscheiden sich zwei Werte fast ausschließlich durch ihre nicht signifikanten Stellen, so<br />

fallen bei <strong>e<strong>in</strong>e</strong>r Subtraktion hauptsächlich die signifikanten Stellen weg. Es bleiben nur die<br />

nicht aussagekräftigen Stellen übrig. Diese Störungen an den h<strong>in</strong>teren Stellen der Werte<br />

werden zu Störungen an vorderen Stellen des Ergebnisses. Daher <strong>ist</strong> der relative Fehler sehr<br />

hoch.<br />

Auslöschung <strong>ist</strong> die häufigste Ursache für schlechte Kondition und die numerische Instabilität<br />

von Algorithmen.<br />

50. Welche Fehlerarten gibt es? (Fehlerbehandlung)<br />

50.<strong>1.</strong> Modellfehler:<br />

Modellfehler können nur behandelt werden, wenn sie auch erkannt werden können. Sie<br />

entstehen oftmals auch durch bewusste Vernachlässigungen.<br />

50.2. Datenfehler:<br />

23


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Datenfehler s<strong>in</strong>d die häufigste Ursache für <strong>e<strong>in</strong>e</strong> Fehlerbehandlung. Dazu zählen<br />

beispielsweise Messungenauigkeiten, syntaktisch Falsche oder unvollständige<br />

E<strong>in</strong>gabedaten oder fehlerhafte <strong>Datei</strong>formate.<br />

50.3. Verletzte Vorbed<strong>in</strong>gung:<br />

Diese Fehlerart zählt eigentlich zu den Datenfehlern. Die Korrektheit der Daten bezieht<br />

sich auf <strong>e<strong>in</strong>e</strong>n bestimmten Algorithmus. Die Daten können anhand <strong>e<strong>in</strong>e</strong>r def<strong>in</strong>ierten<br />

Bed<strong>in</strong>gung (Vorbed<strong>in</strong>gung) auf Korrektheit überprüft werden.<br />

50.4. Anwenderfehler:<br />

Anwenderfehler entstehen durch fehlerhafte Bedienung sowie fehlende oder <strong>in</strong>korrekte<br />

E<strong>in</strong>gaben. Sie gehören auch zu den Datenfehlern und erfordern bei der Behandlung oft<br />

besondere Richtl<strong>in</strong>ien für die Benutzerführung.<br />

50.5. Fehlerhafter Programmaufruf:<br />

Dies <strong>ist</strong> e<strong>in</strong> Fehler, welcher beim Programmaufruf passiert und dadurch eigentlich e<strong>in</strong><br />

Anwenderfehler <strong>ist</strong>. E<strong>in</strong> fehlerhafter Programmaufruf kann zu <strong>e<strong>in</strong>e</strong>m sofortigen Abbruch<br />

des Programms führen.<br />

50.6. Numerische Fehler:<br />

Numerische Methoden liefern nur mit <strong>e<strong>in</strong>e</strong>r Fehlerabschätzung <strong>e<strong>in</strong>e</strong> s<strong>in</strong>nvolle<br />

Auswertung. Es <strong>ist</strong> notwendig bei der Implementierung auf die numerische Stabilität des<br />

Verfahrens zu achten.<br />

50.7. Speicherprobleme:<br />

Speichermangel <strong>ist</strong> e<strong>in</strong> leicht zu erkennendes Problem, welches oftmals nur sehr schwer<br />

korrigiert werden kann. Es kann dazu führen das der Algorithmus nicht mehr ausgeführt<br />

werden kann.<br />

Abhilfe:<br />

Neu starten des Programms<br />

Das Programm wartet bis der Speicher wieder verfügbar <strong>ist</strong><br />

Nicht mehr benötigter Speicher wird freigegeben, wenn möglich.<br />

50.8. Fehlerhafter Speicherzugriff:<br />

Dies <strong>ist</strong> e<strong>in</strong> sehr kritischer Fehler, der entweder zum sofortigen Programmabbruch oder<br />

zum lesen falscher Daten und überschreiben von Daten, die nicht zum Programm<br />

gehören, führt.<br />

Abhilfe: Signalbehandlung<br />

50.9. Fehlerhafte Module:<br />

Bei der Softwareentwicklung wird sehr oft Fremd-Software verwendet. Dazu gehören<br />

auch Bibliotheken und Module, aber auch das Betriebssystem. Diese Fremd <strong>–</strong> Software<br />

kann auch Fehler enthalten.<br />

24


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

50.10. Dead <strong>–</strong> Lock:<br />

Bei parallelen Prozessen kann es vorkommen, dass e<strong>in</strong> Prozess auf Daten des anderen<br />

wartet und es daher zu <strong>e<strong>in</strong>e</strong>m Stoppen des Programmes kommt. Dieser Fehler kann<br />

während der Programmlaufzeit kaum behoben werden, da die Prozesse gestoppt s<strong>in</strong>d.<br />

Am e<strong>in</strong>fachsten <strong>ist</strong> es <strong>e<strong>in</strong>e</strong> gewisse Zeit zu warten, dass der Programmablauf von selbst<br />

wieder beg<strong>in</strong>nt.<br />

5<strong>1.</strong> Welche Möglichkeiten bietet C zur Fehlerbehandlung und wie<br />

funktionieren diese?<br />

Verschiedene Programmiersprachen bieten verschiedene Möglichkeiten zur<br />

Fehlerbehandlung. In C++ gibt es beispielsweise „Ausnahmen“ (exceptions). In C haben sich<br />

die sogenannten Fehlercodes durchgesetzt. Es <strong>ist</strong> empfehlenswert Fehlercodes mit<br />

Aufzählungstypen (enum) zu realisieren.<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Der Präfix ERR deutet darauf h<strong>in</strong>, dass es sich um <strong>e<strong>in</strong>e</strong>n Fehler handelt.<br />

Des Weiteren bietet die Standardbibliothek <strong>in</strong> C e<strong>in</strong>ige Möglichkeiten zur Fehlererkennung<br />

und Fehlerbehandlung an.<br />

Die Fehlervariable errno <strong>ist</strong> vom Typ <strong>in</strong>t und <strong>ist</strong> <strong>in</strong> der Standard-<strong>Header</strong>datei errno.h<br />

deklariert. Sie gibt viele Fehler von Betriebssystemen und C-Standardbibliotheksfunktionen<br />

durch <strong>e<strong>in</strong>e</strong>n Fehlercode bekannt. Beim Programmstart wird diese Variable auf 0 gesetzt und<br />

nur im Fehlerfall von Betriebssystem- und Bibliotheksfunktionen auf den Fehlercode gesetzt.<br />

errno kann dann wie jede andere Variable abgefragt und ausgewertet werden.<br />

Beispielsweise kann errno auf ENOET gesetzt werden. Dies <strong>ist</strong> <strong>e<strong>in</strong>e</strong> Präprozessorkonstante.<br />

52. <strong>Was</strong> macht die Funktion exit() und wie wird sie verwendet?<br />

Diese Funktion <strong>ist</strong> Hilfreich für Testphase <strong>in</strong> der Programmentwicklung. Wird die Funktion<br />

exit() aufgerufen, wird das Programm sofort beendet, egal wo sich das Programm gerade<br />

bef<strong>in</strong>det. Die Funktion <strong>ist</strong> der <strong>Header</strong>datei stdlib.h deklariert und erwartet als e<strong>in</strong>zigen<br />

Parameter <strong>e<strong>in</strong>e</strong>n Fehlerwert. Der Funktionsaufruf erfolgt durch:<br />

exit(-1);<br />

53. <strong>Was</strong> macht die Funktion atexit() und wie wird sie verwendet?<br />

25


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Mit der Funktion atexit() können mehrere Funktionen reg<strong>ist</strong>riert werden, die beim<br />

regulären Programmende aufgerufen werden. E<strong>in</strong> Programmende <strong>ist</strong> regulär, wenn aus der<br />

Funktion ma<strong>in</strong>() zurückgesprungen wird oder wenn exit(-1) aufgerufen wird. Diese<br />

Funktion <strong>ist</strong> genau auch wie exit() <strong>in</strong> der <strong>Header</strong>datei stdlib.h deklariert. S<strong>in</strong>d<br />

mehrere Funktion reg<strong>ist</strong>riert, so werden diese <strong>in</strong> umgekehrter Reihenfolge ihrer<br />

Reg<strong>ist</strong>rierung aufgerufen. Als Parameter wird e<strong>in</strong> Zeiger auf <strong>e<strong>in</strong>e</strong> Funktion erwartet.<br />

atexit(&endfunction);<br />

exit(-1); //Die Funktion endfunction wird hier aufgerufen.<br />

54. Erklärung der Funktion abort():<br />

Die Funktion abort() beendet das Programm nicht wie exit() regulär, sondern durch<br />

<strong>e<strong>in</strong>e</strong>n Abbruch <strong>–</strong> also e<strong>in</strong> außergewöhnliches Programmende. Dabei wird das Signal<br />

SIGABRT an den Prozessor gesendet, wodurch die Signalbehandlung für das Signal<br />

ausgelöst wird. Diese vore<strong>in</strong>gestellte Signalbehandlung bricht das Programm ab. abort()<br />

<strong>ist</strong> <strong>in</strong> der <strong>Header</strong>datei stdlib.h deklariert und hat k<strong>e<strong>in</strong>e</strong> Argumente.<br />

55. <strong>Was</strong> macht die Funktion assert() und wie wird sie verwendet?<br />

Assert <strong>ist</strong> genaugenommen e<strong>in</strong> Präprozessormakro und <strong>ist</strong> <strong>in</strong> der <strong>Header</strong>datei assert.h<br />

deklariert. Assert erwartet <strong>e<strong>in</strong>e</strong>n Parameter, <strong>ist</strong> dieser Parameter gleich 0, so gibt assert()<br />

<strong>e<strong>in</strong>e</strong> Fehlermeldung aus und beendet das Programm durch den Aufruf der Funktion abort().<br />

datei =fopen(„bsp.txt“);<br />

assert(datei);<br />

Diese Funktion wird gerne <strong>in</strong> der Entwicklungsphase <strong>e<strong>in</strong>e</strong>s Programms zur Kontrolle des<br />

Zustandes <strong>e<strong>in</strong>e</strong>r Variablen verwendet. Der übergebene Ausdruck wird auf 0 abgefragt!<br />

56. <strong>Was</strong> s<strong>in</strong>d Signale und wo kommen sie her?<br />

Signale s<strong>in</strong>d nicht vorhersehbare Ereignisse, welche zu nicht vorhersehbaren Zeitpunkten<br />

auftreten können. Es s<strong>in</strong>d also asynchrone Ereignisse. E<strong>in</strong> Signal kann vom Betriebssystem,<br />

von externen Interrupts, von anderen Programmen oder E<strong>in</strong>gabegeräten <strong>in</strong>itiiert werden und<br />

an <strong>e<strong>in</strong>e</strong>n Prozess gesendet werden. In Programmen können diese Signale abgefangen und<br />

behandelt werden.<br />

57. Wie Funktioniert <strong>in</strong> C die Signalbehandlung?<br />

In C enthält die <strong>Header</strong>datei signal.h <strong>e<strong>in</strong>e</strong> vollständige L<strong>ist</strong>e aller vorhandenen Signale.<br />

Empfängt e<strong>in</strong> Prozess e<strong>in</strong> Signal, wird der Programmablauf unterbrochen und <strong>e<strong>in</strong>e</strong> Funktion<br />

zur Signalbehandlung aufgerufen. Diese Funktionen nennt man s<strong>in</strong>galhandler.<br />

26


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

Die Funktion signal() <strong>ist</strong> <strong>in</strong> der <strong>Header</strong>datei signal.h deklariert und erwartet zwei<br />

Parameter. Der erste Parameter <strong>ist</strong> die Signalnummer und der zweite Parameter e<strong>in</strong> Zeiger<br />

auf die Funktion zur Signalbehandlung. Diese Funktion zur Signalbehandlung hat <strong>e<strong>in</strong>e</strong>n <strong>in</strong>t <strong>–</strong><br />

Parameter, die Signalnummer und hat k<strong>e<strong>in</strong>e</strong>n Rückgabewert.<br />

58. Welche Signale kennen Sie?<br />

Signal Bedeutung<br />

SIGINT „<strong>in</strong>terrupt“ Wird beim Drücken der Tastenkomb<strong>in</strong>ation Strg+C an den Prozessor<br />

gesandt.<br />

SIGABRT „abort“ Wird von den Funktionen assert() und abort() verwendet.<br />

SIGTERM „term<strong>in</strong>ate“ Wird beispielsweise beim Herunterfahren des Systems gesandt.<br />

Behandlung <strong>ist</strong> empfohlen.<br />

SIGILL „illegal <strong>in</strong>struction“ Tritt auf wenn e<strong>in</strong> illegaler Masch<strong>in</strong>enbefehl geladen wird.<br />

SIGFPE „float<strong>in</strong>g po<strong>in</strong>t exception“ Tritt bei ungültigen arithmetischen Operationen auf.<br />

Z.B.: Division durch 0.<br />

SIGSEGV „segmentation violation“ Wird vom Prozessor gesendet, wenn versucht wird auf<br />

<strong>e<strong>in</strong>e</strong>n Speicherbereich zuzugreifen, der nicht zum Prozessor gehört oder wenn<br />

<strong>e<strong>in</strong>e</strong> illegale Speicheradresse auftritt.<br />

59. Statische und dynamische Felder:<br />

60. Wie f<strong>in</strong>det man die Nullstelle <strong>e<strong>in</strong>e</strong>r Funktion?<br />

Als erstes setzt man <strong>e<strong>in</strong>e</strong> obere und unter Grenze. Ist <strong>e<strong>in</strong>e</strong> Grenze positiv und <strong>e<strong>in</strong>e</strong> negativ, so<br />

bef<strong>in</strong>det sich die Nullstelle noch im Bereich. Dann wird der Bereich halbiert. Ist wiederum<br />

<strong>e<strong>in</strong>e</strong> Grenze positiv und <strong>e<strong>in</strong>e</strong> negativ, so liegt die Nullstelle immer noch im Bereich. S<strong>in</strong>d<br />

beide Grenzen positiv oder negativ, so liegt der Bereich <strong>in</strong> dem gesucht wird oberhalb oder<br />

unterhalb der Nullstelle. Dieses Verfahren wird solange wiederholt, bis die Annäherung an<br />

die Nullstelle ausreichend genau <strong>ist</strong>.<br />

6<strong>1.</strong> Wie kann man <strong>in</strong> C numerisch <strong>in</strong>tegrieren?<br />

Das Integral <strong>e<strong>in</strong>e</strong>r (stückweise stetigen und beschränkten) Funktion kann als Summe von<br />

Teil<strong>in</strong>tegralen berechnet werden. Die e<strong>in</strong>zelnen Summanden entsprechen jeweils der<br />

Integration über Teil<strong>in</strong>tervalle. Es gibt verschiedene Methoden das Integral über diese<br />

Teil<strong>in</strong>tervalle anzunähern.<br />

E<strong>in</strong>e relativ e<strong>in</strong>fache und anschauliche Methode <strong>ist</strong> die Trapezmethode, welche die Fläche<br />

unter der Funktionskurve durch Trapeze approximiert.<br />

27<br />

( ( ) ( ))<br />

E<strong>in</strong>e Methode um die Fläche unter der Kurve genauer zu approximieren <strong>ist</strong> die<br />

Simpsonmethode:


Fragenkatalog Programmieren 2 Stand: Februar 2013<br />

Blauenst<strong>e<strong>in</strong>e</strong>r<br />

( ( ) (<br />

Außerdem gibt es noch die Newtonmethode:<br />

Referenzbeispiel 4!<br />

( ( ) (<br />

28<br />

) (<br />

) ( ))<br />

) ( ))

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

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!