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

Vorbereitung 4.2.2021

parent c574faa4
No related branches found
No related tags found
No related merge requests found
Showing
with 2728 additions and 0 deletions
#include <stdio.h>
#define ANIMAL 0
#define WITH_WINGS 1
#define WITH_LEGS 2
typedef struct animal
{
int type;
char *name;
} animal;
typedef struct with_wings
{
int wings;
} with_wings;
typedef struct with_legs
{
int legs;
} with_legs;
int main (void)
{
animal *a[2];
animal duck;
a[0] = &duck;
a[0]->type = WITH_WINGS;
a[0]->name = "duck";
a[0]->wings = 2;
animal cow;
a[1] = &cow;
a[1]->type = WITH_LEGS;
a[1]->name = "cow";
a[1]->legs = 4;
for (int i = 0; i < 2; i++)
if (a[i]->type == WITH_LEGS)
printf ("A %s has %d legs.\n", a[i]->name,
((with_legs *) a[i])-> legs);
else if (a[i]->type == WITH_WINGS)
printf ("A %s has %d wings.\n", a[i]->name,
((with_wings *) a[i])-> wings);
else
printf ("Error in animal: %s\n", a[i]->name);
return 0;
}
#include <stdio.h>
#define ANIMAL 0
#define WITH_WINGS 1
#define WITH_LEGS 2
typedef struct animal
{
int type;
char *name;
} animal;
typedef struct with_wings
{
int wings;
} with_wings;
typedef struct with_legs
{
int legs;
} with_legs;
int main (void)
{
animal *a[2];
animal duck;
a[0] = &duck;
a[0]->type = WITH_WINGS;
a[0]->name = "duck";
((with_wings *) a[0])->wings = 2;
animal cow;
a[1] = &cow;
a[1]->type = WITH_LEGS;
a[1]->name = "cow";
((with_legs *) a[1])->legs = 4;
for (int i = 0; i < 2; i++)
if (a[i]->type == WITH_LEGS)
printf ("A %s has %d legs.\n", a[i]->name,
((with_legs *) a[i])-> legs);
else if (a[i]->type == WITH_WINGS)
printf ("A %s has %d wings.\n", a[i]->name,
((with_wings *) a[i])-> wings);
else
printf ("Error in animal: %s\n", a[i]->name);
return 0;
}
#include <stdio.h>
void foreach (int *a, void (*fun) (int x))
{
for (int *p = a; *p >= 0; p++)
fun (*p);
}
void even_or_odd (int x)
{
if (x % 2)
printf ("%d ist ungerade.\n", x);
else
printf ("%d ist gerade.\n", x);
}
int main (void)
{
int numbers[] = { 12, 17, 32, 1, 3, 16, 19, 18, -1 };
foreach (numbers, even_or_odd);
return 0;
}
../common/hello-gtk.png
\ No newline at end of file
File added
% hp-2020ws-p4.pdf - Labor Notes on Low-Level Programming
% Copyright (C) 2014, 2015, 2016, 2018, 2019, 2020, 2021 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: Versuch 4: Objektorientiertes Grafik-Programm
\documentclass[a4paper]{article}
\usepackage{pgscript}
\usepackage{multicol}
\usepackage{amsmath}
\usepackage{sfmath}
\sloppy
%\pagestyle{empty}
\newcommand{\sep}{~$\cdot$~}
\newcommand{\mylicense}{CC-by-sa (Version 3.0) oder GNU GPL (Version 3 oder höher)}
\begin{document}
\makebox(0,0.005)[tl]{\includegraphics[scale=0.72]{logo-hochschule-bochum-cvh-text-v2.pdf}}\hfill
\makebox(0,0)[tr]{\includegraphics[scale=0.5]{logo-hochschule-bochum.pdf}}
\par\bigskip\bigskip
\begin{center}
\Large\textbf{Praktikumsversuch 4: Objektorientiertes Grafik-Programm}
\par\medskip
\normalsize Hardwarenahe Programmierung\sep
Wintersemester 2020/21\sep
Prof.~Dr.~Peter Gerwinski
\end{center}
Aufgabe: Schreiben Sie ein GTK+-Programm,
mit dem man verschiedene Objekte (z.\,B.\ Rechtecke, Kreise, Dreiecke)
in eine Grafik einfügen und nachträglich verändern kann
(z.\,B.\ Position, Größe, Farbe).
(Beispiel: Ich füge zunächst zwei Rechtecke und einen Kreis in eine Grafik ein,
wähle anschließend das erste Rechteck aus und ändere dessen Farbe.)
\bigskip
Hinweise:
\vspace*{-\medskipamount}
\begin{itemize}
\item
Das Beispielprogramm \gitfile{hp}{2020ws/20210128}{objects-9.c} zeigt,
wie man in C verschiedenartige Objekte
in einem Array von Zeigern verwaltet.
\item
Das Beispielprogramm \gitfile{hp}{2020ws/script}{gtk-6.c} zeigt,
wie man mit Hilfe der GUI-Bibliothek GTK+
verschiedene Objekte in ein Fenster zeichnet.
\item
Das Beispielprogramm \gitfile{hp}{2020ws/script}{gtk-7.c} zeigt,
wie man in der GUI-Bibliothek GTK+
Tastatur- und Maus-Eingaben entgegennimmt und verarbeitet.
\item
Das Auswählen eines bereits vorhandenen Objekts geht am einfachsten
mittels Tastatur-Eingaben (z.\,B.\ Ziffer 1 für das erste Objekt usw.).
Auswahl mit der Maus ist auch möglich, aber schwieriger.
\item
Mit Hilfe der Funktion \lstinline{gtk_widget_queue_draw()}
teilen Sie GTK+ mit, daß Sie ein \lstinline{GtkWidget}
neu zeichnen lassen möchten.
\item
Das Compilieren eines GTK+-Programms
(z.\,B.\ \gitfile{hp}{2020ws/script}{gtk-7.c}) geschieht wie folgt:
\begin{lstlisting}[style=cmd,gobble=8]
gcc $(pkg-config --cflags gtk+-3.0) -Wall -O gtk-7.c \
$(pkg-config --libs gtk+-3.0) -o gtk-7
\end{lstlisting}
(Den Backslash am Ende der ersten Zeile entfällt,
wenn Sie den ganzen Befehl in eine einzige Zeile schreiben.)
\end{itemize}
\bigskip
\textbf{GTK+ unter GNU/Linux}
\begin{itemize}
\item
Installieren Sie das Entwickler-Paket für GTK+-3,\\
z.\,B.\ unter Debian GNU/Linux und darauf basierenden Systemen:
\begin{lstlisting}[style=cmd,gobble=8]
apt-get install libgtk-3-dev
\end{lstlisting}
\end{itemize}
\bigskip
\goodbreak
\textbf{GTK+ unter MacOS X}
\begin{itemize}
\item
Zuerst den Paketmanager "`Homebrew"' installieren:
\begin{lstlisting}[style=cmd,gobble=8]
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/
Homebrew/install/2020ws/install)"
\end{lstlisting}
(Die URL nicht trennen, sondern in einer Zeile schreiben.)
\item
Danach mit Hilfe von \lstinline[style=cmd]{brew} GTK+ installieren:
\begin{lstlisting}[style=cmd,gobble=8]
brew install gtk+3
\end{lstlisting}
\end{itemize}
\bigskip
\goodbreak
\textbf{GTK+ unter Microsoft Windows: Cygwin}
\begin{itemize}
\item
Im Cygwin-Setup-Programm die Pakete \file{libgtk3-devel},
\file{xorg-server} und \file{dbus-x11} installieren.
\item
Bevor Sie GTK+-Programme starten können,
müssen Sie einmalig den X-Server starten:
\begin{lstlisting}[style=cmd,gobble=8]
XWin -multiwindow &
\end{lstlisting}
\item
Bevor Sie GTK+-Programme starten können,
müssen Sie einmalig pro Shell-Sitzung\\
die \lstinline[style=cmd]{DISPLAY}-Variable setzen:
\begin{lstlisting}[style=cmd,gobble=8]
export DISPLAY=:0.0
\end{lstlisting}
\end{itemize}
\bigskip
\goodbreak
\textbf{GTK+ unter Microsoft Windows: MinGW}
\begin{itemize}
\item
Installieren Sie \file{MSYS2} (Installer).
\item
Installieren Sie von der MinGW-Shell aus GTK+
und weitere Entwicklungswerkzeuge:
\begin{lstlisting}[style=cmd,gobble=8]
pacman -S mingw-w64-x86_64-gcc
pacman -S mingw-w64-x86_64-gtk3
pacman -S mingw-w64-x86_64-pkg-config
\end{lstlisting}
\item
Falls nötig, ergänzen Sie in der MinGW-Shell
den Pfad zu den neu installierten Programmen:
\begin{lstlisting}[style=cmd,gobble=8]
export PATH=$PATH:/mingw64/bin
\end{lstlisting}
\end{itemize}
\bigskip
\strut\hfill\emph{Viel Erfolg!}
\vfill
\begingroup
\small
\setlength{\leftskip}{3cm}
Stand: 4.\ Februar 2021
% Soweit nicht anders angegeben:\\
Copyright \copyright\ 2014, 2015, 2016, 2018, 2019, 2020, 2021\quad Peter Gerwinski\\
Lizenz: \mylicense
Sie können diese Praktikumsunterlagen einschließlich \LaTeX-Quelltext
% und Beispielprogramme\\
herunterladen unter:\\
\url{https://gitlab.cvh-server.de/pgerwinski/hp}
\endgroup
\end{document}
File added
This diff is collapsed.
File added
This diff is collapsed.
File added
% hp-uebung-20210204.pdf - Exercises on Low-Level Programming
% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021 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: Objektorientierte Tier-Datenbank (Neuauflage), Iterationsfunktionen, dynamisches Bit-Array
\documentclass[a4paper]{article}
\usepackage{pgscript}
\begin{document}
% \thispagestyle{empty}
\section*{Hardwarenahe Programmierung\\
Übungsaufgaben -- 4.\ Februar 2021}
% Diese Übung enthält Punkteangaben wie in einer Klausur.
% Um zu "`bestehen"', müssen Sie innerhalb von 100 Minuten
% unter Verwendung ausschließlich zugelassener Hilfsmittel
% 17 Punkte (von insgesamt \totalpoints) erreichen.
\exercise{Objektorientierte Tier-Datenbank (Neuauflage)}
Diese Aufgabe ist eine Neuauflage von Aufgabe 3 der
Übung vom 28.\ Januar 2021,\\
ergänzt um die Teilaufgaben (e) bis (g).
\medskip
Das auf der nächsten Seite dargestellte Programm
(Datei: \gitfile{hp}{2020ws/20210204}{aufgabe-1a.c})
soll Daten von Tieren verwalten.
Beim Compilieren erscheinen die folgende Fehlermeldungen:
\begin{lstlisting}[style=terminal]
$ ¡gcc -std=c99 -Wall -O aufgabe-1a.c -o aufgabe-1a¿
aufgabe-1a.c: In function 'main':
aufgabe-1a.c:31: error: 'animal' has no member named 'wings'
aufgabe-1a.c:37: error: 'animal' has no member named 'legs'
\end{lstlisting}
Der Programmierer nimmt die auf der nächsten Seite in Rot dargestellten Ersetzungen vor\\
(Datei: \gitfile{hp}{2020ws/20210204}{aufgabe-1b.c}).
Daraufhin gelingt das Compilieren, und die Ausgabe des Programms lautet:
\begin{lstlisting}[style=terminal]
$ ¡gcc -std=c99 -Wall -O aufgabe-1b.c -o aufgabe-1b¿
$ ¡./aufgabe-1b¿
A duck has 2 legs.
Error in animal: cow
\end{lstlisting}
\begin{itemize}
\item[(a)]
Erklären Sie die o.\,a.\ Compiler-Fehlermeldungen.
% \points{2}
\item[(b)]
Wieso verschwinden die Fehlermeldungen nach den o.\,a.\ Ersetzungen?
% \points{3}
\item[(c)]
Erklären Sie die Ausgabe des Programms.
% \points{5}
\item[(d)]
Beschreiben Sie -- in Worten und/oder als C-Quelltext -- einen Weg,
das Programm so zu berichtigen, daß es die Eingabedaten
(``A duck has 2 wings. A cow has 4 legs.'') korrekt speichert und ausgibt. %\\
% \points{4}
\item[(e)]
Schreiben Sie das Programm so um,
daß es keine expliziten Typumwandlungen mehr benötigt.\par
Hinweis: Verwenden Sie \lstinline{union}.
% \points{4}
\item[(f)]
Schreiben Sie das Programm weiter um,
so daß es die Objektinstanzen \lstinline{duck} und \lstinline{cow}
dynamisch erzeugt.\par
Hinweis: Verwenden Sie \lstinline{malloc()} und schreiben Sie Konstruktoren.
% \points{4}
\item[(g)]
Schreiben Sie das Programm weiter um,
so daß die Ausgabe nicht mehr direkt im Hauptprogramm erfolgt,
sondern stattdessen eine virtuelle Methode \lstinline{print()}
aufgerufen wird.\par
Hinweis: Verwenden Sie in den Objekten Zeiger auf Funktionen,
und initialisieren Sie diese in den Konstruktoren.
% \points{4}
\end{itemize}
\begin{minipage}[t]{0.34\textwidth}
\begin{lstlisting}[gobble=6,xleftmargin=0pt]
#include <stdio.h>
#define ANIMAL 0
#define WITH_WINGS 1
#define WITH_LEGS 2
typedef struct animal
{
int type;
char *name;
} animal;
typedef struct with_wings
{
int wings;
} with_wings;
typedef struct with_legs
{
int legs;
} with_legs;
\end{lstlisting}
\end{minipage}\hfill
\begin{minipage}[t]{0.65\textwidth}
\begin{lstlisting}[gobble=6,xleftmargin=0pt]
int main (void)
{
animal *a[2];
animal duck;
a[0] = &duck;
a[0]->type = WITH_WINGS;
a[0]->name = "duck";
a[0]->wings = 2;
animal cow;
a[1] = &cow;
a[1]->type = WITH_LEGS;
a[1]->name = "cow";
a[1]->legs = 4;
for (int i = 0; i < 2; i++)
if (a[i]->type == WITH_LEGS)
printf ("A %s has %d legs.\n", a[i]->name,
((with_legs *) a[i])-> legs);
else if (a[i]->type == WITH_WINGS)
printf ("A %s has %d wings.\n", a[i]->name,
((with_wings *) a[i])-> wings);
else
printf ("Error in animal: %s\n", a[i]->name);
return 0;
}
\end{lstlisting}
\begin{picture}(0,0)
\color{red}
\put(3.7,6.207){\vector(-1,0){0.7}}
\put(3.8,6.207){\makebox(0,0)[l]{\lstinline[basicstyle=\color{red}]{((with_legs *) a[1])->legs = 4;}}}
\put(4.0,8.735){\vector(-1,0){0.7}}
\put(4.1,8.735){\makebox(0,0)[l]{\lstinline[basicstyle=\color{red}]{((with_wings *) a[0])->wings = 2;}}}
\end{picture}
\end{minipage}
\exercise{Iterationsfunktionen}
Wir betrachten das folgende Programm (\gitfile{hp}{2020ws/20210204}{aufgabe-2.c}):
\begin{minipage}[t]{0.4\textwidth}
\begin{lstlisting}[gobble=6]
#include <stdio.h>
void foreach (int *a, void (*fun) (int x))
{
for (int *p = a; *p >= 0; p++)
fun (*p);
}
void even_or_odd (int x)
{
if (x % 2)
printf ("%d ist ungerade.\n", x);
else
printf ("%d ist gerade.\n", x);
}
\end{lstlisting}
\end{minipage}\hfill
\begin{minipage}[t]{0.52\textwidth}
\begin{lstlisting}[gobble=6]
int main (void)
{
int numbers[] = { 12, 17, 32, 1, 3, 16, 19, 18, -1 };
foreach (numbers, even_or_odd);
return 0;
}
\end{lstlisting}
\begin{enumerate}[\quad(a)]
\item
Was bedeutet \lstinline{void (*fun) (int x)},
und welchen Sinn hat seine Verwendung in der Funktion \lstinline{foreach()}?
% \points{2}
\item
Schreiben Sie das Hauptprogramm \lstinline{main()} so um,
daß es unter Verwendung der Funktion \lstinline{foreach()}
die Summe aller positiven Zahlen in dem Array berechnet.
Sie dürfen dabei weitere Funktionen sowie globale Variable einführen.
% \points{4}
\end{enumerate}
\end{minipage}
\clearpage
\exercise{Dynamisches Bit-Array}
Schreiben Sie die folgenden Funktionen zur Verwaltung eines dynamischen Bit-Arrays:
\begin{itemize}
\item
\lstinline{void bit_array_init (int n)}\\
Das Array initialisieren, so daß man \lstinline{n} Bits darin speichern kann.\\
Die Array-Größe \lstinline{n} ist keine Konstante, sondern erst im laufenden Programm bekannt.\\
Die Bits sollen auf den Anfangswert 0 initialisiert werden.
\item
\lstinline{void bit_array_set (int i, int value)}\\
Das Bit mit dem Index \lstinline{i} auf den Wert \lstinline{value} setzen.\\
Der Index \lstinline{i} darf von \lstinline{0} bis \lstinline{n - 1} gehen;
der Wert \lstinline{value} darf 1 oder 0 sein.
\item
\lstinline{void bit_array_flip (int i)}\\
Das Bit mit dem Index \lstinline{i} auf den entgegengesetzten Wert setzen,\\
also auf 1, wenn er vorher 0 ist, bzw.\ auf 0, wenn er vorher 1 ist.\\
Der Index \lstinline{i} darf von \lstinline{0} bis \lstinline{n - 1} gehen.
\item
\lstinline{int bit_array_get (int i)}\\
Den Wert des Bit mit dem Index \lstinline{i} zurückliefern.\\
Der Index \lstinline{i} darf von \lstinline{0} bis \lstinline{n - 1} gehen.
\item
\lstinline{void bit_array_resize (int new_n)}\\
Die Größe des Arrays auf \lstinline{new_n} Bits ändern.\\
Dabei soll der Inhalt des Arrays, soweit er in die neue Größe paßt, erhalten bleiben.\\
Neu hinzukommende Bits sollen auf 0 initialisiert werden.
\item
\lstinline{void bit_array_done (void)}\\
Den vom Array belegten Speicherplatz wieder freigeben.
\end{itemize}
Bei Bedarf dürfen Sie den Funktionen zusätzliche Parameter mitgeben,
beispielsweise um mehrere Arrays parallel verwalten zu können.
(In der objektorientierten Programmierung wäre dies der implizite Parameter \lstinline{this},
der auf die Objekt-Struktur zeigt.)
Die Bits sollen möglichst effizient gespeichert werden,
z.\,B.\ jeweils 8 Bits in einer \lstinline{uint8_t}-Variablen.
Die Funktionen sollen möglichst robust sein,
d.\,h.\ das Programm darf auch bei unsinnigen Parameterwerten nicht abstürzen,
sondern soll eine Fehlermeldung ausgeben.
\medskip
Die folgenden \textbf{Hinweise} beschreiben
einen möglichen Weg, die Aufgabe zu lösen.
Es seht Ihnen frei, die Aufgabe auch auf andere Weise zu lösen.
\begin{itemize}
\item
Setzen Sie zunächst voraus, daß das Array die konstante Länge 8 hat,
und schreiben Sie zunächst nur die Funktionen
\lstinline{bit_array_set()}, \lstinline{bit_array_flip()} und
\lstinline{bit_array_get()}.
\item
Verallgemeinern Sie nun auf eine konstante Länge,
bei der es sich um ein Vielfaches von 8 handelt.
\item
Implementieren Sie nun die Überprüfung auf unsinnige Parameterwerte.
Damit können Sie sich gleichzeitig von der Bedingung lösen,
daß die Länge des Arrays ein Vielfaches von 8 sein muß.
\item
Gehen Sie nun von einem statischen zu einem dynamischen Array über,
und implementieren Sie die Funktionen \lstinline{bit_array_init()},
\lstinline{bit_array_done()} und \lstinline{bit_array_resize()}.
\end{itemize}
% \points{14}
%
% \medskip
%
% (Hinweis für die Klausur:
% Abgabe in digitaler Form ist erwünscht, aber nicht zwingend.)
\begin{flushright}
\textit{Viel Erfolg!}
\end{flushright}
\makeatletter
\immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}}
\makeatother
\end{document}
#include <stdio.h>
#define ANIMAL 0
#define WITH_WINGS 1
#define WITH_LEGS 2
typedef struct animal
{
int type;
char *name;
} animal;
typedef struct with_wings
{
int type;
char *name;
int wings;
} with_wings;
typedef struct with_legs
{
int type;
char *name;
int legs;
} with_legs;
int main (void)
{
animal *a[2];
animal duck;
a[0] = &duck;
a[0]->type = WITH_WINGS;
a[0]->name = "duck";
((with_wings *) a[0])->wings = 2;
animal cow;
a[1] = &cow;
a[1]->type = WITH_LEGS;
a[1]->name = "cow";
((with_legs *) a[1])->legs = 4;
for (int i = 0; i < 2; i++)
if (a[i]->type == WITH_LEGS)
printf ("A %s has %d legs.\n", a[i]->name,
((with_legs *) a[i])-> legs);
else if (a[i]->type == WITH_WINGS)
printf ("A %s has %d wings.\n", a[i]->name,
((with_wings *) a[i])-> wings);
else
printf ("Error in animal: %s\n", a[i]->name);
return 0;
}
#include <stdio.h>
#define ANIMAL 0
#define WITH_WINGS 1
#define WITH_LEGS 2
typedef struct animal
{
int type;
char *name;
} animal;
typedef struct with_wings
{
int type;
char *name;
int wings;
} with_wings;
typedef struct with_legs
{
int type;
char *name;
int legs;
} with_legs;
int main (void)
{
animal *a[2];
with_wings duck;
a[0] = (animal *) &duck;
a[0]->type = WITH_WINGS;
a[0]->name = "duck";
((with_wings *) a[0])->wings = 2;
with_legs cow;
a[1] = (animal *) &cow;
a[1]->type = WITH_LEGS;
a[1]->name = "cow";
((with_legs *) a[1])->legs = 4;
for (int i = 0; i < 2; i++)
if (a[i]->type == WITH_LEGS)
printf ("A %s has %d legs.\n", a[i]->name,
((with_legs *) a[i])-> legs);
else if (a[i]->type == WITH_WINGS)
printf ("A %s has %d wings.\n", a[i]->name,
((with_wings *) a[i])-> wings);
else
printf ("Error in animal: %s\n", a[i]->name);
return 0;
}
#include <stdio.h>
#define ANIMAL 0
#define WITH_WINGS 1
#define WITH_LEGS 2
typedef struct animal
{
int type;
char *name;
} animal;
typedef struct with_wings
{
int type;
char *name;
int wings;
} with_wings;
typedef struct with_legs
{
int type;
char *name;
int legs;
} with_legs;
int main (void)
{
animal *a[2];
with_wings duck;
a[0] = (animal *) &duck;
duck.type = WITH_WINGS;
duck.name = "duck";
duck.wings = 2;
with_legs cow;
a[1] = (animal *) &cow;
cow.type = WITH_LEGS;
cow.name = "cow";
cow.legs = 4;
for (int i = 0; i < 2; i++)
if (a[i]->type == WITH_LEGS)
printf ("A %s has %d legs.\n", a[i]->name,
((with_legs *) a[i])-> legs);
else if (a[i]->type == WITH_WINGS)
printf ("A %s has %d wings.\n", a[i]->name,
((with_wings *) a[i])-> wings);
else
printf ("Error in animal: %s\n", a[i]->name);
return 0;
}
#include <stdio.h>
#define ANIMAL 0
#define WITH_WINGS 1
#define WITH_LEGS 2
typedef struct
{
int type;
char *name;
} base;
typedef struct
{
int type;
char *name;
int wings;
} with_wings;
typedef struct
{
int type;
char *name;
int legs;
} with_legs;
typedef union
{
base b;
with_wings w;
with_legs l;
} animal;
int main (void)
{
animal *a[2];
animal duck;
a[0] = &duck;
duck.b.type = WITH_WINGS;
duck.b.name = "duck";
duck.w.wings = 2;
animal cow;
a[1] = &cow;
cow.b.type = WITH_LEGS;
cow.b.name = "cow";
cow.l.legs = 4;
for (int i = 0; i < 2; i++)
if (a[i]->b.type == WITH_LEGS)
printf ("A %s has %d legs.\n", a[i]->b.name,
a[i]->l.legs);
else if (a[i]->b.type == WITH_WINGS)
printf ("A %s has %d wings.\n", a[i]->b.name,
a[i]->w.wings);
else
printf ("Error in animal: %s\n", a[i]->b.name);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define ANIMAL 0
#define WITH_WINGS 1
#define WITH_LEGS 2
typedef struct
{
int type;
char *name;
} base;
typedef struct
{
int type;
char *name;
int wings;
} with_wings;
typedef struct
{
int type;
char *name;
int legs;
} with_legs;
typedef union
{
base b;
with_wings w;
with_legs l;
} animal;
animal *new_with_wings (char *name, int wings)
{
animal *a = malloc (sizeof (with_wings));
a->b.type = WITH_WINGS;
a->b.name = name;
a->w.wings = wings;
return a;
}
animal *new_with_legs (char *name, int legs)
{
animal *a = malloc (sizeof (with_legs));
a->b.type = WITH_LEGS;
a->b.name = name;
a->l.legs = legs;
return a;
}
int main (void)
{
animal *a[2] = { new_with_wings ("duck", 2),
new_with_legs ("cow", 4) };
for (int i = 0; i < 2; i++)
if (a[i]->b.type == WITH_LEGS)
printf ("A %s has %d legs.\n", a[i]->b.name,
a[i]->l.legs);
else if (a[i]->b.type == WITH_WINGS)
printf ("A %s has %d wings.\n", a[i]->b.name,
a[i]->w.wings);
else
printf ("Error in animal: %s\n", a[i]->b.name);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define ANIMAL 0
#define WITH_WINGS 1
#define WITH_LEGS 2
union animal;
typedef struct
{
int type;
char *name;
void (*print) (union animal *this);
} base;
typedef struct
{
int type;
char *name;
void (*print) (union animal *this);
int wings;
} with_wings;
typedef struct
{
int type;
char *name;
void (*print) (union animal *this);
int legs;
} with_legs;
typedef union animal
{
base b;
with_wings w;
with_legs l;
} animal;
void print_with_wings (animal *this)
{
printf ("A %s has %d wings.\n", this->b.name, this->w.wings);
}
void print_with_legs (animal *this)
{
printf ("A %s has %d legs.\n", this->b.name, this->l.legs);
}
animal *new_with_wings (char *name, int wings)
{
animal *a = malloc (sizeof (with_wings));
a->b.type = WITH_WINGS;
a->b.name = name;
a->b.print = print_with_wings;
a->w.wings = wings;
return a;
}
animal *new_with_legs (char *name, int legs)
{
animal *a = malloc (sizeof (with_legs));
a->b.type = WITH_LEGS;
a->b.name = name;
a->b.print = print_with_legs;
a->l.legs = legs;
return a;
}
int main (void)
{
animal *a[2] = { new_with_wings ("duck", 2),
new_with_legs ("cow", 4) };
for (int i = 0; i < 2; i++)
a[i]->b.print (a[i]);
return 0;
}
../common/logo-hochschule-bochum-cvh-text-v2.pdf
\ No newline at end of file
../common/logo-hochschule-bochum.pdf
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment