Abgabe bis 24.10.2024
Auf den Seiten 2-15 bis 2-19 der Vorlesungsunterlagen sind 15 Grundtypen aufgezählt.
Schreiben Sie ein C-Programm aufgabe1.c
, das zu jedem Grundtyp
je eine lokale Variable mit Initialisierung enthält.
Zusätzlich soll das Programm eine Zeigerdefinition
char* s = "Hallo";
enthalten. Sie müssen also insgesamt 16 Variablen definieren.
Das Programm soll die Adresse, den Platzbedarf, das Alignment,
den Typ, den Namen und den Wert dieser 16 Variablen ausgeben.
Pro Variable soll genau eine Zeile mit den genannten sechs Spalten ausgegeben werden,
immer mit der Adresse am Zeilenanfang.
Das Alignment erhalten Sie per alignof(Typ)
(#include <stdalign.h>
erforderlich).
Abschließend soll das Programm ausgeben, ob es mit dem C-Datenmodell
"ILP32"
, "LP64"
oder "LLP64"
arbeitet,
oder ob keines der drei Modelle vorliegt:
ILP32
-Datenmodell,
wenn die Typen int
(I
),
long int
(L
) und
char*
(P
) je 32 Bit belegenLP64
-Datenmodell liegt vor,
wenn int
32 Bit belegt und
sowohl long int
(L
)
als auch char*
(P
) je 64 Bit belegenLLP64
-Datenmodell liegt vor,
wenn int
sowie long int
je 32 Bit belegen und
sowohl long long int
(LL
)
als auch char*
(P
) je 64 Bit belegen
Hinweise:
Achten Sie bei den Werten auf die richtigen von C unterstützen
printf
-Formatangabe. Bei den Formatangaben für Zahlen brauchen Sie
eine Kombination aus "length modifier" und "conversion specifier".
Ein übersichtliche Darstellung dazu finden Sie unter
https://en.cppreference.com/w/c/io/fprintf.
Andere Quellen sind das Linux Manual (Kommando man 3 printf
)
oder einschlägige Internetseiten wie
https://man7.org/linux/man-pages/index.html
(siehe auch die Literaturseite der Vorlesung).
Eine Beschreibung der C-Datenmodelle finden Sie unter
https://en.cppreference.com/w/c/language/arithmetic_types.
Die Operatoren sizeof
und alignof
liefern Werte vom Typ size_t
.
Speichern Sie die Datei ⤵ Makefile
in Ihr Arbeitverzeichnis der Aufgabe 1. Achten Sie auf den richtigen Namen
Makefile
ohne Endung. Falls beim Download eine Endung .txt
ergänzt wurde, entfernen Sie diese Endung.
Übersetzen und binden Sie dann Ihr Programm mit dem Befehl
Diesen und alle weiteren Befehle abtippen, nicht mit der Maus kopieren, wenn Sie etwas lernen wollen!
make clean make
Das Programm make
automatisiert mittels der Beschreibungen
in Makefile
das Übersetzen und Binden Ihres Programms.
Die Entsprechung dazu bei den Java-Übungen in Programmiertechnik 1
war das Automatisierungswerkzeug ant
mit build.xml
.
Führen Sie Ihr Programm aus und lassen Sie die Ausgaben auch mal vom
sort
-Kommando aufsteigend oder absteigend sortieren:
./aufgabe1 ./aufgabe1 | sort ./aufgabe1 | sort -r
Betrachten Sie die Ausgaben und beantworten Sie folgende Fragen:
Prüfen Sie, ob das Analysewerkzeug cppcheck
Probleme in Ihrem
Quellcode meldet.
Versuchen Sie, wenn möglich, die Probleme zu beheben.
Welche Problemen lassen sich nicht beheben?
cppcheck --enable=warning,style --std=c11 aufgabe1.cSie können
cppcheck
auch vereinfacht über
make
aufrufen:
make cppcheck
Die Entsprechung zu cppcheck
bei den Java-Übungen in
Programmiertechnik 1 war das Analysewerkzeug spotbugs
.
Erstellen Sie ein Protokoll Ihres Test-Schritts.
Öffnen Sie dazu ein neues Terminal und rufen Sie darin
make clean
auf und wiederholen Sie alle Kommandos
aus dem Test-Schritt.
Markieren Sie die Terminalausgaben abschließend,
öffnen Sie einen Texteditor und
kopieren Sie die markierten Terminalausgaben in den Editor.
Speichern Sie mit dem Editor die kopierte Konsolenausgabe als Datei
protokoll-aufgabe1.txt
im gleichen Verzeichnis wie Ihr Programm.
Ergänzen Sie mit dem Texteditor in protokoll-aufgabe1.txt
Ihre Antworten auf die Fragen aus dem Test-Schritt.
Verwenden Sie im Windows-Terminal cmd
, powershell
oder WSL
zum Markieren und Kopieren das Menü links oben,
darin zuerst Bearbeiten -> Alle auswählen
und dann Bearbeiten -> Kopieren
,
alternativ die Tastenkürzel Strg-A
und Enter
.
Im Git-Bash-Terminal funktioniert es analog mit dem Kontextmenü,
das Sie per rechter Maustaste aufrufen können.
Das Einfügen im Editor funtioniert per Strg-V
oder
über Editormenüs.
Führen Sie Ihr Programm und Ihre Protokolldatei vor.
Zeigen Sie das ausgefüllte Teilnahmeprotokoll.
Hinweis:
Der Compiler gcc
darf für Ihr Programm
keine Fehler oder Warnungen mehr ausgeben.
Ihr Programm muss außerdem ordentlich formatierte sein.
Bessern Sie die Formatierung gegebenenfalls mit astyle
nach:
astyle -p -H --style=ansi aufgabe1.c
aufgabe1-int.c
Ihres Programms,
die Variablen mit den in C99 eingeführten 28 ganzzahligen Typen
fester Länge int8_t
, int16_t
usw. definiert.
Initialisieren Sie die Variablen jeweils mit der größten
darstellbaren ZahlINT8_MAX
, INT16_MAX
usw..
Das Programm soll wie im Pflichtteil jeweils Adresse, Platzbedarf, Typ, Name
und Wert der 28 Variablen ausgeben. Verwenden Sie für die Ausgabe des
Werts die ebenfalls in C99 eingeführten Formatangaben PRId8
,
PRId16
usw..
Hinweis: die Typen mit den zugehörigen symbolischen Konstanten und Formatangaben finden Sie unter https://en.cppreference.com/w/c/types/integer
Übersetzen, binden, prüfen und testen Sie Ihr Programm mit den folgenden Aufrufen:
make TARGET=aufgabe1-int make TARGET=aufgabe1-int cppcheck ./aufgabe1-int
Erstellen Sie eine Version aufgabe1-ansi.c
Ihres Programms,
die sich mit dem Sprachstandard C89 (auch ANSI-C genannt) begnügt.
ANSI-C war auch nach der Veröffentlichung von C99 in der Praxis in
weitem Gebrauch.
Variablendefinitionen und Anweisungen dürfen in C89 nicht gemischt werden.
Definieren Sie deshalb alle Variablen am Anfang von main
gleich
nach der öffnenden geschweiften Klammer.
Die ganzzahlige Datentypen long long int
und
unsigned long long int
sowie den Datentyp
bool
bzw. _Bool
gab es in C89 noch nicht.
Es gab in C89 auch noch nicht für alle Zahltypen passende
printf
-Formatangaben.
Verwenden Sie deshalb für sizeof
-Werte %lu
und
fügen Sie vor dem zugehörigen Argument eine Typanpassung
(unsigned long)
ein.
Ein-Byte-Zahlen geben Sie einfach mit %d
bzw. %u
aus.
Die Typanpassung des zugehörigen Arguments funktioniert hier automatisch.
Übersetzen, binden, prüfen und testen Sie Ihr Programm mit den folgenden Aufrufen:
make STD=c89 TARGET=aufgabe1-ansi make STD=c89 TARGET=aufgabe1-ansi cppcheck ./aufgabe1-ansi