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 ...
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 />
) ( ))