diff --git a/20221212/hp-20221212.pdf b/20221219/hp-20221219.pdf similarity index 100% rename from 20221212/hp-20221212.pdf rename to 20221219/hp-20221219.pdf diff --git a/20221212/hp-20221212.tex b/20221219/hp-20221219.tex similarity index 100% rename from 20221212/hp-20221212.tex rename to 20221219/hp-20221219.tex diff --git a/20221219/lists-1.c b/20221219/lists-1.c new file mode 100644 index 0000000000000000000000000000000000000000..a04067e1403601ef56dd706d6148c1d386884e82 --- /dev/null +++ b/20221219/lists-1.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +typedef struct +{ + int content; + node *next; +} node; + +int main (void) +{ + return 0; +} diff --git a/20221219/lists-2.c b/20221219/lists-2.c new file mode 100644 index 0000000000000000000000000000000000000000..f27d1d5af7c0c237f0d0286155380ef9452a497a --- /dev/null +++ b/20221219/lists-2.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +typedef struct node +{ + int content; + struct node *next; +} node; + +int main (void) +{ + return 0; +} diff --git a/20221219/lists-3.c b/20221219/lists-3.c new file mode 100644 index 0000000000000000000000000000000000000000..9c9029724efff25263813c5491add92504779d17 --- /dev/null +++ b/20221219/lists-3.c @@ -0,0 +1,21 @@ +#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; +} diff --git a/20221219/lists-4.c b/20221219/lists-4.c new file mode 100644 index 0000000000000000000000000000000000000000..e048736b85cc228c35f31644d003e00cdefc5496 --- /dev/null +++ b/20221219/lists-4.c @@ -0,0 +1,25 @@ +#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; +} diff --git a/20221219/lists-5.c b/20221219/lists-5.c new file mode 100644 index 0000000000000000000000000000000000000000..a0cc620a884c133dd89582de726139091bc9c5d0 --- /dev/null +++ b/20221219/lists-5.c @@ -0,0 +1,29 @@ +#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; +} diff --git a/20221219/logo-hochschule-bochum-cvh-text-v2.pdf b/20221219/logo-hochschule-bochum-cvh-text-v2.pdf new file mode 120000 index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8 --- /dev/null +++ b/20221219/logo-hochschule-bochum-cvh-text-v2.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum-cvh-text-v2.pdf \ No newline at end of file diff --git a/20221219/logo-hochschule-bochum.pdf b/20221219/logo-hochschule-bochum.pdf new file mode 120000 index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1 --- /dev/null +++ b/20221219/logo-hochschule-bochum.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum.pdf \ No newline at end of file diff --git a/20221212/pgslides.sty b/20221219/pgslides.sty similarity index 100% rename from 20221212/pgslides.sty rename to 20221219/pgslides.sty diff --git a/20221219/tree-01.c b/20221219/tree-01.c new file mode 100644 index 0000000000000000000000000000000000000000..d347186a019709e416529c1b73c32f268e0fce57 --- /dev/null +++ b/20221219/tree-01.c @@ -0,0 +1,13 @@ +#include <stdio.h> + +typedef struct +{ + int content; + node *left, *right; +} node; + +int main (void) +{ + node *root = NULL; + return 0; +} diff --git a/20221219/tree-02.c b/20221219/tree-02.c new file mode 100644 index 0000000000000000000000000000000000000000..7e591c3282329f0211c479dfa1b8c82f3dc755a3 --- /dev/null +++ b/20221219/tree-02.c @@ -0,0 +1,13 @@ +#include <stdio.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +int main (void) +{ + node *root = NULL; + return 0; +} diff --git a/20221219/tree-03.c b/20221219/tree-03.c new file mode 100644 index 0000000000000000000000000000000000000000..b88b8671bbda9efe1031d09e3caa60ebeea8ccea --- /dev/null +++ b/20221219/tree-03.c @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +void insert (node *root, int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + root = p; +} + +void output (node *root) +{ + if (root) + printf ("%d\n", root->content); +} + +int main (void) +{ + node *root = NULL; + insert (root, 7); + output (root); + return 0; +} diff --git a/20221219/tree-04.c b/20221219/tree-04.c new file mode 100644 index 0000000000000000000000000000000000000000..db3b53dde184a82e1f85aa46e1f7e76b38e6b775 --- /dev/null +++ b/20221219/tree-04.c @@ -0,0 +1,37 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +void insert (int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + root = p; +} + +void output (void) +{ + if (root) + printf ("%d\n", root->content); + else + printf ("root is NULL\n"); +} + +int main (void) +{ + insert (7); + insert (137); + insert (3); + output (); + return 0; +} diff --git a/20221219/tree-05.c b/20221219/tree-05.c new file mode 100644 index 0000000000000000000000000000000000000000..628d8803131ca8ff163a085ee8ff4cb6ede0bc88 --- /dev/null +++ b/20221219/tree-05.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +void insert (int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + root = p; + else + { + if (content > root->content) + root->right = p; + else + root->left = p; + } +} + +void output (void) +{ + if (root) + printf ("%d\n", root->content); + else + printf ("root is NULL\n"); +} + +int main (void) +{ + insert (7); + insert (137); + insert (3); + output (); + return 0; +} diff --git a/20221219/tree-06.c b/20221219/tree-06.c new file mode 100644 index 0000000000000000000000000000000000000000..f38634d004a020104e65e04cf437c87085dd0d18 --- /dev/null +++ b/20221219/tree-06.c @@ -0,0 +1,50 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +void insert (int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + root = p; + else + { + if (content > root->content) + root->right = p; + else + root->left = p; + } +} + +void output (void) +{ + if (root) + { + if (root->left) + printf ("%d\n", root->left->content); + printf ("%d\n", root->content); + if (root->right) + printf ("%d\n", root->right->content); + } + else + printf ("root is NULL\n"); +} + +int main (void) +{ + insert (7); + insert (137); + insert (3); + output (); + return 0; +} diff --git a/20221219/tree-07.c b/20221219/tree-07.c new file mode 100644 index 0000000000000000000000000000000000000000..df1dd66b3e1a5892235bcaa894888f8becb4de85 --- /dev/null +++ b/20221219/tree-07.c @@ -0,0 +1,71 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +void insert (int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + root = p; + else + { + node *save_root = root; + if (content > root->content) + { + root = root->left; + insert (content); + } + else + { + root = root->right; + insert (content); + } + root = save_root; + } +} + +void output (void) +{ + if (root) + { + if (root->left) + { + node *save_root = root; + root = root->left; + output (); + root = save_root; + } + printf ("%d\n", root->content); + if (root->right) + { + node *save_root = root; + root = root->right; + output (); + root = save_root; + } + } + else + printf ("root is NULL\n"); +} + +int main (void) +{ + insert (7); + insert (137); + insert (3); + insert (1117); + insert (42); + insert (13); + output (); + return 0; +} diff --git a/20221219/tree-08.c b/20221219/tree-08.c new file mode 100644 index 0000000000000000000000000000000000000000..fd3cafcad82fb4b9bbc6d7c905c1005d7c202f6e --- /dev/null +++ b/20221219/tree-08.c @@ -0,0 +1,73 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +void insert (int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + root = p; + else + { + node *save_root = root; + if (content > root->content) + { + root = root->left; + insert (content); + save_root->left = root; + } + else + { + root = root->right; + insert (content); + save_root->right = root; + } + root = save_root; + } +} + +void output (void) +{ + if (root) + { + if (root->left) + { + node *save_root = root; + root = root->left; + output (); + root = save_root; + } + printf ("%d\n", root->content); + if (root->right) + { + node *save_root = root; + root = root->right; + output (); + root = save_root; + } + } + else + printf ("root is NULL\n"); +} + +int main (void) +{ + insert (7); + insert (137); + insert (3); + insert (1117); + insert (42); + insert (13); + output (); + return 0; +} diff --git a/20221219/tree-09.c b/20221219/tree-09.c new file mode 100644 index 0000000000000000000000000000000000000000..6b44c1108c747f4e6021ddf92d771d77288af18d --- /dev/null +++ b/20221219/tree-09.c @@ -0,0 +1,73 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +void insert (int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + root = p; + else + { + node *save_root = root; + if (content < root->content) + { + root = root->left; + insert (content); + save_root->left = root; + } + else + { + root = root->right; + insert (content); + save_root->right = root; + } + root = save_root; + } +} + +void output (void) +{ + if (root) + { + if (root->left) + { + node *save_root = root; + root = root->left; + output (); + root = save_root; + } + printf ("%d\n", root->content); + if (root->right) + { + node *save_root = root; + root = root->right; + output (); + root = save_root; + } + } + else + printf ("root is NULL\n"); +} + +int main (void) +{ + insert (7); + insert (137); + insert (3); + insert (1117); + insert (42); + insert (13); + output (); + return 0; +} diff --git a/20221219/tree-10.c b/20221219/tree-10.c new file mode 100644 index 0000000000000000000000000000000000000000..26a5575d8c0dbd139b08ca9365ad0a667223841b --- /dev/null +++ b/20221219/tree-10.c @@ -0,0 +1,63 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +void insert (int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + root = p; + else + { + node *save_root = root; + if (content < root->content) + { + root = root->left; + insert (content); + save_root->left = root; + } + else + { + root = root->right; + insert (content); + save_root->right = root; + } + root = save_root; + } +} + +void output (node *root) +{ + if (root) + { + if (root->left) + output (root->left); + printf ("%d\n", root->content); + if (root->right) + output (root->right); + } + else + printf ("root is NULL\n"); +} + +int main (void) +{ + insert (7); + insert (137); + insert (3); + insert (1117); + insert (42); + insert (13); + output (root); + return 0; +} diff --git a/20221219/tree-11.c b/20221219/tree-11.c new file mode 100644 index 0000000000000000000000000000000000000000..508b24316bf6696abc9225fac3fe7ef398a7e094 --- /dev/null +++ b/20221219/tree-11.c @@ -0,0 +1,61 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +void insert (int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + root = p; + else + { + node *save_root = root; + if (content < root->content) + { + root = root->left; + insert (content); + save_root->left = root; + } + else + { + root = root->right; + insert (content); + save_root->right = root; + } + root = save_root; + } +} + +void output (node *root) +{ + if (root) + { + output (root->left); + printf ("%d\n", root->content); + output (root->right); + } + else + printf ("root is NULL\n"); +} + +int main (void) +{ + insert (7); + insert (137); + insert (3); + insert (1117); + insert (42); + insert (13); + output (root); + return 0; +} diff --git a/20221219/tree-12.c b/20221219/tree-12.c new file mode 100644 index 0000000000000000000000000000000000000000..ff07e64e6dceb10266dc6d376d68fd15bc59e68b --- /dev/null +++ b/20221219/tree-12.c @@ -0,0 +1,59 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +void insert (int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + root = p; + else + { + node *save_root = root; + if (content < root->content) + { + root = root->left; + insert (content); + save_root->left = root; + } + else + { + root = root->right; + insert (content); + save_root->right = root; + } + root = save_root; + } +} + +void output (node *root) +{ + if (root) + { + output (root->left); + printf ("%d\n", root->content); + output (root->right); + } +} + +int main (void) +{ + insert (7); + insert (137); + insert (3); + insert (1117); + insert (42); + insert (13); + output (root); + return 0; +} diff --git a/20221219/tree-13.c b/20221219/tree-13.c new file mode 100644 index 0000000000000000000000000000000000000000..236930ed75a80984bfe343a582320470180db3ad --- /dev/null +++ b/20221219/tree-13.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +node *insert (node *root, int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + return p; + else + { + if (content < root->content) + { + root->left = insert (root->left, content); + return root; + } + else + { + root->right = insert (root->right, content); + return root; + } + } +} + +void output (node *root) +{ + if (root) + { + output (root->left); + printf ("%d\n", root->content); + output (root->right); + } +} + +int main (void) +{ + root = insert (root, 7); + root = insert (root, 137); + root = insert (root, 3); + root = insert (root, 1117); + root = insert (root, 42); + root = insert (root, 13); + output (root); + return 0; +} diff --git a/20221219/tree-14.c b/20221219/tree-14.c new file mode 100644 index 0000000000000000000000000000000000000000..a95a1fc5acec20d7fa0fcf714af2d5d746899c1c --- /dev/null +++ b/20221219/tree-14.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +node *insert (node *root, int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + return p; + else + { + if (content < root->content) + { + root->left = insert (root->left, content); + return root; + } + else + { + root->right = insert (root->right, content); + return root; + } + } +} + +void output (node *root) +{ + if (root) + { + output (root->left); + printf ("%d\n", root->content); + output (root->right); + } +} + +int main (void) +{ + insert (root, 7); + insert (root, 137); + insert (root, 3); + insert (root, 1117); + insert (root, 42); + insert (root, 13); + output (root); + return 0; +} diff --git a/20221219/tree-15.c b/20221219/tree-15.c new file mode 100644 index 0000000000000000000000000000000000000000..929d253f77de0cc15a6707dd499420965eb9daca --- /dev/null +++ b/20221219/tree-15.c @@ -0,0 +1,48 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +void insert (node **root, int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (*root == NULL) + *root = p; + else + { + if (content < root->content) + insert (&root->left, content); + else + insert (&root->right, content); + } +} + +void output (node *root) +{ + if (root) + { + output (root->left); + printf ("%d\n", root->content); + output (root->right); + } +} + +int main (void) +{ + node *root = NULL; + insert (&root, 7); + insert (&root, 137); + insert (&root, 3); + insert (&root, 1117); + insert (&root, 42); + insert (&root, 13); + output (root); + return 0; +} diff --git a/20221219/tree-16.c b/20221219/tree-16.c new file mode 100644 index 0000000000000000000000000000000000000000..be7163d4fdf57b897887bb861418e342e5061961 --- /dev/null +++ b/20221219/tree-16.c @@ -0,0 +1,48 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +void insert (node **root, int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (*root == NULL) + *root = p; + else + { + if (content < (*root)->content) + insert (&(*root)->left, content); + else + insert (&(*root)->right, content); + } +} + +void output (node *root) +{ + if (root) + { + output (root->left); + printf ("%d\n", root->content); + output (root->right); + } +} + +int main (void) +{ + node *root = NULL; + insert (&root, 7); + insert (&root, 137); + insert (&root, 3); + insert (&root, 1117); + insert (&root, 42); + insert (&root, 13); + output (root); + return 0; +} diff --git a/20221219/tree-16a.cpp b/20221219/tree-16a.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e11b48316a1ecae2c3263f85ee7e2c3616b3e912 --- /dev/null +++ b/20221219/tree-16a.cpp @@ -0,0 +1,48 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +void insert (node *&root, int content) +{ + node *p = (node *) malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + if (root == NULL) + root = p; + else + { + if (content < root->content) + insert (root->left, content); + else + insert (root->right, content); + } +} + +void output (node *root) +{ + if (root) + { + output (root->left); + printf ("%d\n", root->content); + output (root->right); + } +} + +int main (void) +{ + node *root = NULL; + insert (root, 7); + insert (root, 137); + insert (root, 3); + insert (root, 1117); + insert (root, 42); + insert (root, 13); + output (root); + return 0; +} diff --git a/20221219/tree-3a.c b/20221219/tree-3a.c new file mode 100644 index 0000000000000000000000000000000000000000..8031ec72af9bcb97b83c46b296ab5f2464832fcd --- /dev/null +++ b/20221219/tree-3a.c @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +void insert (node *root, int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + root = p; +} + +void output (node *root) +{ + if (root) + printf ("%d\n", root->content); + else + printf ("root is NULL\n"); +} + +int main (void) +{ + node *root = NULL; + insert (root, 7); + output (root); + return 0; +} diff --git a/20221219/tree-3b.c b/20221219/tree-3b.c new file mode 100644 index 0000000000000000000000000000000000000000..5b47c41b61d5a76380bccefc98f2fd3057ad645b --- /dev/null +++ b/20221219/tree-3b.c @@ -0,0 +1,34 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *root = NULL; + +void insert (int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + root = p; +} + +void output (void) +{ + if (root) + printf ("%d\n", root->content); + else + printf ("root is NULL\n"); +} + +int main (void) +{ + insert (7); + output (); + return 0; +} diff --git a/20221219/tree-3c.c b/20221219/tree-3c.c new file mode 100644 index 0000000000000000000000000000000000000000..63ffbaa792e5bc4d122f96e5cfd32e7579c2077c --- /dev/null +++ b/20221219/tree-3c.c @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *left, *right; +} node; + +node *insert (node *root, int content) +{ + node *p = malloc (sizeof (node)); + p->content = content; + p->left = NULL; + p->right = NULL; + return p; +} + +void output (node *root) +{ + if (root) + printf ("%d\n", root->content); + else + printf ("root is NULL\n"); +} + +int main (void) +{ + node *root = NULL; + root = insert (root, 7); + output (root); + return 0; +} diff --git a/20230109/aufgabe-1.c b/20230109/aufgabe-1.c new file mode 100644 index 0000000000000000000000000000000000000000..f26ce5d665012e2cdbaac8b0f43f01d40f338254 --- /dev/null +++ b/20230109/aufgabe-1.c @@ -0,0 +1,47 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *next; +} node; + +void output_list (node *first) +{ + for (node *p = first; p; p = p->next) + printf ("%d ", p->content); + printf ("\n"); +} + +void insert_into_list (node *what, node *where) +{ + what->next = where->next; + where->next = what; +} + +int main (void) +{ + node *element3 = malloc (sizeof (node)); + node *element7 = malloc (sizeof (node)); + node *element137 = malloc (sizeof (node)); + + element3->content = 3; + element7->content = 7; + element137->content = 137; + + node *first = element3; + element3->next = element7; + element7->next = element137; + element137->next = NULL; + + output_list (first); + + node *element5 = malloc (sizeof (node)); + element5->content = 5; + insert_into_list (element5, element3); + + output_list (first); + + return 0; +} diff --git a/20230109/aufgabe-3.c b/20230109/aufgabe-3.c new file mode 100644 index 0000000000000000000000000000000000000000..5b0cb23fdd5ee15a4403808c18d2104ed49caf3f --- /dev/null +++ b/20230109/aufgabe-3.c @@ -0,0 +1,62 @@ +#include <gtk/gtk.h> + +#define WIDTH 320 +#define HEIGHT 240 + +double t = 0.0; +double dt = 0.2; + +int r = 5; + +double x = 10; +double y = 200; +double vx = 20; +double vy = -60; +double g = 9.81; + +gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data) +{ + GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 }; + + gdk_cairo_set_source_rgba (c, &blue); + cairo_arc (c, x, y, r, 0, 2 * G_PI); + cairo_fill (c); + + return FALSE; +} + +gboolean timer (GtkWidget *widget) +{ + t += dt; + x += vx * dt; + y += vy * dt; + vx = vx; + vy = 0.5 * g * (t * t); + if (y + r >= HEIGHT) + vy = -vy * 0.9; + if (x + r >= WIDTH) + vx = -vx * 0.9; + if (x - r <= 0) + vx = -vx * 0.9; + gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT); + g_timeout_add (50, (GSourceFunc) timer, widget); + return FALSE; +} + +int main (int argc, char **argv) +{ + gtk_init (&argc, &argv); + + GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_show (window); + gtk_window_set_title (GTK_WINDOW (window), "Hello"); + g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); + + GtkWidget *drawing_area = gtk_drawing_area_new (); + gtk_widget_show (drawing_area); + gtk_container_add (GTK_CONTAINER (window), drawing_area); + gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT); + + gtk_main (); + return 0; +} diff --git a/20230109/aufgabe-4.c b/20230109/aufgabe-4.c new file mode 100644 index 0000000000000000000000000000000000000000..2bcd5e63a71f212b7243d1f7d9c92406d1e41e77 --- /dev/null +++ b/20230109/aufgabe-4.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +int main (void) +{ + char buffer[100]; + fgets (buffer, 100, stdin); + for (char *p = buffer; *p; p++) + printf ("%02x", *p); + printf ("\n"); +} diff --git a/20230109/hp-musterloesung-20230109.pdf b/20230109/hp-musterloesung-20230109.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fecb1322d2d38ae43542bdc5fe222115f6503eba Binary files /dev/null and b/20230109/hp-musterloesung-20230109.pdf differ diff --git a/20230109/hp-musterloesung-20230109.tex b/20230109/hp-musterloesung-20230109.tex new file mode 100644 index 0000000000000000000000000000000000000000..a10d64ce3bff36aae2a0a9c59bc18a3beacd64c3 --- /dev/null +++ b/20230109/hp-musterloesung-20230109.tex @@ -0,0 +1,636 @@ +% hp-musterloesung-20230109.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences +% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Peter Gerwinski +% +% This document is free software: you can redistribute it and/or +% modify it either under the terms of the Creative Commons +% Attribution-ShareAlike 3.0 License, or under the terms of the +% GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% This document is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this document. If not, see <http://www.gnu.org/licenses/>. +% +% You should have received a copy of the Creative Commons +% Attribution-ShareAlike 3.0 Unported License along with this +% document. If not, see <http://creativecommons.org/licenses/>. + +% README: Einfach und doppelt verkettete Listen, ternärer Baum, hüpfender Ball, Hexdumps + +% ! Hüpfender Ball (20211206-3) +% ! Hexdumps (20220110-3) +% ! einfach und doppelt verkettete Listen (20220117-2) +% ! ternärer Baum (20220117-3) + +\documentclass[a4paper]{article} + +\usepackage{pgscript} +\usepackage{tikz} + +\begin{document} + + \section*{Hardwarenahe Programmierung\\ + Musterlösung zu den Übungsaufgaben -- 9.\ Januar 2023} + + \exercise{Einfach und doppelt verkettete Listen} + + Das Beispiel-Programm \gitfile{hp}{2022ws/20230109}{aufgabe-1.c} + demonstriert zwei Funktionen zur Verwaltung einfach verketteter Listen: + \lstinline{output_list()} zum Ausgeben der Liste auf den Bildschirm und + \lstinline{insert_into_list()} zum Einfügen in die Liste. + + \begin{enumerate}[\quad(a)] + \item + Ergänzen Sie eine Funktion \lstinline{delete_from_list()} + zum Löschen eines Elements aus der Liste + mit Freigabe des Speicherplatzes. + \points{5} + \item + Ergänzen Sie eine Funktion \lstinline{reverse_list()} + die die Reihenfolge der Elemente in der Liste umdreht.\\ + \points{3} + \end{enumerate} + + Eine doppelt verkettete Liste hat in jedem Knotenpunkt (\lstinline{node}) + \emph{zwei\/} Zeiger -- einen auf das nächste Element (\lstinline{next}) + und einen auf das vorherige Element (z.\,B.\ \lstinline{prev} für "`previous"'). + Dadurch ist es leichter als bei einer einfach verketteten Liste, + die Liste in umgekehrter Reihenfolge durchzugehen. + + \begin{quote} + \begin{tikzpicture} + \color{blendedblue} + \node(first) at (0,3.5) {first}; + \node(NULL1) at (-1,1.25) {NULL}; + \node[shape=rectangle,draw,line width=1pt](3) at (1,2) {3}; + \node[shape=rectangle,draw,line width=1pt](7) at (3,2) {7}; + \node[shape=rectangle,draw,line width=1pt](137) at (5,2) {137}; + \node(NULL2) at (7,2.75) {NULL}; + \draw[-latex](first)--(3); + \draw[-latex](3) to[out=45,in=135] (7); + \draw[-latex](3) to[out=-135,in=0] (NULL1); + \draw[-latex](7) to[out=-135,in=-45] (3); + \draw[-latex](7) to[out=45,in=135] (137); + \draw[-latex](137) to[out=-135,in=-45] (7); + \draw[-latex](137) to[out=45,in=180] (NULL2); + \end{tikzpicture} + \end{quote} + + Der Rückwärts-Zeiger (\lstinline{prev}) des ersten Elements zeigt, + genau wie der Vorwärts-Zeiger (\lstinline{next}) des letzten Elements, + auf \emph{nichts}, hat also den Wert \lstinline{NULL}. + + \begin{enumerate}[\quad(a)]\setcounter{enumi}{2} + \item + Schreiben Sie das Programm um für doppelt verkettete Listen. + \points{5} + \end{enumerate} + + \solution + + \begin{enumerate}[\quad(a)] + \item + \textbf{Ergänzen Sie eine Funktion \lstinline{delete_from_list()} + zum Löschen eines Elements aus der Liste + mit Freigabe des Speicherplatzes.} + + Siehe: \gitfile{hp}{2022ws/20230109}{loesung-1a.c} + + Um ein Element aus einer verketteten Liste zu löschen, + müssen zuerst die Zeiger umgestellt werden, + um das Element von der Liste auszuschließen. + Erst danach darf der Speicherplatz für das Element freigegeben werden. + +% Da das Beispielprogramm (\gitfile{hp}{2021ws/20220117}{lists-5.c}) +% nicht mit dynamischem Speicher arbeitet, +% stellen wir dieses zunächst auf dynamischen Speicher um, z.\,B.: +% \begin{lstlisting}[gobble=8] +% node *element5 = malloc (sizeof (node)); +% \end{lstlisting} +% Danach bezeichnet \lstinline{element5} +% die Adresse der \lstinline{struct}-Variablen; +% es wird also \lstinline{element5} an die Funktionen übergeben +% und nicht \lstinline{&element5} (die Adresse des Zeigers). + +% Um nun ein Element aus der Liste zu entfernen, +% benötigt man + Man benötigt also + \emph{das vorherige Element}, + dessen \lstinline{next}-Zeiger man dann auf + das übernächste Element \lstinline{next->next} weitersetzt. + + Bei jedem Zeiger muß man vor dem Zugriff prüfen, + daß dieser nicht auf \lstinline{NULL} zeigt. + (Die Musterlösung ist in dieser Hinsicht nicht konsequent. + Für den Produktiveinsatz müßte z.\,B.\ \lstinline{delete_from_list()} + auch den übergebenen Zeiger \lstinline{what} auf \lstinline{NULL} prüfen.) + + Ein Spezialfall tritt ein, wenn das erste Element einer Liste + entfernt werden soll. In diesem Fall tritt \lstinline{first} + an die Stelle des \lstinline{next}-Zeigers + des (nicht vorhandenen) vorherigen Elements. + Da \lstinline{delete_from_list()} \emph{schreibend\/} auf \lstinline{first} + zugreift, muß \lstinline{first} \emph{als Zeiger\/} übergeben werden + (\lstinline{node **first}). + + Um alle Spezialfälle zu testen (am Anfang, am Ende und in der Mitte der Liste), + wurden die Testfälle im Hauptprogramm erweitert. + + \item + \textbf{Schreiben Sie das Programm um für doppelt verkettete Listen.} + + Siehe: \gitfile{hp}{2022ws/20230109}{loesung-1b.c} + + Bei allen Einfüge- und Löschaktionen müssen \emph{jeweils zwei\/} + \lstinline{next}- und \lstinline{prev}-Zeiger neu gesetzt werden. + + Zum Debuggen empfiehlt es sich sehr, + eine Funktion zu schreiben, die die Liste auf Konsistenz prüft + (hier: \lstinline{check_list()}). + + Das Testprogramm macht von der Eigenschaft der doppelt verketteten Liste, + daß man sie auch rückwärts effizient durchgehen kann, keinen Gebrauch. + Um diese Eigenschaft als Vorteil nutzen zu können, empfiehlt es sich, + zusätzlich zu \lstinline{first} + auch einen Zeiger auf das letzte Element (z.\,B.\ \lstinline{last}) + einzuführen. Dieser muß dann natürlich bei allen Operationen + (Einfügen, Löschen, \dots) auf dem aktuellen Stand gehalten werden. + + \end{enumerate} + + \exercise{Ternärer Baum} + + Der in der Vorlesung vorgestellte \newterm{binäre Baum\/} + ist nur ein Spezialfall; + im allgemeinen können Bäume auch mehr als zwei Verzweigungen + pro Knotenpunkt haben. + Dies ist nützlich bei der Konstruktion \emph{balancierter Bäume}, + also solcher, die auch im \emph{Worst Case\/} + nicht zu einer linearen Liste entarten, + sondern stets eine -- möglichst flache -- Baumstruktur behalten. + + Wir betrachten einen Baum mit bis zu drei Verzweigungen pro Knotenpunkt, + einen sog.\ \newterm{ternären Baum}. + Jeder Knoten enthält dann nicht nur einen, + sondern \emph{zwei\/} Werte als Inhalt: + \begin{lstlisting} + typedef struct node + { + int content_left, content_right; + struct node *left, *middle, *right; + } node; + \end{lstlisting} + + Wir konstruieren nun einen Baum nach folgenden Regeln: + \vspace{-\medskipamount} + \begin{itemize}\itemsep0pt + \item + Innerhalb eines Knotens sind die Werte sortiert: + \lstinline{content_left} muß stets kleiner sein als \lstinline{content_right}. + \item + Der Zeiger \lstinline{left} zeigt auf Knoten, + deren enthaltene Werte durchweg kleiner sind als \lstinline{content_left}. + \item + Der Zeiger \lstinline{right} zeigt auf Knoten, + deren enthaltene Werte durchweg größer sind als \lstinline{content_right}. + \item + Der Zeiger \lstinline{middle} zeigt auf Knoten, + deren enthaltene Werte durchweg größer sind als \lstinline{content_left}, + aber kleiner als \lstinline{content_right}. + \item + Ein Knoten muß nicht immer mit zwei Werten voll besetzt sein; + er darf auch \emph{nur einen\/} gültigen Wert enthalten. + + Der Einfachheit halber lassen wir in diesem Beispiel + nur positive Zahlen als Werte zu. + Wenn ein Knoten nur einen Wert enthält, + setzen wir \lstinline{content_right = -1}, + und der Zeiger \lstinline{middle} wird nicht verwendet. + \item + Wenn wir neue Werte in den Baum einfügen, + werden \emph{zuerst\/} die nicht voll besetzten Knoten aufgefüllt + und \emph{danach erst\/} neue Knoten angelegt und Zeiger gesetzt. + \item + Beim Auffüllen eines Knotens darf nötigenfalls \lstinline{content_left} + nach \lstinline{content_right} verschoben werden. + Ansonsten werden einmal angelegte Knoten nicht mehr verändert. + \end{itemize} + \vspace*{-\medskipamount} + (In der Praxis dürfen Knoten gemäß speziellen Regeln + nachträglich verändert werden, + um Entartungen gar nicht erst entstehen zu lassen -- + siehe z.\,B.\ \url{https://en.wikipedia.org/wiki/2-3_tree}.) + \begin{enumerate}[\quad(a)] + \item + Zeichnen Sie ein Schaubild, das veranschaulicht, + wie die Zahlen 7, 137, 3, 5, 6, 42, 1, 2 und 12 + nacheinander und in dieser Reihenfolge + in den oben beschriebenen Baum eingefügt werden + -- analog zu den Vortragsfolien (\gitfile{hp}{2022ws/20221219}{hp-20221219.pdf}), + Seite 33. + \points{3} + % + % Lösung: + % + % 7 137 + % / | + % 3 5 12 42 + % / \ + % 1 2 6 + % + % (NULL-Zeiger sind hier nicht dargestellt, + % gehören aber dazu.) + % + \item + Dasselbe, aber in der Reihenfolge + 2, 7, 42, 12, 1, 137, 5, 6, 3. + \points{3} + % + % Lösung: + % + % 2 7 + % / | \ + % 1 5 6 12 42 + % / \ + % 3 137 + % + % (NULL-Zeiger sind hier wieder nicht dargestellt, + % gehören aber dazu.) + % + \item + Beschreiben Sie in Worten und/oder als C-Quelltext-Fragment, + wie eine Funktion aussehen müßte, um den auf diese Weise entstandenen Baum + sortiert auszugeben. + \points{4} + \end{enumerate} + + \solution + + \begin{enumerate}[\quad(a)] + \item + \textbf{Zeichnen Sie ein Schaubild, das veranschaulicht, + wie die Zahlen 7, 137, 3, 5, 6, 42, 1, 2 und 12 + nacheinander und in dieser Reihenfolge + in den oben beschriebenen Baum eingefügt werden + -- analog zu den Vortragsfolien (\gitfile{hp}{2022ws/20221219}{hp-20221219.pdf}), + Seite 21.} + % + % Lösung: + % + % 7 137 + % / | + % 3 5 12 42 + % / \ + % 1 2 6 + % + % (NULL-Zeiger sind hier nicht dargestellt, + % gehören aber dazu.) + % + \begin{center} + \newcommand{\x}{~\makebox(0,0){\raisebox{0.7em}{\rule{1pt}{1.4em}}}~} + \begin{tikzpicture} + \color{blendedblue} + \node(root) at (0,0) {\lstinline{node *root;}}; + \node[shape=rectangle,draw,line width=1pt](7-137) at (0,-1.5) {7\x 137}; + \draw[-latex](root)--(7-137); + \node[shape=rectangle,draw,line width=1pt](3-5) at (-2,-3) {3\x 5}; + \draw[-latex](7-137)--(3-5); + \node[shape=rectangle,draw,line width=1pt](12-42) at (0,-3) {12\x 42}; + \draw[-latex](7-137)--(12-42); + \node[shape=rectangle,draw,line width=1pt](1-2) at (-4,-4.5) {1\x 2}; + \draw[-latex](3-5)--(1-2); + \node[shape=rectangle,draw,line width=1pt](6) at (0,-4.5) {6}; + \draw[-latex](3-5)--(6); + \end{tikzpicture} + \end{center} + Bemerkungen: + \begin{itemize} + \item + Zeiger mit dem Wert \lstinline{NULL} sind nicht dargestellt: + \lstinline{right}-Zeiger von 7/137, + \lstinline{middle}-Zeiger von 3/5, + sämtliche Zeiger von 1/2, 12/42 und 6. + \item + Beim Einfügen der 12 wird die sich bereits vorher in diesem + \lstinline{node} befindliche 42 zu \lstinline{content_right}, + und die 12 wird das neue \lstinline{content_left}. + \item + Dieser Baum hat sehr einfache Regeln und ist daher \emph{nicht\/} + balanciert. Insbesondere unsere Regel, daß einmal angelegte Knoten + nicht mehr verändert werden dürfen, steht dem im Wege. + Ein einfaches Beispiel für einen \emph{balancierten\/} ternären + Baum ist der 2-3-Baum -- siehe z.\,B.\ \url{https://en.wikipedia.org/wiki/2-3_tree}. + \end{itemize} + \goodbreak + \item + \textbf{Dasselbe, aber in der Reihenfolge + 2, 7, 42, 12, 1, 137, 5, 6, 3.} + % + % Lösung: + % + % 2 7 + % / | \ + % 1 5 6 12 42 + % / \ + % 3 137 + % + % (NULL-Zeiger sind hier wieder nicht dargestellt, + % gehören aber dazu.) + % + \begin{center} + \newcommand{\x}{~\makebox(0,0){\raisebox{0.7em}{\rule{1pt}{1.4em}}}~} + \begin{tikzpicture} + \color{blendedblue} + \node(root) at (0,0) {\lstinline{node *root;}}; + \node[shape=rectangle,draw,line width=1pt](2-7) at (0,-1.5) {2\x 7}; + \draw[-latex](root)--(7-137); + \node[shape=rectangle,draw,line width=1pt](1) at (-2,-3) {1}; + \draw[-latex](2-7)--(1); + \node[shape=rectangle,draw,line width=1pt](5-6) at (0,-3) {5\x 6}; + \draw[-latex](2-7)--(5-6); + \node[shape=rectangle,draw,line width=1pt](3) at (-2,-4.5) {3}; + \draw[-latex](5-6)--(3); + \node[shape=rectangle,draw,line width=1pt](12-42) at (2,-3) {12\x 42}; + \draw[-latex](2-7)--(12-42); + \node[shape=rectangle,draw,line width=1pt](137) at (4,-4.5) {137}; + \draw[-latex](12-42)--(137); + \end{tikzpicture} + \end{center} + Bemerkungen: + \begin{itemize} + \item + Wieder sind Zeiger mit dem Wert \lstinline{NULL} nicht dargestellt: + \lstinline{middle}- und \lstinline{right}-Zeiger von 5/6, + \lstinline{left}- und \lstinline{middle}-Zeiger von 12/42, + sämtliche Zeiger von 1, 3 und 137. + \item + Beim Einfügen der 12 wird wieder die sich bereits vorher in diesem + \lstinline{node} befindliche 42 zu \lstinline{content_right}, + und die 12 wird das neue \lstinline{content_left}. + \end{itemize} + \item + \textbf{Beschreiben Sie in Worten und/oder als C-Quelltext-Fragment, + wie eine Funktion aussehen müßte, um den auf diese Weise entstandenen Baum + sortiert auszugeben.} + + Die entscheidende Idee ist \textbf{Rekursion}. + + Eine Funktion, die den gesamten Baum ausgibt, + müßte einmalig für den Zeiger \lstinline{root} aufgerufen werden + und folgendes tun: + \begin{enumerate}[\quad 1.] + \item + falls der übergebene Zeiger den Wert \lstinline{NULL} hat, + nichts ausgeben, sondern die Funktion direkt beenden, + \item + sich selbst für den \lstinline{left}-Zeiger aufrufen, + \item + den Wert von \lstinline{content_left} ausgeben, + \item + sich selbst für den \lstinline{middle}-Zeiger aufrufen, + \item + sofern vorhanden (also ungleich \lstinline{-1}), + den Wert von \lstinline{content_right} ausgeben, + \item + sich selbst für den \lstinline{right}-Zeiger aufrufen. + \end{enumerate} + Als C-Fragment: + \begin{lstlisting}[gobble=8] + void output_tree (node *root) + { + if (root) + { + output_tree (root->left); + printf ("%d\n", root->content_left); + output_tree (root->middle); + if (root->content_right >= 0) + printf ("%d\n", root->content_right); + output_tree (root->right); + } + } + \end{lstlisting} + Die Datei \gitfile{hp}{2022ws/20230109}{loesung-2c.c} erweitert dieses Fragment + zu einem vollständigen C-Programm zum Erstellen und sortierten Ausgeben + eines ternären Baums mit den Zahlenwerten von Aufgabenteil (a). + \end{enumerate} + + \exercise{Fehlerhaftes Programm: Hüpfender Ball} + + Das auf der nächsten Seite abgedruckte GTK+-Programm + (Datei: \gitfile{hp}{2022ws/20230109}{aufgabe-3.c}) soll einen + hüpfenden Ball darstellen, ist jedoch fehlerhaft. + + \begin{enumerate}[\quad(a)] + \item + Warum sieht man lediglich ein leeres Fenster? + Welchen Befehl muß man ergänzen, um diesen Fehler zu beheben? + \points{3} + \item + Nach der Fehlerbehebung in Aufgabenteil (a) + zeigt das Programm einen unbeweglichen Ball. + Welchen Befehl muß man ergänzen, um diesen Fehler zu beheben, und warum? + \points{2} + \item + Erklären Sie das merkwürdige Hüpfverhalten des Balls. + Wie kommt es zustande? + Was an diesem Verhalten ist korrekt, und was ist fehlerhaft? \points{5} + \item + Welche Befehle muß man in welcher Weise ändern, + um ein realistischeres Hüpf-Verhalten zu bekommen? \points{2} + \end{enumerate} + + Hinweis: Das Hinzuziehen von Beispiel-Programmen aus der Vorlesung + ist ausdrücklich erlaubt -- auch in der Klausur. + + Allgemeiner Hinweis: + Wenn Sie die Übungsaufgaben zu dieser Lehrveranstaltung + als PDF-Datei betrachten und darin auf die Dateinamen klicken, + können Sie die Beispiel-Programme direkt herunterladen. + Dadurch vermeiden Sie Übertragungsfehler. + + \solution + + \begin{enumerate}[\quad(a)] + \item + \textbf{Warum sieht man lediglich ein leeres Fenster? + Welchen Befehl muß man ergänzen, um diesen Fehler zu beheben?} + + Die für das Zeichnen zuständige Callback-Funktion wurde zwar geschrieben, + aber nicht installiert. + Um dies zu beheben, ergänze man den folgenden Befehl im Hauptprogramm: + + \lstinline{g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);} + + Dies erkennt man sehr schnell durch Vergleich mit dem Beispiel-Programm + \gitfile{hp}{2022ws/20221114}{gtk-13.c}. + + \item + \textbf{Nach der Fehlerbehebung in Aufgabenteil (a) + zeigt das Programm einen unbeweglichen Ball. + Welchen Befehl muß man ergänzen, um diesen Fehler zu beheben, und warum?} + + Die Timer-Callback-Funktion wurde zwar geschrieben, aber nicht installiert. + Um dies zu beheben, ergänze man den folgenden Befehl im Hauptprogramm: + + \lstinline{g_timeout_add (50, (GSourceFunc) timer, drawing_area);} + + Auch dies erkennt man sehr schnell durch Vergleich mit dem Beispiel-Programm + \gitfile{hp}{2022ws/20221114}{gtk-13.c}. + + \item + \textbf{Erklären Sie das merkwürdige Hüpfverhalten des Balls. + Wie kommt es zustande? + Was an diesem Verhalten ist korrekt, und was ist fehlerhaft?} + + Die Geschwindigkeit in $y$-Richtung wächst immer weiter. + Der Grund dafür ist, daß die $y$-Komponente der Geschwindigkeit + nicht auf physikalisch sinnvolle Weise berechnet wird. + In der dafür zuständigen Zeile + \lstinline{vy = 0.5 * g * (t * t);} + wird stattdessen der Weg in $y$-Richtung bei einer gleichmäßig + beschleunigten Bewegung berechnet und als Geschwindigkeit verwendet. + + \item + \textbf{Welche Befehle muß man in welcher Weise ändern, + um ein realistischeres Hüpf-Verhalten zu bekommen?} + + Da der Ball am Boden abprallen soll, ist es \emph{nicht\/} sinnvoll, + die $y$-Komponente der Geschwindigkeit über die bekannte physikalische + Formel $v_y = -g\cdot t$ für die Geschwindigkeit in einer + gleichmäßig beschleunigten Bewegung zu berechnen. + + Stattdessen ist es sinnvoll, die \emph{Geschwindigkeitsänderung\/} + innerhalb des Zeitintervalls \lstinline{dt} + zur Geschwindigkeitskomponente zu addieren: + \lstinline{vy += g * dt;} + + Auch dies erkennt man sehr schnell durch Vergleich mit dem Beispiel-Programm + \gitfile{hp}{2022ws/20221114}{gtk-13.c}. + \end{enumerate} + + \clearpage + + \vbox to \textheight{\vspace*{-0.5cm}\begin{lstlisting} + #include <gtk/gtk.h> + + #define WIDTH 320 + #define HEIGHT 240 + + double t = 0.0; + double dt = 0.2; + + int r = 5; + + double x = 10; + double y = 200; + double vx = 20; + double vy = -60; + double g = 9.81; + + gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data) + { + GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 }; + + gdk_cairo_set_source_rgba (c, &blue); + cairo_arc (c, x, y, r, 0, 2 * G_PI); + cairo_fill (c); + + return FALSE; + } + + gboolean timer (GtkWidget *widget) + { + t += dt; + x += vx * dt; + y += vy * dt; + vx = vx; + vy = 0.5 * g * (t * t); + if (y + r >= HEIGHT) + vy = -vy * 0.9; + if (x + r >= WIDTH) + vx = -vx * 0.9; + if (x - r <= 0) + vx = -vx * 0.9; + gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT); + g_timeout_add (50, (GSourceFunc) timer, widget); + return FALSE; + } + + int main (int argc, char **argv) + { + gtk_init (&argc, &argv); + + GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_show (window); + gtk_window_set_title (GTK_WINDOW (window), "Hello"); + g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); + + GtkWidget *drawing_area = gtk_drawing_area_new (); + gtk_widget_show (drawing_area); + gtk_container_add (GTK_CONTAINER (window), drawing_area); + gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT); + + gtk_main (); + return 0; + } + \end{lstlisting}\vss} + + \clearpage + + \exercise{Hexdumps} + + Das folgende Programm (\gitfile{hp}{2022ws/20230109}{aufgabe-4.c}) liest + einen String ein und gibt die ASCII-Werte der Buchstaben hexadezimal aus. + (Anders als z.\,B.\ \lstinline{scanf()} + akzeptiert die Funktion \lstinline{fgets()} zum Lesen von Strings auch Leerzeichen, + und sie vermeidet Pufferüberläufe.) + \begin{lstlisting}[style=numbered] + #include <stdio.h> + + int main (void) + { + char buffer[100]; + fgets (buffer, 100, stdin); + for (char *p = buffer; *p; p++) + printf ("%02x", *p); + printf ("\n"); + } + \end{lstlisting} + Beispiel: Bei der Eingabe von \lstinline[style=cmd]{Dies ist ein Test.} + erscheint die Ausgabe\\ + \lstinline[style=terminal]{44696573206973742065696e20546573742e0a}. + + Schreiben Sie ein Programm, das diese Umwandlung in umgekehrter Richtung vornimmt, + also z.\,B.\ bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a} + wieder \lstinline[style=terminal]{Dies ist ein Test.} ausgibt. + + \points{6} + + Hinweis für die Klausur: + Abgabe in digitaler Form ist erwünscht, aber nicht zwingend. + + \solution + + Siehe \gitfile{hp}{2022ws/20230109}{loesung-4.c}. + + Das Programm macht mehrfach davon Gebrauch, + daß in C Zeichen und Zahlen äquivalent sind. + Wenn z.\,B.\ die \lstinline{char}-Variable \lstinline{c} + den Wert \lstinline{'3'} (Ziffer 3) enthält, + dann hat der Ausdruck \lstinline{c - '0'} den Wert \lstinline{3} (Zahlenwert 3). + Hierfür ist es insbesondere nicht nötig, vorauszusetzen, + daß wir den ASCII-Zeichensatz verwenden und \lstinline{'0'} + den Wert \lstinline{48} hat. + + Bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a} + gibt das Programm zusätzlich eine Leerzeile aus. + Die liegt daran, daß das \lstinline[style=cmd]{0a} am Ende + bereits eine Zeilenschaltung enthält und das Programm mit + \lstinline{printf ("\n")} eine zusätzliche Zeilenschaltung ausgibt. + +\end{document} diff --git a/20230109/hp-uebung-20230109.pdf b/20230109/hp-uebung-20230109.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fa3d56e5adb15c9eca45f503587d85415b4cd073 Binary files /dev/null and b/20230109/hp-uebung-20230109.pdf differ diff --git a/20230109/hp-uebung-20230109.tex b/20230109/hp-uebung-20230109.tex new file mode 100644 index 0000000000000000000000000000000000000000..e74dbe9a04de7ba9eb0de465392b0d840323d5cd --- /dev/null +++ b/20230109/hp-uebung-20230109.tex @@ -0,0 +1,350 @@ +% hp-uebung-20230109.pdf - Exercises on Low-Level Programming / Applied Computer Sciences +% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Peter Gerwinski +% +% This document is free software: you can redistribute it and/or +% modify it either under the terms of the Creative Commons +% Attribution-ShareAlike 3.0 License, or under the terms of the +% GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% This document is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this document. If not, see <http://www.gnu.org/licenses/>. +% +% You should have received a copy of the Creative Commons +% Attribution-ShareAlike 3.0 Unported License along with this +% document. If not, see <http://creativecommons.org/licenses/>. + +% README: Einfach und doppelt verkettete Listen, ternärer Baum, hüpfender Ball, Hexdumps + +% ! Hüpfender Ball (20211206-3) +% ! Hexdumps (20220110-3) +% ! einfach und doppelt verkettete Listen (20220117-2) +% ! ternärer Baum (20220117-3) + +\documentclass[a4paper]{article} + +\usepackage{pgscript} +\usepackage{tikz} + +\begin{document} + + \section*{Hardwarenahe Programmierung\\ + Übungsaufgaben -- 9.\ Januar 2023} + + Diese Übung enthält Punkteangaben wie in einer Klausur. + Um zu "`bestehen"', müssen Sie innerhalb von 120 Minuten + unter Verwendung ausschließlich zugelassener Hilfsmittel + 20 Punkte (von insgesamt \totalpoints) erreichen. + + \exercise{Einfach und doppelt verkettete Listen} + + Das Beispiel-Programm \gitfile{hp}{2022ws/20230109}{aufgabe-1.c} + demonstriert zwei Funktionen zur Verwaltung einfach verketteter Listen: + \lstinline{output_list()} zum Ausgeben der Liste auf den Bildschirm und + \lstinline{insert_into_list()} zum Einfügen in die Liste. + + \begin{enumerate}[\quad(a)] + \item + Ergänzen Sie eine Funktion \lstinline{delete_from_list()} + zum Löschen eines Elements aus der Liste + mit Freigabe des Speicherplatzes. + \points{5} + \item + Ergänzen Sie eine Funktion \lstinline{reverse_list()} + die die Reihenfolge der Elemente in der Liste umdreht.\\ + \points{3} + \end{enumerate} + + Eine doppelt verkettete Liste hat in jedem Knotenpunkt (\lstinline{node}) + \emph{zwei\/} Zeiger -- einen auf das nächste Element (\lstinline{next}) + und einen auf das vorherige Element (z.\,B.\ \lstinline{prev} für "`previous"'). + Dadurch ist es leichter als bei einer einfach verketteten Liste, + die Liste in umgekehrter Reihenfolge durchzugehen. + + \begin{quote} + \begin{tikzpicture} + \color{blendedblue} + \node(first) at (0,3.5) {first}; + \node(NULL1) at (-1,1.25) {NULL}; + \node[shape=rectangle,draw,line width=1pt](3) at (1,2) {3}; + \node[shape=rectangle,draw,line width=1pt](7) at (3,2) {7}; + \node[shape=rectangle,draw,line width=1pt](137) at (5,2) {137}; + \node(NULL2) at (7,2.75) {NULL}; + \draw[-latex](first)--(3); + \draw[-latex](3) to[out=45,in=135] (7); + \draw[-latex](3) to[out=-135,in=0] (NULL1); + \draw[-latex](7) to[out=-135,in=-45] (3); + \draw[-latex](7) to[out=45,in=135] (137); + \draw[-latex](137) to[out=-135,in=-45] (7); + \draw[-latex](137) to[out=45,in=180] (NULL2); + \end{tikzpicture} + \end{quote} + + Der Rückwärts-Zeiger (\lstinline{prev}) des ersten Elements zeigt, + genau wie der Vorwärts-Zeiger (\lstinline{next}) des letzten Elements, + auf \emph{nichts}, hat also den Wert \lstinline{NULL}. + + \begin{enumerate}[\quad(a)]\setcounter{enumi}{2} + \item + Schreiben Sie das Programm um für doppelt verkettete Listen. + \points{5} + \end{enumerate} + + \vspace{3cm} + + \exercise{Ternärer Baum} + + Der in der Vorlesung vorgestellte \newterm{binäre Baum\/} + ist nur ein Spezialfall; + im allgemeinen können Bäume auch mehr als zwei Verzweigungen + pro Knotenpunkt haben. + Dies ist nützlich bei der Konstruktion \emph{balancierter Bäume}, + also solcher, die auch im \emph{Worst Case\/} + nicht zu einer linearen Liste entarten, + sondern stets eine -- möglichst flache -- Baumstruktur behalten. + + Wir betrachten einen Baum mit bis zu drei Verzweigungen pro Knotenpunkt, + einen sog.\ \newterm{ternären Baum}. + Jeder Knoten enthält dann nicht nur einen, + sondern \emph{zwei\/} Werte als Inhalt: + \begin{lstlisting} + typedef struct node + { + int content_left, content_right; + struct node *left, *middle, *right; + } node; + \end{lstlisting} + + Wir konstruieren nun einen Baum nach folgenden Regeln: + \vspace{-\medskipamount} + \begin{itemize}\itemsep0pt + \item + Innerhalb eines Knotens sind die Werte sortiert: + \lstinline{content_left} muß stets kleiner sein als \lstinline{content_right}. + \item + Der Zeiger \lstinline{left} zeigt auf Knoten, + deren enthaltene Werte durchweg kleiner sind als \lstinline{content_left}. + \item + Der Zeiger \lstinline{right} zeigt auf Knoten, + deren enthaltene Werte durchweg größer sind als \lstinline{content_right}. + \item + Der Zeiger \lstinline{middle} zeigt auf Knoten, + deren enthaltene Werte durchweg größer sind als \lstinline{content_left}, + aber kleiner als \lstinline{content_right}. + \item + Ein Knoten muß nicht immer mit zwei Werten voll besetzt sein; + er darf auch \emph{nur einen\/} gültigen Wert enthalten. + + Der Einfachheit halber lassen wir in diesem Beispiel + nur positive Zahlen als Werte zu. + Wenn ein Knoten nur einen Wert enthält, + setzen wir \lstinline{content_right = -1}, + und der Zeiger \lstinline{middle} wird nicht verwendet. + \item + Wenn wir neue Werte in den Baum einfügen, + werden \emph{zuerst\/} die nicht voll besetzten Knoten aufgefüllt + und \emph{danach erst\/} neue Knoten angelegt und Zeiger gesetzt. + \item + Beim Auffüllen eines Knotens darf nötigenfalls \lstinline{content_left} + nach \lstinline{content_right} verschoben werden. + Ansonsten werden einmal angelegte Knoten nicht mehr verändert. + \end{itemize} + \vspace*{-\medskipamount} + (In der Praxis dürfen Knoten gemäß speziellen Regeln + nachträglich verändert werden, + um Entartungen gar nicht erst entstehen zu lassen -- + siehe z.\,B.\ \url{https://en.wikipedia.org/wiki/2-3_tree}.) + \begin{enumerate}[\quad(a)] + \item + Zeichnen Sie ein Schaubild, das veranschaulicht, + wie die Zahlen 7, 137, 3, 5, 6, 42, 1, 2 und 12 + nacheinander und in dieser Reihenfolge + in den oben beschriebenen Baum eingefügt werden + -- analog zu den Vortragsfolien (\gitfile{hp}{2022ws/20221219}{hp-20221219.pdf}), + Seite 33. + \points{3} + % + % Lösung: + % + % 7 137 + % / | + % 3 5 12 42 + % / \ + % 1 2 6 + % + % (NULL-Zeiger sind hier nicht dargestellt, + % gehören aber dazu.) + % + \item + Dasselbe, aber in der Reihenfolge + 2, 7, 42, 12, 1, 137, 5, 6, 3. + \points{3} + % + % Lösung: + % + % 2 7 + % / | \ + % 1 5 6 12 42 + % / \ + % 3 137 + % + % (NULL-Zeiger sind hier wieder nicht dargestellt, + % gehören aber dazu.) + % + \item + Beschreiben Sie in Worten und/oder als C-Quelltext-Fragment, + wie eine Funktion aussehen müßte, um den auf diese Weise entstandenen Baum + sortiert auszugeben. + \points{4} + \end{enumerate} + + \vspace{3cm} + + \exercise{Fehlerhaftes Programm: Hüpfender Ball} + + Das auf der nächsten Seite abgedruckte GTK+-Programm + (Datei: \gitfile{hp}{2022ws/20230109}{aufgabe-3.c}) soll einen + hüpfenden Ball darstellen, ist jedoch fehlerhaft. + + \begin{enumerate}[\quad(a)] + \item + Warum sieht man lediglich ein leeres Fenster? + Welchen Befehl muß man ergänzen, um diesen Fehler zu beheben? + \points{3} + \item + Nach der Fehlerbehebung in Aufgabenteil (a) + zeigt das Programm einen unbeweglichen Ball. + Welchen Befehl muß man ergänzen, um diesen Fehler zu beheben, und warum? + \points{2} + \item + Erklären Sie das merkwürdige Hüpfverhalten des Balls. + Wie kommt es zustande? + Was an diesem Verhalten ist korrekt, und was ist fehlerhaft? \points{5} + \item + Welche Befehle muß man in welcher Weise ändern, + um ein realistischeres Hüpf-Verhalten zu bekommen? \points{2} + \end{enumerate} + + Hinweis: Das Hinzuziehen von Beispiel-Programmen aus der Vorlesung + ist ausdrücklich erlaubt -- auch in der Klausur. + + Allgemeiner Hinweis: + Wenn Sie die Übungsaufgaben zu dieser Lehrveranstaltung + als PDF-Datei betrachten und darin auf die Dateinamen klicken, + können Sie die Beispiel-Programme direkt herunterladen. + Dadurch vermeiden Sie Übertragungsfehler. + + \clearpage + + \vbox to \textheight{\vspace*{-0.5cm}\begin{lstlisting} + #include <gtk/gtk.h> + + #define WIDTH 320 + #define HEIGHT 240 + + double t = 0.0; + double dt = 0.2; + + int r = 5; + + double x = 10; + double y = 200; + double vx = 20; + double vy = -60; + double g = 9.81; + + gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data) + { + GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 }; + + gdk_cairo_set_source_rgba (c, &blue); + cairo_arc (c, x, y, r, 0, 2 * G_PI); + cairo_fill (c); + + return FALSE; + } + + gboolean timer (GtkWidget *widget) + { + t += dt; + x += vx * dt; + y += vy * dt; + vx = vx; + vy = 0.5 * g * (t * t); + if (y + r >= HEIGHT) + vy = -vy * 0.9; + if (x + r >= WIDTH) + vx = -vx * 0.9; + if (x - r <= 0) + vx = -vx * 0.9; + gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT); + g_timeout_add (50, (GSourceFunc) timer, widget); + return FALSE; + } + + int main (int argc, char **argv) + { + gtk_init (&argc, &argv); + + GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_show (window); + gtk_window_set_title (GTK_WINDOW (window), "Hello"); + g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); + + GtkWidget *drawing_area = gtk_drawing_area_new (); + gtk_widget_show (drawing_area); + gtk_container_add (GTK_CONTAINER (window), drawing_area); + gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT); + + gtk_main (); + return 0; + } + \end{lstlisting}\vss} + + \exercise{Hexdumps} + + Das folgende Programm (\gitfile{hp}{2022ws/20230109}{aufgabe-4.c}) liest + einen String ein und gibt die ASCII-Werte der Buchstaben hexadezimal aus. + (Anders als z.\,B.\ \lstinline{scanf()} + akzeptiert die Funktion \lstinline{fgets()} zum Lesen von Strings auch Leerzeichen, + und sie vermeidet Pufferüberläufe.) + \begin{lstlisting}[style=numbered] + #include <stdio.h> + + int main (void) + { + char buffer[100]; + fgets (buffer, 100, stdin); + for (char *p = buffer; *p; p++) + printf ("%02x", *p); + printf ("\n"); + } + \end{lstlisting} + Beispiel: Bei der Eingabe von \lstinline[style=cmd]{Dies ist ein Test.} + erscheint die Ausgabe\\ + \lstinline[style=terminal]{44696573206973742065696e20546573742e0a}. + + Schreiben Sie ein Programm, das diese Umwandlung in umgekehrter Richtung vornimmt, + also z.\,B.\ bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a} + wieder \lstinline[style=terminal]{Dies ist ein Test.} ausgibt. + + \points{6} + + Hinweis für die Klausur: + Abgabe in digitaler Form ist erwünscht, aber nicht zwingend. + + \begin{flushright} + \textit{Viel Erfolg -- auch in den Prüfungen!} + \end{flushright} + + \makeatletter + \immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}} + \makeatother + +\end{document} diff --git a/20230109/loesung-1a.c b/20230109/loesung-1a.c new file mode 100644 index 0000000000000000000000000000000000000000..93f5e5629a98d13d6292c56d1a3f855b4f5bd8fd --- /dev/null +++ b/20230109/loesung-1a.c @@ -0,0 +1,69 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *next; +} node; + +void output_list (node *first) +{ + for (node *p = first; p; p = p->next) + printf ("%d ", p->content); + printf ("\n"); +} + +void insert_into_list (node *what, node *where) +{ + what->next = where->next; + where->next = what; +} + +void delete_from_list (node *what, node **first) +{ + if (what == *first) + *first = what->next; + else + { + node *p = *first; + while (p && p->next != what) + p = p->next; + if (p) + p->next = what->next; + } + free (what); +} + +int main (void) +{ + node *element3 = malloc (sizeof (node)); + node *element7 = malloc (sizeof (node)); + node *element137 = malloc (sizeof (node)); + + element3->content = 3; + element7->content = 7; + element137->content = 137; + + node *first = element3; + element3->next = element7; + element7->next = element137; + element137->next = NULL; + + output_list (first); + + node *element5 = malloc (sizeof (node)); + element5->content = 5; + insert_into_list (element5, element3); + + output_list (first); + + delete_from_list (element5, &first); + output_list (first); + delete_from_list (element3, &first); + output_list (first); + delete_from_list (element137, &first); + output_list (first); + + return 0; +} diff --git a/20230109/loesung-1b.c b/20230109/loesung-1b.c new file mode 100644 index 0000000000000000000000000000000000000000..811b99b1fc9697ca0302eea8950c9bc6e7ab6042 --- /dev/null +++ b/20230109/loesung-1b.c @@ -0,0 +1,97 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content; + struct node *next, *prev; +} node; + +void check_list (node *first) +{ + for (node *p = first; p; p = p->next) + { + if (p->next && p->next->prev != p) + fprintf (stderr, "List inconsistency!\n"); + if (p->prev && p->prev->next != p) + fprintf (stderr, "List inconsistency!\n"); + } +} + +void output_list (node *first) +{ + for (node *p = first; p; p = p->next) + printf ("%d ", p->content); + printf ("\n"); +} + +void insert_into_list (node *what, node *where) +{ + what->next = where->next; + if (where->next) + where->next->prev = what; + what->prev = where; + where->next = what; +} + +void delete_from_list (node *what, node **first) +{ + if (what == *first) + { + *first = what->next; + if (*first) + (*first)->prev = NULL; + } + else + { + node *p = *first; + while (p && p->next != what) + p = p->next; + if (p) + p->next = what->next; + if (what->next) + what->next->prev = p; + } + free (what); +} + +int main (void) +{ + node *element3 = malloc (sizeof (node)); + node *element7 = malloc (sizeof (node)); + node *element137 = malloc (sizeof (node)); + + element3->content = 3; + element7->content = 7; + element137->content = 137; + + node *first = element3; + element3->prev = NULL; + element3->next = element7; + element7->prev = element3; + element7->next = element137; + element137->prev = element7; + element137->next = NULL; + + output_list (first); + check_list (first); + + node *element5 = malloc (sizeof (node)); + element5->content = 5; + insert_into_list (element5, element3); + + output_list (first); + check_list (first); + + delete_from_list (element5, &first); + output_list (first); + check_list (first); + delete_from_list (element3, &first); + output_list (first); + check_list (first); + delete_from_list (element137, &first); + output_list (first); + check_list (first); + + return 0; +} diff --git a/20230109/loesung-2c.c b/20230109/loesung-2c.c new file mode 100644 index 0000000000000000000000000000000000000000..a6dea990b25895475e343f07895c6a946426d2d8 --- /dev/null +++ b/20230109/loesung-2c.c @@ -0,0 +1,68 @@ +#include <stdio.h> +#include <stdlib.h> + +typedef struct node +{ + int content_left, content_right; + struct node *left, *middle, *right; +} node; + +void insert_into_tree (node **root, int value) +{ + if (*root) + { + if ((*root)->content_right >= 0) + if (value < (*root)->content_left) + insert_into_tree (&(*root)->left, value); + else if (value < (*root)->content_right) + insert_into_tree (&(*root)->middle, value); + else + insert_into_tree (&(*root)->right, value); + else + if (value < (*root)->content_left) + { + (*root)->content_right = (*root)->content_left; + (*root)->content_left = value; + } + else + (*root)->content_right = value; + } + else + { + *root = malloc (sizeof (node)); + (*root)->left = NULL; + (*root)->content_left = value; + (*root)->middle = NULL; + (*root)->content_right = -1; + (*root)->right = NULL; + } +} + +void output_tree (node *root) +{ + if (root) + { + output_tree (root->left); + printf ("%d\n", root->content_left); + output_tree (root->middle); + if (root->content_right >= 0) + printf ("%d\n", root->content_right); + output_tree (root->right); + } +} + +int main (void) +{ + node *root = NULL; + insert_into_tree (&root, 7); + insert_into_tree (&root, 137); + insert_into_tree (&root, 3); + insert_into_tree (&root, 5); + insert_into_tree (&root, 6); + insert_into_tree (&root, 42); + insert_into_tree (&root, 1); + insert_into_tree (&root, 2); + insert_into_tree (&root, 12); + output_tree (root); + return 0; +} diff --git a/20230109/loesung-4.c b/20230109/loesung-4.c new file mode 100644 index 0000000000000000000000000000000000000000..872058ac9fecdcb59ac1104ca67841cb3dc974a9 --- /dev/null +++ b/20230109/loesung-4.c @@ -0,0 +1,28 @@ +#include <stdio.h> + +int read_hex (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else + { + fprintf (stderr, "invalid hex digit '%c'\n", c); + return 0; + } +} + +int main (void) +{ + char buffer[100]; + fgets (buffer, 100, stdin); + for (char *p = buffer; p[0] && p[1]; p += 2) + { + char c = 16 * read_hex (p[0]) + read_hex (p[1]); + printf ("%c", c); + } + printf ("\n"); +} diff --git a/20230109/logo-hochschule-bochum-cvh-text-v2.pdf b/20230109/logo-hochschule-bochum-cvh-text-v2.pdf new file mode 120000 index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8 --- /dev/null +++ b/20230109/logo-hochschule-bochum-cvh-text-v2.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum-cvh-text-v2.pdf \ No newline at end of file diff --git a/20230109/logo-hochschule-bochum.pdf b/20230109/logo-hochschule-bochum.pdf new file mode 120000 index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1 --- /dev/null +++ b/20230109/logo-hochschule-bochum.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum.pdf \ No newline at end of file diff --git a/20230109/pgscript.sty b/20230109/pgscript.sty new file mode 120000 index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b --- /dev/null +++ b/20230109/pgscript.sty @@ -0,0 +1 @@ +../common/pgscript.sty \ No newline at end of file diff --git a/README.md b/README.md index 3ddb14b19a44834df18d846b5b47432b73996be5..583ac081047ac170412f57d62da3988669520b2c 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Vortragsfolien und Beispiele: * [21.11.2022: Aufwandsabschätzungen, Objektorientierte Programmierung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221121/hp-20221121.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2022ws/20221121/) * [28.11.2022: Objektorientierte Programmierung](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221128/hp-20221128.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2022ws/20221128/) * [05.12.2022: Objektorientierte Programmierung, Datenstrukturen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221205/hp-20221205.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2022ws/20221205/) - * [12.12.2022: Objektorientierte Programmierung, Datenstrukturen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221212/hp-20221212.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2022ws/20221212/) + * [19.12.2022: Objektorientierte Programmierung, Datenstrukturen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221219/hp-20221219.pdf) [**(Beispiele)**](https://gitlab.cvh-server.de/pgerwinski/hp/tree/2022ws/20221219/) * [alle in 1 Datei](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/hp-slides-2022ws.pdf) Übungsaufgaben: @@ -43,6 +43,7 @@ Vortragsfolien und Beispiele: * [28.11.2022: Einfügen in Strings (Ergänzung), dynamisches Bit-Array, objektorientierte Tier-Datenbank](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221128/hp-uebung-20221128.pdf) * [05.12.2022: Objektorientierte Tier-Datenbank (Ergänzung), Iterationsfunktionen, Stack-Operationen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221205/hp-uebung-20221205.pdf) * [12.12.2022: Länge von Strings (Neuauflage), Text-Grafik-Bibliothek, PBM-Grafik](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221212/hp-uebung-20221212.pdf) + * [09.01.2023: Einfach und doppelt verkettete Listen, ternärer Baum, hüpfender Ball, Hexdumps](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20230109/hp-uebung-20230109.pdf) Musterlösungen: --------------- @@ -56,6 +57,7 @@ Musterlösungen: * [28.11.2022: Einfügen in Strings (Ergänzung), dynamisches Bit-Array, objektorientierte Tier-Datenbank](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221128/hp-musterloesung-20221128.pdf) * [05.12.2022: Objektorientierte Tier-Datenbank (Ergänzung), Iterationsfunktionen, Stack-Operationen](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221205/hp-musterloesung-20221205.pdf) * [12.12.2022: Länge von Strings (Neuauflage), Text-Grafik-Bibliothek, PBM-Grafik](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20221212/hp-musterloesung-20221212.pdf) + * [09.01.2023: Einfach und doppelt verkettete Listen, ternärer Baum, hüpfender Ball, Hexdumps](https://gitlab.cvh-server.de/pgerwinski/hp/raw/2022ws/20230109/hp-musterloesung-20230109.pdf) Praktikumsunterlagen: ---------------------