Skip to content
Snippets Groups Projects
Commit cbdaa0ad authored by Peter Gerwinski's avatar Peter Gerwinski
Browse files

Beispiel-Programme und Musterlösung 23.1.2020

parent c255da4d
Branches
No related tags found
No related merge requests found
Showing
with 595 additions and 7 deletions
cassini/home/peter/bo/2019ws/hp/20200123> ./stack-6
stack overflow
cassini/home/peter/bo/2019ws/hp/20200123> ./stack-6 2>/dev/null
cassini/home/peter/bo/2019ws/hp/20200123> ./stack-6 >/dev/null
stack overflow
cassini/home/peter/bo/2019ws/hp/20200123> ./stack-5
137
7
3
cassini/home/peter/bo/2019ws/hp/20200123> ./stack-5 2>/dev/null
137
7
3
cassini/home/peter/bo/2019ws/hp/20200123> ./stack-5 >/dev/null
cassini/home/peter/bo/2019ws/hp/20200123>
#include <stdio.h>
#define FIFO_SIZE 10
int fifo[FIFO_SIZE];
int fifo_pointer = 0;
void push (int x)
{
fifo[fifo_pointer++] = x;
}
int pop (void)
{
return fifo[0];
fifo[0] = fifo[1];
fifo[1] = fifo[2];
fifo[2] = fifo[3];
/* ... */
}
int main (void)
{
push (3);
push (7);
push (137);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
printf ("%d\n", pop ());
return 0;
}
#include <stdio.h>
#define FIFO_SIZE 10
int fifo[FIFO_SIZE];
int fifo_pointer = 0;
void push (int x)
{
fifo[fifo_pointer++] = x;
}
int pop (void)
{
fifo[0] = fifo[1];
fifo[1] = fifo[2];
fifo[2] = fifo[3];
/* ... */
return fifo[0];
}
int main (void)
{
push (3);
push (7);
push (137);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
printf ("%d\n", pop ());
return 0;
}
#include <stdio.h>
#define FIFO_SIZE 10
int fifo[FIFO_SIZE];
int fifo_pointer = 0;
void push (int x)
{
fifo[fifo_pointer++] = x;
}
int pop (void)
{
int result = fifo[0];
fifo[0] = fifo[1];
fifo[1] = fifo[2];
fifo[2] = fifo[3];
/* ... */
return result;
}
int main (void)
{
push (3);
push (7);
push (137);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
printf ("%d\n", pop ());
return 0;
}
#include <stdio.h>
#define FIFO_SIZE 10
int fifo[FIFO_SIZE];
int fifo_pointer = 0;
void push (int x)
{
fifo[fifo_pointer++] = x;
}
int pop (void)
{
int result = fifo[0];
for (int i = 1; i < FIFO_SIZE; i++)
fifo[i - 1] = fifo[i];
return result;
}
int main (void)
{
push (3);
push (7);
push (137);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
printf ("%d\n", pop ());
return 0;
}
#include <stdio.h>
#define FIFO_SIZE 10
int fifo[FIFO_SIZE];
int fifo_pointer = 0;
void push (int x)
{
fifo[fifo_pointer++] = x;
}
int pop (void)
{
int result = fifo[0];
for (int i = 1; i < FIFO_SIZE; i++)
fifo[i - 1] = fifo[i];
return result;
}
int main (void)
{
push (3);
push (7);
push (137);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
printf ("%d\n", pop ());
push (42);
printf ("%d\n", pop ());
return 0;
}
#include <stdio.h>
#define FIFO_SIZE 10
int fifo[FIFO_SIZE];
int fifo_pointer = 0;
void push (int x)
{
fifo[fifo_pointer++] = x;
}
int pop (void)
{
int result = fifo[0];
for (int i = 1; i < FIFO_SIZE; i++)
fifo[i - 1] = fifo[i];
fifo_pointer--;
return result;
}
int main (void)
{
push (3);
push (7);
push (137);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
printf ("%d\n", pop ());
push (42);
printf ("%d\n", pop ());
return 0;
}
#include <stdio.h>
#define FIFO_SIZE 10
int fifo[FIFO_SIZE];
int fifo_write_pointer = 0;
int fifo_read_pointer = 0;
void push (int x)
{
fifo[fifo_write_pointer++] = x;
if (fifo_write_pointer >= FIFO_SIZE)
fifo_write_pointer = 0;
}
int pop (void)
{
int result = fifo[fifo_read_pointer++];
if (fifo_read_pointer >= FIFO_SIZE)
fifo_read_pointer = 0;
return result;
}
int main (void)
{
push (3);
push (7);
push (137);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
printf ("%d\n", pop ());
push (42);
printf ("%d\n", pop ());
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define FIFO_SIZE 10
int fifo[FIFO_SIZE];
int fifo_write_pointer = 0;
int fifo_read_pointer = 0;
void push (int x)
{
fifo[fifo_write_pointer++] = x;
if (fifo_write_pointer >= FIFO_SIZE)
fifo_write_pointer = 0;
if (fifo_write_pointer == fifo_read_pointer)
{
fprintf (stderr, "fifo overflow\n");
exit (1);
}
}
int pop (void)
{
if (fifo_read_pointer == fifo_write_pointer)
{
fprintf (stderr, "fifo underflow\n");
exit (1);
}
else
{
int result = fifo[fifo_read_pointer++];
if (fifo_read_pointer >= FIFO_SIZE)
fifo_read_pointer = 0;
return result;
}
}
int main (void)
{
push (3);
push (7);
push (137);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
printf ("%d\n", pop ());
push (42);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define FIFO_SIZE 10
int fifo[FIFO_SIZE];
int fifo_write_pointer = 0;
int fifo_read_pointer = 0;
void push (int x)
{
int old_fifo_write_pointer = fifo_write_pointer;
fifo_write_pointer++;
if (fifo_write_pointer >= FIFO_SIZE)
fifo_write_pointer = 0;
if (fifo_write_pointer == fifo_read_pointer)
{
fprintf (stderr, "fifo overflow\n");
exit (1);
}
else
fifo[old_fifo_write_pointer] = x;
}
int pop (void)
{
if (fifo_read_pointer == fifo_write_pointer)
{
fprintf (stderr, "fifo underflow\n");
exit (1);
}
else
{
int result = fifo[fifo_read_pointer++];
if (fifo_read_pointer >= FIFO_SIZE)
fifo_read_pointer = 0;
return result;
}
}
int main (void)
{
push (3);
push (7);
push (137);
for (int i = 0; i < 42; i++)
push (i);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
printf ("%d\n", pop ());
push (42);
printf ("%d\n", pop ());
printf ("%d\n", pop ());
return 0;
}
No preview for this file type
......@@ -349,7 +349,9 @@
\medskip
Die \textbf{Hinweise} auf der nächsten Seite beschreiben
Die \textbf{Hinweise} auf der nächsten Seite\footnote{Auf dem Übungszettel
befanden sich die Hinweise auf der nächsten Seite. In dieser Musterlösung
befinden sie sich direkt darunter.} beschreiben
einen möglichen Weg, die Aufgabe zu lösen.\\
Es seht Ihnen frei, die Aufgabe auch auf andere Weise zu lösen.
......@@ -370,9 +372,9 @@
Damit können Sie sich gleichzeitig von der Bedingung lösen,
daß die Länge des Arrays ein Vielfaches von 8 sein muß.
\item
Gehen Sie nun von einem statichen zu einem dynamischen Array über,
Gehen Sie nun von einem statischen zu einem dynamischen Array über,
und implementieren sie die Funktionen \lstinline{bit_array_init()},
\lstinline{bit_array_done()} und \lstinline{bit_array_reseize()}.
\lstinline{bit_array_done()} und \lstinline{bit_array_resize()}.
\end{itemize}
\points{14}
......@@ -384,10 +386,102 @@
\solution
(wird nachgereicht)
Die hier vorgestellte Lösung folgt den Hinweisen.
\begin{itemize}
\item
\textbf{Setzen Sie zunächst voraus, daß das Array die konstante Länge 8 hat,
und schreiben Sie zunächst nur die Funktionen
\lstinline{bit_array_set()}, \lstinline{bit_array_flip()} und
\lstinline{bit_array_get()}.}
Siehe: \gitfile{hp}{20200123}{loesung-3-1.c}
Wir speichern in jedem der acht Bit einer \lstinline{uint8_t}-Variablen
jeweils eine Zahl, die 0 oder 1 sein kann.
Dies geschieht durch Setzen bzw.\ Löschen bzw.\ Umklappen einzelner Bits
in der Variablen.
Das Programm enthält zusätzlich eine Funktion \lstinline{output()},
mit der man sich den Inhalt des Arrays anzeigen lassen kann,
sowie ein Hauptprogramm \lstinline{main()}, um die Funktionen zu testen.
\item
\textbf{Verallgemeinern Sie nun auf eine konstante Länge,
bei der es sich um ein Vielfaches von 8 handelt.}
Siehe: \gitfile{hp}{20200123}{loesung-3-2.c}
In diesem Programm setzen wir die Länge auf konstant \lstinline{LENGTH} Bits,
wobei es sich um eine Präprozessor-Konstante mit dem Wert 32 handelt.
Um \lstinline{LENGTH} Bits zu speichern, benötigen wir ein Array
der Länge \lstinline{LENGTH / 8} Bytes.
Um auf ein einzelnes Bit zuzugreifen, müssen wir zunächst ermitteln,
in welchem der Bytes sich befindet. Außerdem interessieren wir uns
für die Nummer des Bits innerhalb des Bytes.
Den Array-Index des Bytes erhalten wir, indem wir den Index des Bits
durch 8 dividieren. Der bei dieser Division verbleibende Rest ist die
Nummer des Bits innerhalb des Bytes.
Diese Rechnungen führen wir in den drei Funktionen
\lstinline{bit_array_set()}, \lstinline{bit_array_flip()} und
\lstinline{bit_array_get()} durch.
(Diese ist eine eher unelegante Code-Verdopplung -- hier sogar eine Verdreifachung.
Für den Produktiveinsatz lohnt es sich, darüber nachzudenken,
wie man diese vermeiden kann, ohne gleichzeitig an Effizienz einzubüßen.
Hierfür käme z.\,B.\ ein Präprozessor-Makro in Frage.
Für die Lösung der Übungsaufgabe wird dies hingegen nicht verlangt.)
\item
\textbf{Implementieren Sie nun die Überprüfung auf unsinnige Parameterwerte.
Damit können Sie sich gleichzeitig von der Bedingung lösen,
daß die Länge des Arrays ein Vielfaches von 8 sein muß.}
Siehe: \gitfile{hp}{20200123}{loesung-3-3.c}
Um weitere Code-Verdopplungen zu vermeiden,
führen wir eine Funktion \lstinline{check_index()} ein,
die alle Prüfungen durchführt.
Wenn die Länge des Arrays kein Vielfaches von 8 ist,
wird das letzte Byte nicht vollständig genutzt.
Die einzige Schwierigkeit besteht darin, die korrekte Anzahl von Bytes
zu ermitteln, nämlich die Länge dividiert durch 8, aber nicht ab-, sondern
aufgerundet. Am elegantesten geht dies durch vorherige Addition von 7:
\lstinline{#define BYTES ((LENGTH + 7) / 8)}.
Es ist aber auch zulässig, die Anzahl der Bytes mit Hilfe einer
\lstinline{if}-Anweisung zu ermitteln: Länge durch 8 teilen und abrunden;
falls die Division nicht glatt aufging, um 1 erhöhen.
\item
\textbf{Gehen Sie nun von einem statischen zu einem dynamischen Array über,
und implementieren sie die Funktionen \lstinline{bit_array_init()},
\lstinline{bit_array_done()} und \lstinline{bit_array_resize()}.}
Siehe: \gitfile{hp}{20200123}{loesung-3-4.c}.
Damit ist die Aufgabe gelöst.
Aus den Präprozessor-Konstanten \lstinline{LENGTH} und \lstinline{BYTES}
werden nun globale \lstinline{int}-Variable.
Die Funktion \lstinline{bit_array_init()} berechnet die korrekten Werte
für diese Variablen und legt das Array mittels \lstinline{malloc()} dynamisch
an. Eine Größenänderung des Arrays erfolgt mittels \lstinline{realloc()},
das Freigeben mittels \lstinline{free()}.
Das Programm setzt Variable, die aktuell nicht verwendet werden,
auf den Wert \lstinline{0} bzw.\ \lstinline{NULL}.
Dies ermöglicht es der Funktion \lstinline{check_index()},
auch zu prüfen, ob das Array vorher korrekt mit \lstinline{bit_array_init()}
erzeugt wurde -- oder ob es vielleicht schon wieder mit
\lstinline{bit_array_done()} freigegeben wurde.
\end{itemize}
\bigskip
\begin{flushright}
\textit{Viel Erfolg -- auch in der Klausur!}
\textit{Viel Erfolg in der Klausur!}
\end{flushright}
\end{document}
No preview for this file type
......@@ -252,9 +252,9 @@
Damit können Sie sich gleichzeitig von der Bedingung lösen,
daß die Länge des Arrays ein Vielfaches von 8 sein muß.
\item
Gehen Sie nun von einem statichen zu einem dynamischen Array über,
Gehen Sie nun von einem statischen zu einem dynamischen Array über,
und implementieren sie die Funktionen \lstinline{bit_array_init()},
\lstinline{bit_array_done()} und \lstinline{bit_array_reseize()}.
\lstinline{bit_array_done()} und \lstinline{bit_array_resize()}.
\end{itemize}
\points{14}
......
#include <stdio.h>
typedef struct
{
int content;
node *next;
} node;
int main (void)
{
return 0;
}
#include <stdio.h>
typedef struct node
{
int content;
struct node *next;
} node;
int main (void)
{
return 0;
}
#include <stdio.h>
typedef struct node
{
int content;
struct node *next;
} node;
int main (void)
{
node node3 = { 3, NULL };
node node7 = { 7, NULL };
node node137 = { 137, NULL };
node *first = &node3;
for (node *p = first; p; p = p->next)
printf ("%d\n", p->content);
return 0;
}
#include <stdio.h>
typedef struct node
{
int content;
struct node *next;
} node;
int main (void)
{
node node3 = { 3, NULL };
node node7 = { 7, NULL };
node node137 = { 137, NULL };
node3.next = &node7;
node7.next = &node137;
node137.next = NULL;
node *first = &node3;
for (node *p = first; p; p = p->next)
printf ("%d\n", p->content);
return 0;
}
#include <stdio.h>
typedef struct node
{
int content;
struct node *next;
} node;
int main (void)
{
node node3 = { 3, NULL };
node node7 = { 7, NULL };
node node137 = { 137, NULL };
node3.next = &node7;
node7.next = &node137;
node137.next = NULL;
node node5 = { 5, NULL };
node5.next = node3.next;
node3.next = &node5;
node *first = &node3;
for (node *p = first; p; p = p->next)
printf ("%d\n", p->content);
return 0;
}
.file "lists-5.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
.LFB11:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
pushq %rbx
.cfi_def_cfa_offset 24
.cfi_offset 3, -24
subq $72, %rsp
.cfi_def_cfa_offset 96
movl $3, 48(%rsp)
movl $7, 32(%rsp)
movl $137, 16(%rsp)
movq $0, 24(%rsp)
leaq 16(%rsp), %rax
movq %rax, 40(%rsp)
movl $5, (%rsp)
leaq 32(%rsp), %rax
movq %rax, 8(%rsp)
movq %rsp, 56(%rsp)
leaq 48(%rsp), %rbx
leaq .LC0(%rip), %rbp
.L2:
movl (%rbx), %esi
movq %rbp, %rdi
movl $0, %eax
call printf@PLT
movq 8(%rbx), %rbx
testq %rbx, %rbx
jne .L2
movl $0, %eax
addq $72, %rsp
.cfi_def_cfa_offset 24
popq %rbx
.cfi_def_cfa_offset 16
popq %rbp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE11:
.size main, .-main
.ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
.section .note.GNU-stack,"",@progbits
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment