diff --git a/20231019/gitlab.png b/20231019/gitlab.png deleted file mode 100644 index 5724da8b8338534857e5e845f1f1a9b67f0fab1a..0000000000000000000000000000000000000000 Binary files a/20231019/gitlab.png and /dev/null differ diff --git a/20231019/hp-20231019.pdf b/20231019/hp-20231019.pdf index 37ccf57ed6f0d63235ac4d4beae3a835c71f7993..2789c58506853019d478ba6bb4c5c07b702f91be 100644 Binary files a/20231019/hp-20231019.pdf and b/20231019/hp-20231019.pdf differ diff --git a/20231019/hp-20231019.tex b/20231019/hp-20231019.tex index 266ebe9007677bb157c8f0dda3141dc016b42725..78d595669e21cc2d2551a27dd44565eb1904b67e 100644 --- a/20231019/hp-20231019.tex +++ b/20231019/hp-20231019.tex @@ -1152,6 +1152,8 @@ \end{frame} +\iffalse + \begin{frame}[fragile] \showsubsection @@ -1304,4 +1306,6 @@ \end{frame} +\fi + \end{document} diff --git a/20231026/aufgabe-1.c b/20231026/aufgabe-1.c new file mode 100644 index 0000000000000000000000000000000000000000..632b4b796ae2f4060878a8870b9e7e55e5f064b9 --- /dev/null +++ b/20231026/aufgabe-1.c @@ -0,0 +1,22 @@ +#include <stdio.h> + +void f (int *s0, int *s1) +{ + while (*s0 >= 0) + { + int *s = s1; + while (*s >= 0) + if (*s0 == *s++) + printf ("%d ", *s0); + s0++; + } + printf ("\n"); +} + +int main (void) +{ + int a[] = { 10, 4, 3, 7, 12, 0, 1, -1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10, -1 }; + f (a, b); + return 0; +} diff --git a/20231026/aufgabe-1c.c b/20231026/aufgabe-1c.c new file mode 100644 index 0000000000000000000000000000000000000000..9b6e7ab2ecfbddc16121acd229a13745182190c2 --- /dev/null +++ b/20231026/aufgabe-1c.c @@ -0,0 +1,22 @@ +#include <stdio.h> + +void f (int *s0, int *s1) +{ + while (*s0 >= 0) + { + int *s = s1; + while (*s >= 0) + if (*s0 == *s++) + printf ("%d ", *s0); + s0++; + } + printf ("\n"); +} + +int main (void) +{ + int a[] = { 10, 4, 3, 7, 12, 0, 1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10 }; + f (a, b); + return 0; +} diff --git a/20231026/aufgabe-3.c b/20231026/aufgabe-3.c new file mode 100644 index 0000000000000000000000000000000000000000..cd80c21b95b5a4c91a43a8b3e849f5e12db183c7 --- /dev/null +++ b/20231026/aufgabe-3.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main (void) +{ + int n, i, divisors; + for (n = 0; n < 100; n++) + divisors = 0; + for (i = 0; i < n; i++) + if (n % i == 0) + divisors++; + if (divisors = 2) + printf ("%d ist eine Primzahl.\n", n); + return 0; +} diff --git a/20231026/gtk-01.c b/20231026/gtk-01.c new file mode 100644 index 0000000000000000000000000000000000000000..6e4cf8a819c88092ecb039ad9221611f5577d925 --- /dev/null +++ b/20231026/gtk-01.c @@ -0,0 +1,17 @@ +#include <gtk/gtk.h> + +static void activate (GtkApplication *app, gpointer user_data) +{ + GtkWidget *window = gtk_application_window_new (app); + gtk_window_set_title (GTK_WINDOW (window), "Hello"); + gtk_window_present (GTK_WINDOW (window)); +} + +int main (int argc, char **argv) +{ + GtkApplication *app = gtk_application_new ("de.hs-bochum.cvh.hp.hello-gtk", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + int status = g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return status; +} diff --git a/20231026/gtk-02.c b/20231026/gtk-02.c new file mode 100644 index 0000000000000000000000000000000000000000..507acdf0cd745527e56defbded7c6c70bfe642e3 --- /dev/null +++ b/20231026/gtk-02.c @@ -0,0 +1,26 @@ +#include <gtk/gtk.h> + +static void hello (GtkWidget *this, gpointer user_data) +{ + char *world = user_data; + printf ("Hello, %s!\n", world); +} + +static void activate (GtkApplication *app, gpointer user_data) +{ + GtkWidget *window = gtk_application_window_new (app); + gtk_window_set_title (GTK_WINDOW (window), "Hello"); + GtkWidget *button = gtk_button_new_with_label ("Hello, world!"); + g_signal_connect (button, "clicked", G_CALLBACK (hello), "world"); + gtk_window_set_child (GTK_WINDOW (window), button); + gtk_window_present (GTK_WINDOW (window)); +} + +int main (int argc, char **argv) +{ + GtkApplication *app = gtk_application_new ("de.hs-bochum.cvh.hp.hello-gtk", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + int status = g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return status; +} diff --git a/20231026/gtk-03.c b/20231026/gtk-03.c new file mode 100644 index 0000000000000000000000000000000000000000..4fe3a030783bc3075bae4a85705085d0e36b8d5c --- /dev/null +++ b/20231026/gtk-03.c @@ -0,0 +1,26 @@ +#include <gtk/gtk.h> + +static void close_window (GtkWidget *this, gpointer user_data) +{ + GtkWindow *window = user_data; + gtk_window_destroy (window); +} + +static void activate (GtkApplication *app, gpointer user_data) +{ + GtkWidget *window = gtk_application_window_new (app); + gtk_window_set_title (GTK_WINDOW (window), "Hello"); + GtkWidget *button = gtk_button_new_with_label ("Quit"); + g_signal_connect (button, "clicked", G_CALLBACK (close_window), window); + gtk_window_set_child (GTK_WINDOW (window), button); + gtk_window_present (GTK_WINDOW (window)); +} + +int main (int argc, char **argv) +{ + GtkApplication *app = gtk_application_new ("de.hs-bochum.cvh.hp.hello-gtk", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + int status = g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return status; +} diff --git a/20231026/gtk-04.c b/20231026/gtk-04.c new file mode 100644 index 0000000000000000000000000000000000000000..6ae0e7dca8ad959bcf22fb275d6a78a5f39c00f5 --- /dev/null +++ b/20231026/gtk-04.c @@ -0,0 +1,20 @@ +#include <gtk/gtk.h> + +static void activate (GtkApplication *app, gpointer user_data) +{ + GtkWidget *window = gtk_application_window_new (app); + gtk_window_set_title (GTK_WINDOW (window), "Hello"); + GtkWidget *button = gtk_button_new_with_label ("Quit"); + g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window); + gtk_window_set_child (GTK_WINDOW (window), button); + gtk_window_present (GTK_WINDOW (window)); +} + +int main (int argc, char **argv) +{ + GtkApplication *app = gtk_application_new ("de.hs-bochum.cvh.hp.hello-gtk", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + int status = g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return status; +} diff --git a/20231026/gtk-05.c b/20231026/gtk-05.c new file mode 100644 index 0000000000000000000000000000000000000000..a7394ee1faf9c92fe04a7ca5e95b79a63d9c3b66 --- /dev/null +++ b/20231026/gtk-05.c @@ -0,0 +1,35 @@ +#include <gtk/gtk.h> + +static void hello (GtkWidget *this, gpointer user_data) +{ + char *world = user_data; + printf ("Hello, %s!\n", world); +} + +static void activate (GtkApplication *app, gpointer user_data) +{ + GtkWidget *window = gtk_application_window_new (app); + gtk_window_set_title (GTK_WINDOW (window), "Hello"); + + GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); + gtk_window_set_child (GTK_WINDOW (window), vbox); + + GtkWidget *hello_button = gtk_button_new_with_label ("Hello, world!"); + g_signal_connect (hello_button, "clicked", G_CALLBACK (hello), "world"); + gtk_box_append (GTK_BOX (vbox), hello_button); + + GtkWidget *quit_button = gtk_button_new_with_label ("Quit"); + g_signal_connect_swapped (quit_button, "clicked", G_CALLBACK (gtk_window_destroy), window); + gtk_box_append (GTK_BOX (vbox), quit_button); + + gtk_window_present (GTK_WINDOW (window)); +} + +int main (int argc, char **argv) +{ + GtkApplication *app = gtk_application_new ("de.hs-bochum.cvh.hp.hello-gtk", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + int status = g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return status; +} diff --git a/20231026/gtk-06.c b/20231026/gtk-06.c new file mode 100644 index 0000000000000000000000000000000000000000..64687de0440a694d1f644de4f2a180a37987ff84 --- /dev/null +++ b/20231026/gtk-06.c @@ -0,0 +1,53 @@ +#include <gtk/gtk.h> + +static void draw (GtkDrawingArea *drawing_area, cairo_t *c, + int width, int height, gpointer user_data) +{ + GdkRGBA red = { 1.0, 0.0, 0.0, 0.8 }; + GdkRGBA yellow = { 1.0, 1.0, 0.0, 0.6 }; + GdkRGBA blue = { 0.0, 0.5, 1.0, 0.4 }; + + gdk_cairo_set_source_rgba (c, &red); + cairo_rectangle (c, 10, 10, 60, 40); + cairo_fill (c); + + gdk_cairo_set_source_rgba (c, &yellow); + cairo_arc (c, 65, 50, 30, 0, 2 * G_PI); + cairo_fill (c); + + gdk_cairo_set_source_rgba (c, &blue); + cairo_move_to (c, 10, 70); + cairo_line_to (c, 70, 70); + cairo_line_to (c, 40, 18); + cairo_close_path (c); + cairo_fill (c); +} + +static void activate (GtkApplication *app, gpointer user_data) +{ + GtkWidget *window = gtk_application_window_new (app); + gtk_window_set_title (GTK_WINDOW (window), "Hello"); + + GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); + gtk_window_set_child (GTK_WINDOW (window), vbox); + + GtkWidget *drawing_area = gtk_drawing_area_new (); + gtk_widget_set_size_request (drawing_area, 100, 100); + gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area), draw, NULL, NULL); + gtk_box_append (GTK_BOX (vbox), drawing_area); + + GtkWidget *quit_button = gtk_button_new_with_label ("Quit"); + g_signal_connect_swapped (quit_button, "clicked", G_CALLBACK (gtk_window_destroy), window); + gtk_box_append (GTK_BOX (vbox), quit_button); + + gtk_window_present (GTK_WINDOW (window)); +} + +int main (int argc, char **argv) +{ + GtkApplication *app = gtk_application_new ("de.hs-bochum.cvh.hp.hello-gtk", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + int status = g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + return status; +} diff --git a/20231026/hexe.h b/20231026/hexe.h new file mode 100644 index 0000000000000000000000000000000000000000..2b98e2bb0231a5114084d64430290fea93281edc --- /dev/null +++ b/20231026/hexe.h @@ -0,0 +1 @@ +eine kleine Hexe. diff --git a/20231026/hp-20231026.pdf b/20231026/hp-20231026.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ca79ca5a6b4a3df11a0a9db2f0f526ff41738ac1 Binary files /dev/null and b/20231026/hp-20231026.pdf differ diff --git a/20231026/hp-20231026.tex b/20231026/hp-20231026.tex new file mode 100644 index 0000000000000000000000000000000000000000..6fb14dbf14f7ded25d0e9c45b18e8bf2403c0730 --- /dev/null +++ b/20231026/hp-20231026.tex @@ -0,0 +1,1304 @@ +% hp-20231026.pdf - Lecture Slides on Low-Level Programming +% Copyright (C) 2012, 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: Einführung in C: String-Operationen; Bibliotheken + +\documentclass[10pt,t]{beamer} + +\usepackage{pgslides} +\usepackage{pdftricks} +\usepackage{tikz} + +\begin{psinputs} + \usepackage[utf8]{inputenc} + \usepackage[german]{babel} + \usepackage[T1]{fontenc} + \usepackage{helvet} + \renewcommand*\familydefault{\sfdefault} + \usepackage{pstricks,pst-grad} +\end{psinputs} + +\newcommand{\redurl}[1]{\href{#1}{\color{red}\nolinkurl{#1}}} + +\title{Hardwarenahe Programmierung} +\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski} +\date{26.\ Oktober 2023} + +\begin{document} + +\maketitleframe + +%\date{\begin{picture}(0,0) +% \color{red} +% \put(0.65,1.05){\makebox(0,0)[t]{$\underbrace{\rule{1.45cm}{0pt}}_{% +% \mbox{\emph{rerum naturalium\/} = der natürlichen Dinge (lat.)}}$}} +% \put(1.65,-3){\makebox(0,0)[bl]{\redurl{https://www.peter.gerwinski.de/physik/}}} +% \end{picture}% +% 12.\ Oktober 2023} +% +%\maketitleframe + +\title{Hardwarenahe Programmierung} + +\nosectionnonumber{\inserttitle} + +\begin{frame} + + \shownosectionnonumber + + \begin{itemize} + \item[\textbf{1}] \textbf{Einführung} + \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}} + \item[\textbf{2}] \textbf{Einführung in C} + \begin{itemize} + \vspace{-1.5\smallskipamount} + \item[\dots] + \item[2.7] Strukturierte Programmierung + \item[2.8] Seiteneffekte + \item[2.9] Funktionen + \item[2.10] Zeiger + \color{medgreen} + \item[2.11] Arrays und Strings + \item[2.12] Strukturen + \item[2.13] Dateien und Fehlerbehandlung + \item[2.14] Parameter des Hauptprogramms + \color{orange} + \item[2.15] String-Operationen + \end{itemize} + \item[\textbf{3}] \textbf{Bibliotheken} + \vspace*{-\smallskipamount} + \item[\textbf{\dots}] +% \item[\textbf{4}] \textbf{Hardwarenahe Programmierung} +% \item[\textbf{5}] \textbf{Algorithmen} +% \item[\textbf{6}] \textbf{Ergänzungen und Ausblicke} + \end{itemize} + +\end{frame} + +\section{Einführung} +\section{Einführung in C} +\setcounter{subsection}{10} +\subsection{Arrays und Strings} + +\begin{frame}[fragile] + \showsubsection + + Ein Zeiger zeigt auf eine Variable\only<2->{ und deren Nachbarn}. + + \bigskip + \pause + \pause + + \begin{onlyenv}<1-8> + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + int main (void) + { + int prime[5] = { 2, 3, 5, 7, 11 }; + int *p = prime; + for (int i = 0; i < 5; i++) + printf ("%d\n", *(p + i)); + return 0; + } + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<9> + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + int main (void) + { + int prime[5] = { 2, 3, 5, 7, 11 }; + int *p = prime; + for (int i = 0; i < 5; i++) + printf ("%d\n", p[i]); + return 0; + } + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<10> + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + int main (void) + { + int prime[5] = { 2, 3, 5, 7, 11 }; + for (int i = 0; i < 5; i++) + printf ("%d\n", prime[i]); + return 0; + } + ¡ ¿ + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<11> + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + int main (void) + { + int prime[5] = { 2, 3, 5, 7, 11 }; + for (int *p = prime; + p < prime + 5; p++) + printf ("%d\n", *p); + return 0; + } + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<12> + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + int main (void) + { + int prime[6] = { 2, 3, 5, 7, 11, 0 }; + for (int *p = prime; *p; p++) + printf ("%d\n", *p); + return 0; + } + ¡ ¿ + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<13-> + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + int main (void) + { + int prime[] = { 2, 3, 5, 7, 11, 0 }; + for (int *p = prime; *p; p++) + printf ("%d\n", *p); + return 0; + } + ¡ ¿ + \end{lstlisting} + \end{onlyenv} + + \pause + \vspace{-3.05cm}\hspace{5.5cm}% + \begin{minipage}{6.5cm} + \begin{itemize} + \item + \lstinline{prime} ist \alt<5->{ein Array}{eine Ansammlung} von\\fünf ganzen Zahlen. + \pause + \pause + \item + \only<6-9>{\begin{picture}(0,0) + \color{red} + \put(-1.6,0.1){\tikz{\draw[-latex](0.0,0.0)--(-1,0);}} + \end{picture}}% + \lstinline{prime} ist ein Zeiger auf eine \lstinline{int}. + \pause + \item + \lstinline{p + i} ist ein Zeiger\\ + auf den \lstinline{i}-ten Nachbarn von \lstinline{*p}. + \pause + \item + \lstinline{*(p + i)} ist der \lstinline{i}-te Nachbar von \lstinline{*p}. + \pause + \item + Andere Schreibweise:\\ + \lstinline{p[i]} statt \lstinline{*(p + i)} + \pause + \pause + \item + Zeiger-Arithmetik:\\ + \lstinline{p++} rückt den Zeiger \lstinline{p}\\ + um eine \lstinline{int} weiter. + \pause + \pause + \item + Array ohne \only<14->{explizite }Längenangabe:\\ + Compiler zählt selbst + \vspace*{-1cm} + \pause + \begin{picture}(0,0) + \put(-5.2,1.0){\makebox(0,0)[br]{\color{red}\bf\shortstack{Die Länge des Arrays\\ist \emph{nicht\/} veränderlich!}}} + \end{picture} + \end{itemize} + \end{minipage} +\end{frame} + +\nosectionnonumber{\inserttitle} + +\begin{frame} + + \shownosectionnonumber + + \begin{itemize} + \item[\textbf{1}] \textbf{Einführung} + \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}} + \item[\textbf{2}] \textbf{Einführung in C} + \begin{itemize} + \vspace{-1.5\smallskipamount} + \item[\dots] + \item[2.5] Verzweigungen + \item[2.6] Schleifen + \color{medgreen} + \item[2.7] Strukturierte Programmierung + \item[2.8] Seiteneffekte + \item[2.9] Funktionen + \item[2.10] Zeiger + \color{orange} + \item[2.11] Arrays und Strings + \color{red} + \item[2.12] Strukturen + \item[2.13] Dateien und Fehlerbehandlung + \item[2.14] Parameter des Hauptprogramms + \item[2.15] String-Operationen + \end{itemize} + \color{gray} + \item[\textbf{3}] \textbf{Bibliotheken} + \vspace*{-\smallskipamount} + \item[\textbf{\dots}] +% \item[\textbf{4}] \textbf{Hardwarenahe Programmierung} +% \item[\textbf{5}] \textbf{Algorithmen} +% \item[\textbf{6}] \textbf{Ergänzungen und Ausblicke} + \end{itemize} + \vspace*{-1cm} + +\end{frame} + +% \begin{frame}[fragile] +% \showsubsection +% +% \begin{lstlisting} +% #include <stdio.h> +% +% int main (void) +% { +% char hello_world[] = "Hello, world!\n"; +% int i = 0; +% while (hello_world[i] != 0) +% printf ("%d", hello_world[i++]); +% return 0; +% } +% \end{lstlisting} +% \end{frame} + +% \begin{frame}[fragile] +% \showsubsection +% +% \begin{lstlisting} +% #include <stdio.h> +% +% int main (void) +% { +% char hello_world[] = "Hello, world!\n"; +% int i = 0; +% while (hello_world[i]) +% printf ("%d", hello_world[i++]); +% return 0; +% } +% \end{lstlisting} +% \end{frame} + +% \begin{frame}[fragile] +% \showsubsection +% +% \begin{lstlisting} +% #include <stdio.h> +% +% int main (void) +% { +% char hello_world[] = "Hello, world!\n"; +% char *p = hello_world; +% while (*p) +% printf ("%c", *p++); +% return 0; +% } +% \end{lstlisting} +% \end{frame} + +\begin{frame}[fragile] + \showsubsection + + \begin{onlyenv}<1-6> + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + int main (void) + { + char hello[] = "Hello, world!\n"; + for (char *p = hello; *p; p++) + printf ("%d", *p); + return 0; + } + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<7> + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + int main (void) + { + char hello[] = "Hello, world!\n"; + for (char *p = hello; *p; p++) + printf ("%c", *p); + return 0; + } + \end{lstlisting} + \end{onlyenv} +% \begin{onlyenv}<8> +% \begin{lstlisting}[gobble=6] +% #include <stdio.h> +% +% int main (void) +% { +% char hello[] = "Hello, world!\n"; +% printf ("%s", hello); +% return 0; +% } +% ¡ ¿ +% \end{lstlisting} +% \end{onlyenv} +% \begin{onlyenv}<9> +% \begin{lstlisting}[gobble=6] +% #include <stdio.h> +% +% int main (void) +% { +% char *hello = "Hello, world!\n"; +% printf ("%s", hello); +% return 0; +% } +% ¡ ¿ +% \end{lstlisting} +% \end{onlyenv} +% \begin{onlyenv}<10> +% \begin{lstlisting}[gobble=6] +% #include <stdio.h> +% +% int main (void) +% { +% char *hello = "Hello, world!\n"; +% while (*hello) +% printf ("%c", *hello++); +% return 0; +% } +% \end{lstlisting} +% \end{onlyenv} + + \vspace{-1.7cm}\hfill + \begin{minipage}{6.8cm} + \begin{itemize} + \pause[2] + \item + Ein \lstinline{char} ist eine kleinere \lstinline{int}. + \pause + \item + Ein "`String"' in C ist ein Array von \lstinline{char}s\only<4->{,\\ + also ein Zeiger auf \lstinline{char}s}\only<5->{\\ + also ein Zeiger auf (kleinere) Integer}. + \pause + \pause + \pause + \item + Der letzte \lstinline{char} muß 0 sein.\\ + Er kennzeichnet das Ende des Strings. + \pause + \item + Die Formatspezifikation\\ + entscheidet über die Ausgabe:\\[\smallskipamount] + \begin{tabular}{ll} + \lstinline|%d|\hspace*{0.5em}dezimal + & \lstinline|%c|\hspace*{0.5em}Zeichen\\ + \lstinline|%x|\hspace*{0.5em}hexadezimal +% \pause +% & \lstinline|%s|\hspace*{0.5em}String + \end{tabular} + \vspace*{-1cm} + \end{itemize} + \end{minipage} +\end{frame} + +\addtocounter{subsection}{-1} +\subsection{Arrays und Strings \protect\color{gray}und Zeichen} + +\begin{frame}[fragile] + \showsubsection + + \emph{"`Alles ist Zahl."'\/} -- Schule der Pythagoreer, 6.\ Jh.\ v.\,Chr. + + \medskip + + \begin{center} + \renewcommand{\arraystretch}{1.5} + \begin{tabular}{r} + \lstinline|"Hello"|\\ + \lstinline|'H'|\\ + \lstinline|'a' + 4| + \end{tabular} + \renewcommand{\arraystretch}{1.0} + \begin{tabular}{c} + ist nur eine andere\\ + Schreibweise für + \end{tabular} + \renewcommand{\arraystretch}{1.5} + \begin{tabular}{l} + \lstinline|{ 72, 101, 108, 108, 111, 0 }|\\ + \lstinline|72|\\ + \lstinline|'e'| + \end{tabular} + \renewcommand{\arraystretch}{1.0} + \end{center} + + \begin{itemize} + \item + Welchen Zahlenwert hat \lstinline{'*'} im Zeichensatz? + + \smallskip + + \begin{lstlisting}[gobble=8] + printf ("%d\n", '*'); + \end{lstlisting} + + \smallskip + + (normalerweise: ASCII) + \medskip + \item + Ist \lstinline{char ch} ein Großbuchstabe? + + \smallskip + + \begin{lstlisting}[gobble=8] + if (ch >= 'A' && ch <= 'Z') + ... + \end{lstlisting} + \medskip + \item + Groß- in Kleinbuchstaben umwandeln + + \smallskip + + \begin{lstlisting}[gobble=8] + ch += 'a' - 'A'; + \end{lstlisting} + \end{itemize} +\end{frame} + +\subsection{Strukturen} + +\begin{frame}[fragile] + \showsubsection + + \begin{lstlisting} + #include <stdio.h> + + typedef struct + { + char day, month; + int year; + } + date; + + int main (void) + { + date today = { 17, 10, 2022 }; + printf ("%d.%d.%d\n", today.day, today.month, today.year); + return 0; + } + \end{lstlisting} +\end{frame} + +\begin{frame}[fragile] + \showsubsection + + \vspace*{0.9mm} + \begin{minipage}[b]{6cm} + \begin{lstlisting}[gobble=6] + ¡#include <stdio.h> + + typedef struct + { + char day, month; + int year; + } + date; + + void set_date (date *d) + { + (*d).day = 17; + (*d).month = 10; + (*d).year = 2022; + }¿ + \end{lstlisting} + \end{minipage}% + \begin{minipage}[b]{6cm} + \begin{lstlisting}[gobble=6] + ¡int main (void) + { + date today; + set_date (&today); + printf ("%d.%d.%d\n", today.day, + today.month, today.year); + return 0; + }¿ + \end{lstlisting} + \end{minipage} +\end{frame} + +\begin{frame}[fragile] + \showsubsection + + \vspace*{0.9mm} + \begin{minipage}[b]{6cm} + \begin{lstlisting}[gobble=6] + ¡#include <stdio.h> + + typedef struct + { + char day, month; + int year; + } + date; + + void set_date (date *d) + { + d->day = 17; + d->month = 10; + d->year = 2022; + }¿ + \end{lstlisting} + \end{minipage}% + \begin{minipage}[b]{6cm} + \hspace*{-1cm}% + \lstinline{foo->bar} + ist Abkürzung für + \lstinline{(*foo).bar} + + \bigskip + + \visible<2->{% + \hspace*{-1cm}% + Eine Funktion, die mit einem \lstinline{struct} arbeitet,\\ + \hspace*{-1cm}% + kann man eine \newterm{Methode\/} des \lstinline{struct} nennen.} + + \bigskip + \bigskip + + \begin{lstlisting}[gobble=6] + ¡int main (void) + { + date today; + set_date (&today); + printf ("%d.%d.%d\n", today.day, + today.month, today.year); + return 0; + }¿ + \end{lstlisting} + \end{minipage} + +\end{frame} + +\subsection{Dateien und Fehlerbehandlung} + +\begin{frame}[fragile] + \showsubsection + \vspace*{-0.2925cm} + \begin{minipage}[t]{6cm} + \begin{onlyenv}<1> + \begin{lstlisting}[gobble=8] + ¡#include <stdio.h> + + int main (void) + { + FILE *f = fopen ("fhello.txt", "w"); + fprintf (f, "Hello, world!\n"); + fclose (f); + return 0; + }¿ + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<2> + \begin{lstlisting}[gobble=8] + ¡#include <stdio.h> + + int main (void) + { + FILE *f = fopen ("fhello.txt", "w"); + if (f) + { + fprintf (f, "Hello, world!\n"); + fclose (f); + } + return 0; + }¿ + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<3> + \begin{lstlisting}[gobble=8] + ¡#include <stdio.h> + #include <errno.h> + + int main (void) + { + FILE *f = fopen ("fhello.txt", "w"); + if (f) + { + fprintf (f, "Hello, world!\n"); + fclose (f); + } + else + fprintf (stderr, "error #%d\n", errno); + return 0; + }¿ + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<4> + \begin{lstlisting}[gobble=8] + ¡#include <stdio.h> + #include <errno.h> + #include <string.h> + + int main (void) + { + FILE *f = fopen ("fhello.txt", "w"); + if (f) + { + fprintf (f, "Hello, world!\n"); + fclose (f); + } + else + { + char *msg = strerror (errno); + fprintf (stderr, "%s\n", msg); + } + return 0; + }¿ + \end{lstlisting} + \vspace*{-1cm} + \end{onlyenv} + \begin{onlyenv}<5-> + \begin{lstlisting}[gobble=8] + ¡#include <stdio.h> + #include <errno.h> + #include <er¡ror.h> + + int main (void) + { + FILE *f = fopen ("fhello.txt", "w"); + if (!f) + error (errno, errno, "cannot open file"); + fprintf (f, "Hello, world!\n"); + fclose (f); + return 0; + } + \end{lstlisting} + \end{onlyenv} + \end{minipage}\pause\hspace*{-1.5cm}% + \begin{minipage}[t]{8.5cm} + \bigskip + \only<3->{\bigskip} + \begin{itemize} + \item + Wenn die Datei nicht geöffnet werden kann,\\ + gibt \lstinline{fopen()} den Wert \lstinline{NULL} zurück. + \pause + \medskip + \item + \addtolength{\leftskip}{1cm} + Die globale Variable \lstinline{int errno}\\ + enthält dann die Nummer des Fehlers.\\ + Benötigt: \lstinline{#include <errno.h>} + \pause + \medskip + \only<5->{\bigskip} + \item + Die Funktion \lstinline{strerror()} wandelt \lstinline{errno}\\ + in einen Fehlermeldungstext um.\\ + Benötigt: \lstinline{#include <string.h>} + \pause + \medskip + \item + \addtolength{\leftskip}{-1.5cm} + Die Funktion \lstinline{error()} gibt eine Fehlermeldung aus\\ + und beendet das Programm.\\ + Benötigt: \lstinline{#include <er¡¿ror.h>} + \pause + \medskip + \item + \textbf{Niemals Fehler einfach ignorieren!} + \end{itemize} + \addtolength{\leftskip}{0.5cm} + \end{minipage} +\end{frame} + +\subsection{Parameter des Hauptprogramms} + +\begin{frame}[fragile] + + \showsubsection + + \begin{lstlisting} + #include <stdio.h> + + int main (int argc, char **argv) + { + printf ("argc = %d\n", argc); + for (int i = 0; i < argc; i++) + printf ("argv[%d] = \"%s\"\n", i, argv[i]); + return 0; + } + \end{lstlisting} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + \begin{lstlisting} + #include <stdio.h> + + int main (int argc, char **argv) + { + printf ("argc = %d\n", argc); + for (int i = 0; *argv; i++, argv++) + printf ("argv[%d] = \"%s\"\n", i, *argv); + return 0; + } + \end{lstlisting} + +\end{frame} + +\subsection{String-Operationen} + +\begin{frame}[fragile] + + \showsubsection + +% \vspace*{-0.4cm} + \begin{lstlisting} + #include <stdio.h> + #include <string.h> + + int main (void) + { + char hello[] = "Hello, world!\n"; + + printf ("%s\n", hello); + printf ("%zd\n", strlen (hello)); + + printf ("%s\n", hello + 7); + printf ("%zd\n", strlen (hello + 7)); + + hello[5] = 0; + printf ("%s\n", hello); + printf ("%zd\n", strlen (hello)); + + return 0; + } + \end{lstlisting} + \vspace*{-1cm} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + +% \vspace*{-0.4cm} + \begin{lstlisting} + #include <stdio.h> + #include <string.h> + + int main (void) + { + char *anton = "Anton"; + char *zacharias = "Zacharias"; + + printf ("%d\n", strcmp (anton, zacharias)); + printf ("%d\n", strcmp (zacharias, anton)); + printf ("%d\n", strcmp (anton, anton)); + + char buffer[100] = "Huber "; + strcat (buffer, anton); + printf ("%s\n", buffer); + + return 0; + } + \end{lstlisting} + \vspace*{-1cm} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + +% \vspace*{-0.4cm} + \begin{lstlisting} + #include <stdio.h> + #include <string.h> + + int main (void) + { + char buffer[100] = ""; + sprintf (buffer, "Die Antwort lautet: %d", 42); + printf ("%s\n", buffer); + + char *answer = strstr (buffer, "Antwort"); + printf ("%s\n", answer); + printf ("found at: %zd\n", answer - buffer); + + return 0; + } + \end{lstlisting} + \vspace*{-1cm} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + +% \vspace*{-0.4cm} + \begin{lstlisting} + #include <stdio.h> + #include <string.h> + + int main (void) + { + char buffer[100] = ""; + snprintf (buffer, 100, "Die Antwort lautet: %d", 42); + printf ("%s\n", buffer); + + char *answer = strstr (buffer, "Antwort"); + printf ("%s\n", answer); + printf ("found at: %zd\n", answer - buffer); + + return 0; + } + \end{lstlisting} + +\end{frame} + +\begin{frame} + + \showsection + + Sprachelemente weitgehend komplett + + \bigskip + Es fehlen: + \begin{itemize} + \item + Ergänzungen (z.\,B.\ ternärer Operator, \lstinline{union}, \lstinline{unsigned}, \lstinline{volatile}) + \item + Bibliotheksfunktionen (z.\,B.\ \lstinline{malloc()}) + \arrowitem + werden eingeführt, wenn wir sie brauchen + \bigskip + \item + Konzepte (z.\,B.\ rekursive Datenstrukturen, Klassen selbst bauen) + \arrowitem + werden eingeführt, wenn wir sie brauchen, oder: + \arrowitem + Literatur\\[\smallskipamount] + (z.\,B.\ Wikibooks: C-Programmierung,\\ + Dokumentation zu Compiler und Bibliotheken) + \bigskip + \item + Praxiserfahrung + \arrowitem + Übung und Praktikum: nur Einstieg + \arrowitem + selbständig arbeiten + \end{itemize} +\end{frame} + +\nosectionnonumber{\inserttitle} + +\begin{frame} + + \shownosectionnonumber + + \begin{itemize} + \item[\textbf{1}] \textbf{Einführung} + \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}} + \item[\textbf{2}] \textbf{Einführung in C} + \begin{itemize} + \vspace{-1.5\smallskipamount} + \item[\dots] + \item[2.7] Strukturierte Programmierung + \item[2.8] Seiteneffekte + \item[2.9] Funktionen + \item[2.10] Zeiger + \item[2.11] Arrays und Strings + \item[2.12] Strukturen + \item[2.13] Dateien und Fehlerbehandlung + \item[2.14] Parameter des Hauptprogramms + \color{medgreen} + \item[2.15] String-Operationen + \end{itemize} + \item[\textbf{3}] \textbf{Bibliotheken} + \vspace*{-\smallskipamount} + \item[\textbf{\dots}] +% \item[\textbf{4}] \textbf{Hardwarenahe Programmierung} +% \item[\textbf{5}] \textbf{Algorithmen} +% \item[\textbf{6}] \textbf{Ergänzungen und Ausblicke} + \end{itemize} + \vspace*{-1cm} + +\end{frame} + +\section{Bibliotheken} +\subsection{Der Präprozessor} + +\begin{frame}[fragile] + + \showsection + \showsubsection + + \lstinline{#include}: %\pause: + Text einbinden + \begin{itemize} + \pause + \item + \lstinline{#include <stdio.h>}: Standard-Verzeichnisse -- Standard-Header + \pause + \item + \lstinline{#include "answer.h"}: auch aktuelles Verzeichnis -- eigene Header + \end{itemize} + + \pause + \bigskip + + \lstinline{#define SIX 6}: Text ersetzen lassen -- Konstante definieren + \begin{itemize} + \pause + \item + Kein Semikolon! + \pause + \item + Berechnungen in Klammern setzen:\\ + \lstinline{#define SIX (1 + 5)} + \pause + \item + Konvention: Großbuchstaben + \end{itemize} + +\end{frame} + +\subsection{Bibliotheken einbinden} + +\begin{frame}[fragile] + + \showsection + \showsubsection + + Inhalt der Header-Datei: externe Deklarationen + + \pause + \smallskip + \lstinline{extern int answer (void);} + + \pause + \smallskip + \lstinline{extern int printf (__const char *__restrict __format, ...);} + + \pause + \bigskip + Funktion wird "`anderswo"' definiert + \begin{itemize} + \pause + \item + separater C-Quelltext: mit an \lstinline[style=terminal]{gcc} übergeben + \pause + \item + Zusammenfügen zu ausführbarem Programm durch den \newterm{Linker} + \pause + \item + vorcompilierte Bibliothek: \lstinline[style=terminal]{-lfoo}\\ + \pause + = Datei \file{libfoo.a} in Standard-Verzeichnis + \end{itemize} + +\end{frame} + +\subsection{Bibliothek verwenden (Beispiel: GTK)} + +\begin{frame}[fragile] + + \showsubsection + + \begin{itemize} + \item + \lstinline{#include <gtk/gtk.h>} + \pause + \smallskip + \item + Mit \lstinline[style=cmd]{pkg-config --cflags --libs} erfährt man,\\ + welche Optionen und Bibliotheken man an \lstinline[style=cmd]{gcc} + übergeben muß\alt<4->{.}{:} + \pause + \begin{onlyenv}<3> + \begin{lstlisting}[style=terminal,gobble=10] + $ ¡pkg-config --cflags --libs gtk4¿ + -I/usr/include/gtk-4.0 -I/usr/include/pango-1.0 -I/usr/ + include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/i + nclude -I/usr/include/harfbuzz -I/usr/include/freetype2 + -I/usr/include/libpng16 -I/usr/include/libmount -I/usr/ + include/blkid -I/usr/include/fribidi -I/usr/include/cai + ro -I/usr/include/pixman-1 -I/usr/include/gdk-pixbuf-2. + 0 -I/usr/include/x86_64-linux-gnu -I/usr/include/graphe + ne-1.0 -I/usr/lib/x86_64-linux-gnu/graphene-1.0/include + -mfpmath=sse -msse -msse2 -pthread -lgtk-4 -lpangocairo + -1.0 -lpango-1.0 -lharfbuzz -lgdk_pixbuf-2.0 -lcairo-go + bject -lcairo -lgraphene-1.0 -lgio-2.0 -lgobject-2.0 -l + glib-2.0 + \end{lstlisting} + \vspace*{-3cm} + \end{onlyenv} + \pause + \arrowitem + Compiler-Aufruf: + \begin{onlyenv}<4> + \begin{lstlisting}[style=terminal,gobble=10] + $ ¡gcc -Wall -O hello-gtk.c -I/usr/include/gtk-4.0 -I/u + sr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib + /x86_64-linux-gnu/glib-2.0/include -I/usr/include/harfb + uzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I + /usr/include/libmount -I/usr/include/blkid -I/usr/inclu + de/fribidi -I/usr/include/cairo -I/usr/include/pixman-1 + -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/x86_64-lin + ux-gnu -I/usr/include/graphene-1.0 -I/usr/lib/x86_64-li + nux-gnu/graphene-1.0/include -mfpmath=sse -msse -msse2 + -pthread -lgtk-4 -lpangocairo -1.0 -lpango-1.0 -lharfbu + zz -lgdk_pixbuf-2.0 -lcairo-gobject -lcairo -lgraphene- + 1.0 -lgio-2.0 -lgobject-2.0 -l glib-2.0 -o hello-gtk¿ + \end{lstlisting} + \vspace*{-2cm} + \end{onlyenv} + \begin{onlyenv}<5-> + \begin{lstlisting}[style=terminal,gobble=10] + $ ¡gcc -Wall -O hello-gtk.c $(pkg-config --cflags --libs + gtk4) -o hello-gtk¿ + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<5> + \begin{picture}(0,0)(0.3,0.3) + \color{red} + \put(6.6,-0.6){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(3,1.5);}}} + \put(6.3,-0.7){\makebox(0,0)[t]{\shortstack{\strut Optionen:\\ + \strut u.\,a.\ viele Include-Verzeichnisse:\\ + \lstinline[style=cmd]{-I/usr/include/gtk-4.0}}}} + \put(10.0,-2.1){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(1.5,3);}}} + \put(10.3,-2.2){\makebox(0,0)[t]{\shortstack{\strut Bibliotheken:\\ + \strut u.\,a.\ \lstinline[style=cmd]{-lgtk-4}}}} + \end{picture} + \end{onlyenv} + \pause + \pause + \item + Auf manchen Plattformen kommt es auf die Reihenfolge an: + \begin{lstlisting}[style=terminal,gobble=8] + $ ¡gcc -Wall -O $(pkg-config --cflags gtk4) \ + hello-gtk.c $(pkg-config --libs gtk4) \ + -o hello-gtk¿ + \end{lstlisting} + (Backslash = "`Es geht in der nächsten Zeile weiter."') + \end{itemize} + +\end{frame} + +\subsection{Callbacks} + +\begin{frame}[fragile] + + \showsubsection + + Selbst geschriebene Funktion übergeben: \newterm{Callback} + + \bigskip + + \begin{lstlisting}[xleftmargin=1em] + static void hello (GtkWidget *this, gpointer user_data) + { + char *world = user_data; + printf ("Hello, %s!\n", world); + } + + ... + + g_signal_connect (button, "clicked", G_CALLBACK (hello), "world"); + \end{lstlisting} + + \medskip + + \begin{itemize} + \arrowitem + GTK ruft immer dann, wenn der Button betätigt wurde,\\ + die Funktion \lstinline{hello} auf. + \end{itemize} + + \pause + \begin{picture}(0,0)(1.1,0.8) + \color{red} + \put(9.7,5.1){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.3,0.5);}}} + \put(10.0,5.0){\makebox(0,0)[t]{\shortstack{\strut optionale Zusatzinformationen\\ + \strut für hello(), hier ein String\\ + \strut oft ein Zeiger auf ein struct}}} + \put(10.5,3.5){\makebox(0,0)[tl]{\tikz{\draw[-latex](0,0)--(0.3,-0.5);}}} + \end{picture} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Selbst geschriebene Funktion übergeben: \newterm{Callback} + + \bigskip + + \begin{lstlisting}[xleftmargin=1em] + static void draw (GtkDrawingArea *drawing_area, cairo_t *c, + int width, int height, gpointer user_data) + { + /* Zeichenbefehle */ + ... + } + + ... + + gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area), + draw, NULL, NULL); + \end{lstlisting} + + \medskip + + \begin{itemize} + \arrowitem + GTK ruft immer dann, wenn es etwas zu zeichnen gibt,\\ + die Funktion \lstinline{draw} auf. + \end{itemize} + + \pause + \begin{picture}(0,0) + \color{red} + \put(10.0,4.9){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.3,0.9);}}} + \put(10.0,4.8){\makebox(0,0)[t]{\shortstack{\strut repräsentiert den\\ + \strut Bildschirm, auf den\\ + \strut gezeichnet werden soll}}} + \end{picture} + +\end{frame} + +\iffalse + +\begin{frame}[fragile] + + \showsubsection + + Selbst geschriebene Funktion übergeben: \newterm{Callback} + + \bigskip + + \begin{lstlisting}[xleftmargin=1em] + gboolean timer (GtkWidget *widget) + { + /* Rechenbefehle */ + ... + + gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT); + g_timeout_add (50, (GSourceFunc) timer, widget); + return FALSE; + } + + ... + + g_timeout_add (50, (GSourceFunc) timer, drawing_area); + \end{lstlisting} + + \medskip + + \begin{itemize} + \arrowitem + GTK+ ruft nach 50 Millisekunden + die Funktion \lstinline{timer} auf. + \end{itemize} + + \pause + \begin{picture}(0,0)(-0.07,0.2) + \color{red} + \put(9.7,6.7){\makebox(0,0)[t]{\shortstack{\strut Dieser Bereich soll\\ + \strut neu gezeichnet werden.}}} + \put(9.7,5.7){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.6,-0.8);}}} + \pause + \put(4.3,3.2){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.7,0.6);}}} + \put(4.3,3.1){\makebox(0,0)[t]{\shortstack{\strut In weiteren 50 Millisekunden soll\\ + \strut die Funktion erneut aufgerufen werden.}}} + \pause + \put(9.3,2.9){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-3.3,0.9);}}} + \put(9.8,2.8){\makebox(0,0)[t]{\shortstack{\strut Explizite Typumwandlung\\ + \strut eines Zeigers (später)}}} + \end{picture} + +\end{frame} + +\fi + +\nosectionnonumber{\inserttitle} + +\begin{frame} + + \shownosectionnonumber + + \begin{itemize} + \item[\textbf{1}] \textbf{Einführung} + \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}} + \item[\textbf{2}] \textbf{Einführung in C} + \begin{itemize} + \vspace{-1.5\smallskipamount} + \item[\dots] + \item[2.11] Arrays und Strings + \item[2.12] Strukturen + \item[2.13] Dateien und Fehlerbehandlung + \item[2.14] Parameter des Hauptprogramms + \color{medgreen} + \item[2.15] String-Operationen + \end{itemize} + \item[\textbf{3}] \textbf{Bibliotheken} + \begin{itemize} + \color{medgreen} + \item[3.1] Der Präprozessor + \item[3.2] Bibliotheken einbinden + \item[3.3] Bibliotheken verwenden + \color{orange} + \item[3.4] Callbacks + \color{red} + \item[3.5] Projekt organisieren: make + \end{itemize} + \item[\textbf{4}] \textbf{Hardwarenahe Programmierung} + \vspace*{-\smallskipamount} + \item[\textbf{\dots}] +% \item[\textbf{5}] \textbf{Algorithmen} +% \item[\textbf{6}] \textbf{Ergänzungen und Ausblicke} + \end{itemize} + +\end{frame} + +\end{document} diff --git a/20231026/hp-musterloesung-20231026.pdf b/20231026/hp-musterloesung-20231026.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3af669aa4c36ed6a0db9a8661a5ad92ddce4e33c Binary files /dev/null and b/20231026/hp-musterloesung-20231026.pdf differ diff --git a/20231026/hp-musterloesung-20231026.tex b/20231026/hp-musterloesung-20231026.tex new file mode 100644 index 0000000000000000000000000000000000000000..2ff43297565b816f4d904f186511d5aa879e1c60 --- /dev/null +++ b/20231026/hp-musterloesung-20231026.tex @@ -0,0 +1,348 @@ +% hp-musterloesung-20231026.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: Seltsame Programme, Kalender-Berechnung, Strings, Programm analysieren + +\documentclass[a4paper]{article} + +\usepackage{pgscript} +\renewcommand{\breath}{\bigskip} + +\begin{document} + + \section*{Hardwarenahe Programmierung\\ + Musterlösung zu den Übungsaufgaben -- 26.\ Oktober 2023} + + \exercise{Arrays mit Zahlen} + + \begin{minipage}[t]{0.4\textwidth} + Wir betrachten das folgende Programm\\ + (Datei: \gitfile{hp}{2023ws/20231026}{aufgabe-1.c}): + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + void f (int *s0, int *s1) + { + while (*s0 >= 0) + { + int *s = s1; + while (*s >= 0) + if (*s0 == *s++) + printf ("%d ", *s0); + s0++; + } + printf ("\n"); + } + + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1, -1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10, -1 }; + f (a, b); + return 0; + } + \end{lstlisting} + \end{minipage}\hfill + \begin{minipage}[t]{0.55\textwidth} + \vspace*{-\bigskipamount} + \begin{enumerate}[\quad(a)] + \item + Was bewirkt die Funktion \lstinline{f},\\ + und wie funktioniert sie? + \points{4} +% \item +% Von welcher Ordnung (Landau-Symbol) ist die Funktion? +% Begründen Sie Ihre Antwort. +% +% Wir beziehen uns hierbei auf die Anzahl der Vergleiche +% in Abhängigkeit von der Länge der Eingabedaten \lstinline{s0} und \lstinline{s1}. +% Für die Rechnung dürfen Sie beide Längen mit $n$ gleichsetzen, +% obwohl sie normalerweise nicht gleich sind. +% \points{2} + \item + Was passiert, wenn Sie beim Aufruf der Funktion für einen der + Parameter den Wert \lstinline{NULL} übergeben? + Begründen Sie Ihre Antwort. + \points{2} + \item + Was kann passieren, wenn Sie das Hauptprogramm wie folgt abändern + (\gitfile{hp}{2023ws/20231026}{aufgabe-1c.c})? + Begründen Sie Ihre Antwort. + \begin{lstlisting}[gobble=8] + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10 }; + f (a, b); + return 0; + } + \end{lstlisting} + \points{2} +% \item +% Beschreiben Sie -- in Worten und/oder als C-Quelltext --, wie +% sich die Funktion \lstinline{f} effizienter gestalten läßt, +% wenn man die ihr übergebenen Arrays \lstinline{s0} und +% \lstinline{s1} als sortiert voraussetzt. +% \points{5} +% +% Hinweis: Wie würden Sie als Mensch die Aufgabe erledigen? +% \item +% Von welcher +% Ordnung (Landau-Symbol) ist Ihre effizientere Version der Funktion und warum? +% \points{2} + \end{enumerate} + \end{minipage} + + \solution + + \begin{enumerate}[\quad(a)] + \item + \textbf{Was bewirkt die Funktion \lstinline{f}, und wie funktioniert sie?} + + Die Funktion gibt alle Zahlen aus, die sowohl im Array \lstinline{s0} + als auch im Array \lstinline{s1} vorkommen (Schnittmenge). + + Dies geschieht, indem der Zeiger \lstinline{s0} das gesamte Array durchläuft + (äußere Schleife). + Für jedes Element des ersten Arrays durchläuft der Zeiger \lstinline{s} + das gesamte zweite Array (innere Schleife). + Auf diese Weise wird jedes Element von \lstinline{s0} + mit jedem von \lstinline{s1} verglichen und bei Gleichheit ausgegeben. + + Um die Schleifen abbrechen zu können, enthalten beide Arrays + als Ende-Markierung eine negative Zahl (\lstinline{-1}). + + \item + \textbf{Was passiert, wenn Sie beim Aufruf der Funktion für einen der + Parameter den Wert \lstinline{NULL} übergeben? + Begründen Sie Ihre Antwort.} + + In dem Moment, wo auf den jeweiligen Parameter-Zeiger zugegriffen wird + (\lstinline{while (*s0 >= 0)} für \lstinline{s0} bzw.\ + \lstinline{int *s = s1; while (*s >= 0)} für \lstinline{s1}), + kommt es zu einem Absturz (Speicherzugriffsfehler). + Die Dereferenzierung eines Zeigers mit dem Wert \lstinline{NULL} + ist nicht zulässig. + + \item + \textbf{Was kann passieren, wenn Sie das Hauptprogramm wie folgt abändern + (\gitfile{hp}{2023ws/20231026}{aufgabe-1c.c})? + Begründen Sie Ihre Antwort.} + + \begin{minipage}{0.35\textwidth} + \begin{lstlisting}[gobble=10] + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10 }; + f (a, b); + return 0; + } + \end{lstlisting} + \end{minipage}\hfill + \begin{minipage}{0.575\textwidth} + Durch die fehlenden Ende-Markierungen der Arrays + laufen die Schleifen immer weiter, + bis sie irgendwann zufällig auf Speicherzellen stoßen, + die sich als Ende-Markierungen interpretieren lassen (negative Zahlen). + Dadurch kann es zu einem Lesezugriff auf Speicher kommen, + für den das Programm kein Lesezugriffsrecht hat, + also zu einem Absturz (Speicherzugriffsfehler). + \end{minipage} + \end{enumerate} + + \exercise{Datum-Bibliothek} + + Schreiben Sie eine Bibliothek (\file{.c}-Datei und \file{.h}-Datei) + zur Behandlung von Datumsangaben. + + Diese soll enthalten: + \begin{itemize} + \item + einen \lstinline{struct}-Datentyp \lstinline{date}, + der eine Datumsangabe speichert, + \item + eine Funktion \lstinline{void date_print (date *d)}, die ein Datum ausgibt, + \item + eine Funktion \lstinline{int date_set (date *d, int day, int month, int year)}, + die ein Datum auf einen gegebenen Tag setzt + und zurückgibt, ob es sich um ein gültiges Datum handelt (0 = nein, 1 = ja), + \item + eine Funktion \lstinline{void date_next (date *d)}, + die ein Datum auf den nächsten Tag vorrückt. + \end{itemize} + + Schreiben Sie auch ein Programm, das die o.\,a.\ Funktionen testet. + + \solution + + Die Dateien \gitfile{hp}{2023ws/20231026}{loesung-2.c}, + \gitfile{hp}{2023ws/20231026}{loesung-2.h} + und \gitfile{hp}{2023ws/20231026}{loesung-2-test.c} + enthalten die Bibliothek und das Test-Programm. + + Eine detaillierte Anleitung, + wie man auf die Funktion \lstinline{date_next()} kommt, + finden Sie im Skript zur Lehrveranstaltung, + Datei \gitfile{hp}{2023ws/script/hp-2023ws.pdf}{hp-2023ws.pdf}, + ab Seite 29. + + \exercise{Fehlerhaftes Primzahl-Programm} + + \begin{minipage}[t]{5.5cm} + Das nebenstehende Primzahlsuchprogramm (Datei: \gitfile{hp}{2023ws/20231026}{aufgabe-3.c}) + soll Zahlen ausgeben, die genau zwei Teiler haben, ist aber fehlerhaft. + + \smallskip + + Korrigieren Sie das Programm derart, daß ein Programm entsteht, + welches alle Primzahlen kleiner 100 ausgibt.% \points 5 + \end{minipage}\hfill + \begin{minipage}[t]{9cm} + \vspace*{-0.5cm} + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + int main (void) + { + int n, i, divisors; + for (n = 0; n < 100; n++) + divisors = 0; + for (i = 0; i < n; i++) + if (n % i == 0) + divisors++; + if (divisors = 2) + printf ("%d ist eine Primzahl.\n", n); + return 0; + } + \end{lstlisting} + \end{minipage} + + \solution + + Beim Compilieren des Beispiel-Programms mit + \lstinline[style=cmd]{gcc -Wall} erhalten wir die folgende Warnung: + \begin{lstlisting}[style=terminal] + aufgabe-2.c:11:5: warning: suggest parentheses around assignment + used as truth value [-Wparentheses] + \end{lstlisting} + Beim Ausführen gibt das Programm die folgende (falsche) Behauptung aus: + \begin{lstlisting}[style=terminal] + 100 ist eine Primzahl. + \end{lstlisting} + + Einen ersten Hinweis auf den Fehler im Programm liefert die Warnung. + Die Bedingung \lstinline{if (divisors = 2)} in Zeile 11 + steht \emph{nicht\/} für einen Vergleich + der Variablen \lstinline{divisors} mit der Zahl 2, + sondern für eine Zuweisung der Zahl 2 an die Variable \lstinline{divisors}. + Neben dem \emph{Seiteneffekt\/} der Zuweisung gibt \lstinline{divisors = 2} + den Wert \lstinline{2} zurück. + Als Bedingung interpretiert, hat \lstinline{2} den Wahrheitswert "`wahr"' ("`true"'); + die \lstinline{printf()}-Anweisung wird daher in jedem Fall ausgeführt. + + Korrektur dieses Fehlers: \lstinline{if (divisors == 2)} + -- siehe die Datei \gitfile{hp}{2023ws/20231026}{loesung-2-1.c}. + + \bigskip + + Nach der Korrektur dieses Fehlers compiliert das Programm ohne Warnung, + gibt aber beim Ausführen die folgende Fehlermeldung aus: + \begin{lstlisting}[style=terminal] + Gleitkomma-Ausnahme + \end{lstlisting} + (Bemerkung: Bei ausgeschalteter Optimierung + -- \lstinline[style=cmd]{gcc} ohne \lstinline[style=cmd]{-O} -- + kommt diese Fehlermeldung bereits beim ersten Versuch, das Programm auszuführen. + Der Grund für dieses Verhalten ist, daß bei eingeschalteter Optimierung + irrelevante Teile des Programms entfernt und gar nicht ausgeführt werden, + so daß der Fehler nicht zum Tragen kommt. + In diesem Fall wurde die Berechnung von \lstinline{divisors} komplett wegoptimiert, + da der Wert dieser Variablen nirgendwo abgefragt, + sondern durch die Zuweisung \lstinline{if (divisors = 2)} + sofort wieder überschrieben wurde.) + + Die Fehlermeldung "`\lstinline[style=terminal]{Gleitkomma-Ausnahme}"' + ist insofern irreführend, als daß hier gar keine Gleitkommazahlen im Spiel sind; + andererseits deutet sie auf einen Rechenfehler hin, was auch tatsächlich zutrifft. + Durch Untersuchen aller Rechenoperationen + -- z.\,B.\ durch das Einfügen zusätzlicher \lstinline{printf()} -- + finden wir den Fehler in Zeile 9: + Die Modulo-Operation \lstinline{n % i} ist eine Division, + die dann fehlschlägt, wenn der Divisor \lstinline{i} den Wert 0 hat. + Die Fehlerursache ist die bei 0 beginnende \lstinline{for}-Schleife in Zeile 8: + \lstinline{for (i = 0; i < n; i++)}. + + Korrektur dieses Fehlers: Beginn der Schleife mit \lstinline{i = 1} + statt \lstinline{i = 0} -- siehe die Datei \gitfile{hp}{2023ws/20231026}{loesung-2-2.c}. + + \bigskip + + Nach der Korrektur dieses Fehlers gibt das Programm überhaupt nichts mehr aus. + + Durch Untersuchen des Verhaltens des Programms + -- z.\,B.\ durch das Einfügen zusätzlicher \lstinline{printf()} -- + stellen wir fest, daß die Zeilen 8 bis 12 des Programms nur einmal ausgeführt werden + und nicht, wie die \lstinline{for}-Schleife in Zeile 6 vermuten ließe, 100mal. + Der Grund dafür ist, daß sich die \lstinline{for}-Schleife + nur auf die unmittelbar folgende Anweisung \lstinline{divisors = 0} bezieht. + Nur diese Zuweisung wird 100mal ausgeführt; + alles andere befindet sich außerhalb der \lstinline{for}-Schleife. + (Die Einrückung hat in C keine inhaltliche Bedeutung, + sondern dient nur zur Verdeutlichung der Struktur des Programms. + In diesem Fall entsprach die tatsächliche Struktur nicht der beabsichtigten.) + + Korrektur dieses Fehlers: + geschweifte Klammern um den Inhalt der äußeren \lstinline{for}-Schleife + -- siehe die Datei \gitfile{hp}{2023ws/20231026}{loesung-2-3.c}. + + \bigskip + + Nach der Korrektur dieses Fehlers gibt das Programm folgendes aus: + \begin{lstlisting}[style=terminal] + 4 ist eine Primzahl. + 9 ist eine Primzahl. + 25 ist eine Primzahl. + 49 ist eine Primzahl. + \end{lstlisting} + Diese Zahlen sind keine Primzahlen (mit zwei Teilern), + sondern sie haben drei Teiler. + Demnach findet das Programm einen Teiler zu wenig. + (Um diesen Fehler zu finden, kann man sich zu jeder Zahl + die gefundene Anzahl der Teiler \lstinline{divisors} ausgeben lassen.) + + Der nicht gefundene Teiler ist jeweils die Zahl selbst. + Dies kommt daher, daß die Schleife + \lstinline{for (i = 1; i < n; i++)} nur bis \lstinline{n - 1} geht, + also keine Division durch \lstinline{n} stattfindet. + + Korrektur dieses Fehlers: Schleifenbedingung \lstinline{i <= n} + statt \lstinline{i < n} + -- siehe die Datei \gitfile{hp}{2023ws/20231026}{loesung-2-4.c}. + + \bigskip + + Nach der Korrektur dieses Fehlers verhält sich das Programm korrekt. + + Die Datei \gitfile{hp}{2023ws/20231026}{loesung-2-4.c} enthält somit das korrigierte Programm. + +\end{document} diff --git a/20231026/hp-uebung-20231026.pdf b/20231026/hp-uebung-20231026.pdf new file mode 100644 index 0000000000000000000000000000000000000000..baf5e0a8b7ecebdf7271f71622330b595cbb1a44 Binary files /dev/null and b/20231026/hp-uebung-20231026.pdf differ diff --git a/20231026/hp-uebung-20231026.tex b/20231026/hp-uebung-20231026.tex new file mode 100644 index 0000000000000000000000000000000000000000..49bdb98cd10c8a81a378cf6111ea68f188891564 --- /dev/null +++ b/20231026/hp-uebung-20231026.tex @@ -0,0 +1,181 @@ +% hp-uebung-20231026.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: Arrays mit Zahlen, Datum-Bibliothek, fehlerhaftes Primzahl-Programm + +\documentclass[a4paper]{article} + +\usepackage{pgscript} + +\begin{document} + + \thispagestyle{empty} + + \section*{Hardwarenahe Programmierung\\ + Übungsaufgaben -- 26.\ Oktober 2023} + + Diese Übung enthält Punkteangaben wie in einer Klausur. + Um zu "`bestehen"', müssen Sie innerhalb von 60 Minuten + unter Verwendung ausschließlich zugelassener Hilfsmittel + 10 Punkte (von insgesamt \totalpoints) erreichen. + + \exercise{Arrays mit Zahlen} + + \begin{minipage}[t]{0.4\textwidth} + Wir betrachten das folgende Programm\\ + (Datei: \gitfile{hp}{2023ws/20231026}{aufgabe-1.c}): + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + void f (int *s0, int *s1) + { + while (*s0 >= 0) + { + int *s = s1; + while (*s >= 0) + if (*s0 == *s++) + printf ("%d ", *s0); + s0++; + } + printf ("\n"); + } + + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1, -1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10, -1 }; + f (a, b); + return 0; + } + \end{lstlisting} + \end{minipage}\hfill + \begin{minipage}[t]{0.55\textwidth} + \vspace*{-\bigskipamount} + \begin{enumerate}[\quad(a)] + \item + Was bewirkt die Funktion \lstinline{f},\\ + und wie funktioniert sie? + \points{4} +% \item +% Von welcher Ordnung (Landau-Symbol) ist die Funktion? +% Begründen Sie Ihre Antwort. +% +% Wir beziehen uns hierbei auf die Anzahl der Vergleiche +% in Abhängigkeit von der Länge der Eingabedaten \lstinline{s0} und \lstinline{s1}. +% Für die Rechnung dürfen Sie beide Längen mit $n$ gleichsetzen, +% obwohl sie normalerweise nicht gleich sind. +% \points{2} + \item + Was passiert, wenn Sie beim Aufruf der Funktion für einen der + Parameter den Wert \lstinline{NULL} übergeben? + Begründen Sie Ihre Antwort. + \points{2} + \item + Was kann passieren, wenn Sie das Hauptprogramm wie folgt abändern + (\gitfile{hp}{2023ws/20231026}{aufgabe-1c.c})? + Begründen Sie Ihre Antwort. + \begin{lstlisting}[gobble=8] + int main (void) + { + int a[] = { 10, 4, 3, 7, 12, 0, 1 }; + int b[] = { 7, 14, 0, 8, 9, 22, 10 }; + f (a, b); + return 0; + } + \end{lstlisting} + \points{2} +% \item +% Beschreiben Sie -- in Worten und/oder als C-Quelltext --, wie +% sich die Funktion \lstinline{f} effizienter gestalten läßt, +% wenn man die ihr übergebenen Arrays \lstinline{s0} und +% \lstinline{s1} als sortiert voraussetzt. +% \points{5} +% +% Hinweis: Wie würden Sie als Mensch die Aufgabe erledigen? +% \item +% Von welcher +% Ordnung (Landau-Symbol) ist Ihre effizientere Version der Funktion und warum? +% \points{2} + \end{enumerate} + \end{minipage} + + \exercise{Datum-Bibliothek} + + Schreiben Sie eine Bibliothek (\file{.c}-Datei und \file{.h}-Datei) + zur Behandlung von Datumsangaben. + + Diese soll enthalten: + \begin{itemize} + \item + einen \lstinline{struct}-Datentyp \lstinline{date}, + der eine Datumsangabe speichert, + \item + eine Funktion \lstinline{void date_print (date *d)}, die ein Datum ausgibt, + \item + eine Funktion \lstinline{int date_set (date *d, int day, int month, int year)}, + die ein Datum auf einen gegebenen Tag setzt + und zurückgibt, ob es sich um ein gültiges Datum handelt (0 = nein, 1 = ja), + \item + eine Funktion \lstinline{void date_next (date *d)}, + die ein Datum auf den nächsten Tag vorrückt. + \end{itemize} + + Schreiben Sie auch ein Programm, das die o.\,a.\ Funktionen testet. + + \points{8} + + \exercise{Fehlerhaftes Primzahl-Programm} + + \begin{minipage}[t]{5.5cm} + Das nebenstehende Primzahlsuchprogramm (Datei: \gitfile{hp}{2023ws/20231026}{aufgabe-3.c}) + soll Zahlen ausgeben, die genau zwei Teiler haben, ist aber fehlerhaft. + + \smallskip + + Korrigieren Sie das Programm derart, daß ein Programm entsteht, + welches alle Primzahlen kleiner 100 ausgibt. \points 5 + \end{minipage}\hfill + \begin{minipage}[t]{9cm} + \vspace*{-0.5cm} + \begin{lstlisting}[gobble=6] + #include <stdio.h> + + int main (void) + { + int n, i, divisors; + for (n = 0; n < 100; n++) + divisors = 0; + for (i = 0; i < n; i++) + if (n % i == 0) + divisors++; + if (divisors = 2) + printf ("%d ist eine Primzahl.\n", n); + return 0; + } + \end{lstlisting} + \end{minipage} + + \makeatletter + \immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}} + \makeatother + +\end{document} diff --git a/20231026/loesung-2-test.c b/20231026/loesung-2-test.c new file mode 100644 index 0000000000000000000000000000000000000000..7947ae0afe7221e20f66fed108c900c3964ccfc0 --- /dev/null +++ b/20231026/loesung-2-test.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include "loesung-2.h" + +void check (char day, char month, int year) +{ + date d; + if (date_set (&d, day, month, year)) + { + date_print (&d); + printf (" --> "); + date_next (&d); + date_print (&d); + printf ("\n"); + } + else + printf ("%02d.%02d.%04d: invalid date\n", day, month, year); +} + +int main (void) +{ + check (6, 11, 2018); + check (29, 11, 2018); + check (30, 11, 2018); + check (31, 11, 2018); + check (29, 12, 2018); + check (30, 12, 2018); + check (31, 12, 2018); + check (28, 2, 2016); + check (29, 2, 2016); + check (30, 2, 2016); + check (28, 2, 2015); + check (29, 2, 2015); + check (30, 2, 2015); + check (31, 12, 2008); + check (28, 2, 2000); + check (29, 2, 2000); + check (30, 2, 2000); + check (28, 2, 1900); + check (29, 2, 1900); + check (30, 2, 1900); + return 0; +} diff --git a/20231026/loesung-2.c b/20231026/loesung-2.c new file mode 100644 index 0000000000000000000000000000000000000000..9ce7f9da4be532c884be6a463dfcaeec32c4e134 --- /dev/null +++ b/20231026/loesung-2.c @@ -0,0 +1,62 @@ +#include "loesung-2.h" + +int is_leap_year (int year) +{ + if (year % 4 == 0) + if (year % 100 == 0) + if (year % 400 == 0) + return 1; + else + return 0; + else + return 1; + else + return 0; +} + +int days_in_month (int month, int year) +{ + if (month == 2) + if (is_leap_year (year)) + return 29; + else + return 28; + else if (month == 4 || month == 6 || month == 9 || month == 11) + return 30; + else + return 31; +} + +void date_print (date *d) +{ + printf ("%02d.%02d.%04d", d->day, d->month, d->year); +} + +int date_set (date *d, char day, char month, int year) +{ + d->year = year; + if (month > 0 && month <= 12) + d->month = month; + else + return 0; + if (day > 0 && day <= days_in_month (month, year)) + d->day = day; + else + return 0; + return 1; +} + +void date_next (date *d) +{ + d->day++; + if (d->day > days_in_month (d->month, d->year)) + { + d->month++; + d->day = 1; + if (d->month > 12) + { + d->year++; + d->month = 1; + } + } +} diff --git a/20231026/loesung-2.h b/20231026/loesung-2.h new file mode 100644 index 0000000000000000000000000000000000000000..f0d8f5991518d851931ffe06a13387f57cef1905 --- /dev/null +++ b/20231026/loesung-2.h @@ -0,0 +1,14 @@ +#include <stdio.h> + +typedef struct +{ + char day, month; + int year; +} +date; + +extern int is_leap_year (int year); +extern int days_in_month (int month, int year); +extern void date_print (date *d); +extern int date_set (date *d, char day, char month, int year); +extern void date_next (date *d); diff --git a/20231026/loesung-3-1.c b/20231026/loesung-3-1.c new file mode 100644 index 0000000000000000000000000000000000000000..248883b772ca68d498ae4dc080e83899eb715570 --- /dev/null +++ b/20231026/loesung-3-1.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main (void) +{ + int n, i, divisors; + for (n = 0; n < 100; n++) + divisors = 0; + for (i = 0; i < n; i++) + if (n % i == 0) + divisors++; + if (divisors == 2) + printf ("%d ist eine Primzahl.\n", n); + return 0; +} diff --git a/20231026/loesung-3-2.c b/20231026/loesung-3-2.c new file mode 100644 index 0000000000000000000000000000000000000000..0cc3db639099eab0040c568acbd46987eb599645 --- /dev/null +++ b/20231026/loesung-3-2.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main (void) +{ + int n, i, divisors; + for (n = 0; n < 100; n++) + divisors = 0; + for (i = 1; i < n; i++) + if (n % i == 0) + divisors++; + if (divisors == 2) + printf ("%d ist eine Primzahl.\n", n); + return 0; +} diff --git a/20231026/loesung-3-3.c b/20231026/loesung-3-3.c new file mode 100644 index 0000000000000000000000000000000000000000..af2694c1ad2f710d79d7913b9dcfc7348be96115 --- /dev/null +++ b/20231026/loesung-3-3.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +int main (void) +{ + int n, i, divisors; + for (n = 0; n < 100; n++) + { + divisors = 0; + for (i = 1; i < n; i++) + if (n % i == 0) + divisors++; + if (divisors == 2) + printf ("%d ist eine Primzahl.\n", n); + } + return 0; +} diff --git a/20231026/loesung-3-4.c b/20231026/loesung-3-4.c new file mode 100644 index 0000000000000000000000000000000000000000..770d92706cc68f64147e5efd443880ac3d875495 --- /dev/null +++ b/20231026/loesung-3-4.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +int main (void) +{ + int n, i, divisors; + for (n = 0; n < 100; n++) + { + divisors = 0; + for (i = 1; i <= n; i++) + if (n % i == 0) + divisors++; + if (divisors == 2) + printf ("%d ist eine Primzahl.\n", n); + } + return 0; +} diff --git a/20231026/logo-hochschule-bochum-cvh-text-v2.pdf b/20231026/logo-hochschule-bochum-cvh-text-v2.pdf new file mode 120000 index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8 --- /dev/null +++ b/20231026/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/20231026/logo-hochschule-bochum.pdf b/20231026/logo-hochschule-bochum.pdf new file mode 120000 index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1 --- /dev/null +++ b/20231026/logo-hochschule-bochum.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum.pdf \ No newline at end of file diff --git a/20231026/maerchen.c b/20231026/maerchen.c new file mode 100644 index 0000000000000000000000000000000000000000..5c2716e85205136d406ad2e20285c18ddc967c07 --- /dev/null +++ b/20231026/maerchen.c @@ -0,0 +1,4 @@ +Vor langer, langer Zeit +gab es einmal +#include "hexe.h" +Die lebte in einem Wald. diff --git a/20231026/pgscript.sty b/20231026/pgscript.sty new file mode 120000 index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b --- /dev/null +++ b/20231026/pgscript.sty @@ -0,0 +1 @@ +../common/pgscript.sty \ No newline at end of file diff --git a/20231026/pgslides.sty b/20231026/pgslides.sty new file mode 120000 index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64 --- /dev/null +++ b/20231026/pgslides.sty @@ -0,0 +1 @@ +../common/pgslides.sty \ No newline at end of file