Übung 1
- Bearbeiten Sie Hello, It’s Me.
- Bearbeiten Sie Mario.
- Bearbeiten Sie Bargeld.
Warm-Up-Aufgaben
Erstellen Sie für jede Übungseinheit jeweils eine eigene Datei für die Warm-Up-Aufgaben in dem Projektverzeichnis, in dem Sie auch die Übungsaufgaben bearbeiten werden.
Weitere Informationen finden Sie in diesem FAQ (Warm-Up-Aufgaben).
Als kompilierbares Codegerüst können Sie zu Beginn folgendes Snippet in Ihre Datei kopieren:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
return 0;
}
Beachten Sie insbesondere den Import der CS50-Bibliothek und der “Standard Input and Output”-Bibliotheken.
Warm-Up 1
Dank Professor Brian Kernighan wurde “hello, world” (Link führt zu YouTube, nicht kursrelevant) in Hunderten von Sprachen implementiert. Beginnen wir also mit dieser Tradition.
Geben Sie ein einfaches Hello World\n
auf der Konsole aus.
Schritt für Schritt
Öffnen Sie VS Code entsprechend Ihrem Setup.
Führen Sie cd
in Ihrem Terminalfenster aus. Die Eingabeaufforderung Ihres Terminalfensters sollte wie folgt aussehen:
$
Sie können nun Folgendes ausführen,
code warmup_aufgaben_1.c
um eine Datei namens warmup_aufgaben_1.c
zu erstellen, in die Sie Ihren Code schreiben können. Im Endeffekt passiert hier aber nichts anderes, als wenn man eine Datei mit dem Namen warmup_aufgaben_1.c
auf die übliche Art und Weise erstellt. Nur schneller und effizienter.
Kompilieren und Ausführen
Wenn Sie mit dem Programm fertig sind, können Sie es mit folgendem Befehl kompilieren, unter der Annahme, dass die Datei warmup_aufgaben_1.c
heißt (ansonsten entsprechend anpassen):
make warmup_aufgaben_1
Wenn Sie keine Fehlermeldung sehen, wurde das Programm erfolgreich kompiliert! Sie können dies mit
ls
überprüfen. Es sollte nun nicht nur warmup_aufgaben_1.c
(das ist der Quellcode), sondern auch warmup_aufgaben_1
(darin steht der Maschinencode) aufgelistet werden.
Wenn Sie eine Fehlermeldung sehen, versuchen Sie, Ihren Code zu korrigieren und ihn erneut zu kompilieren.
Sobald Ihr Code erfolgreich kompiliert wurde, können Sie Ihr Programm mit folgendem Befehl ausführen:
./warmup_aufgaben_1
Wo zu finden?
Warm-Up 2
Geben Sie Hello World\n
in Abhängigkeit von einer Variablen n
mal auf der Konsole aus. Initialisieren Sie n
auf den Wert 5
.
Implementieren Sie diese Aufgabe in drei Varianten:
- Verwenden Sie eine
while
-Schleife. - Verwenden Sie eine
for
-Schleife. - Verwenden Sie eine
do while
-Schleife.
Für die verschiedenen Varianten können die vorhergehenden Schleifen, wie im entsprechenden FAQ-Eintrag beschrieben, jeweils mit der Blockkommentar-Syntax /* */
auskommentiert werden.
Die Ausgabe sollte folgendermaßen aussehen:
Hello World
Hello World
Hello World
Hello World
Hello World
Welcher Unterschied besteht zwischen einer do while
-Schleife und einer while
- oder for
-Schleife? Mit welchem Wert für n
funktioniert die do while
-Schleife in diesem Kontext nicht wie gewünscht?
Wo zu finden?
Warm-Up 3
Arbeiten Sie für die folgenden Warm-Ups mit der for
-Schleifen Variante weiter.
Ergänzen Sie die Ausgabe von “Hello World” mit dem Index des aktuellen Schleifendurchlaufs (d.h. “Hello World 0”, “Hello World 1” usw.). Verwenden Sie eine if
-Bedingung innerhalb der Schleife, sodass die printf
-Funktion nicht bei dem Indexwert 3
aufgerufen wird.
Mit n = 5
sollte die Ausgabe also wie folgt aussehen:
Hello World 0
Hello World 1
Hello World 2
Hello World 4
Wo zu finden?
Warm-Up 4
Lagern Sie diese Funktionalität (ohne die zusätzliche if-Bedingung
) in eine separate Funktion namens print_n_times
aus, die einen int
entgegennimmt und entsprechend häufig “Hello World” ausgibt. In der main
-Funktion sollte nur diese Funktion mit einem entsprechendem Argument aufgerufen werden, um “Hello World” n
mal auf der Konsole ausgeben zu lassen. Vergessen Sie nicht den Funktionsprototypen oberhalb der main
-Funktion einzufügen, wenn Sie die Funktion unterhalb der main
-Funktion definieren.
Passen Sie anschließend in der Funktion den Schleifenkopf der for
-Schleife so an, dass der ausgegebene Index mit dem Wert 1
beginnt und am Ende dem Wert von n
entspricht. Bei n = 5
sollte die Ausgabe also folgendermaßen aussehen:
Hello World 1
Hello World 2
Hello World 3
Hello World 4
Hello World 5
Wo zu finden?
meow()
aus der Vorlesung. Weitere Erklärungen zur Implementation von Funktionen gibt es in der Section 1.
Warm-Up 5
Nehmen Sie nun folgende Änderungen innerhalb der print_n_times
-Funktion vor:
- Geben Sie statt “Hello World” nun einfach ein “+” aus (ohne Zeilenumbruch!).
- Geben Sie am Ende – nachdem die Schleife durchgelaufen ist – einen einzelnen Zeilenumbruch mit
printf
aus.
Multiplizieren Sie beim Aufruf von print_n_times
außerdem das übergebene Argument n
mit 4
(also print_n_times(n * 4);
)
So sollte die Ausgabe dann aussehen:
++++++++++++++++++++
print_n_times
gibt nun also nicht mehr mehrere Zeilen aus, sondern in Abhängigkeit von n
das “+” nacheinander als eine Zeile.
Rufen Sie nun mittels einer weiteren Schleife in der main
-Funktion die print_n_times
-Funktion in Abhängigkeit von n
mehrfach (im Falle von n = 5
also 5 Mal) auf, sodass ein kleiner Gartenzaun ausgegeben wird:
++++++++++++++++++++
++++++++++++++++++++
++++++++++++++++++++
++++++++++++++++++++
++++++++++++++++++++
Wo zu finden?
mario.c
aus der Vorlesung. Geschachtelte Schleifen kennen Sie auch aus der Section 1.
Warm-Up 6
Kommentieren Sie den bisherigen Code mittels der Blockkommentar-Syntax aus (dann haben Sie all Ihren geschrieben Code weiterhin in einer Datei zur Verfügung):
/*
// Code bis Warm-Up 5
*/
Funktionen können auch Werte zurückgeben. Schreiben Sie eine Funktion divide
, die zwei int
Werte entgegennimmt, die beiden Werte dividiert (der erste Wert soll dabei der Dividend, der zweite der Divisor sein) und den Quotienten zurückgibt. Vergessen Sie nicht den Funktionsprototypen oberhalb der main
-Funktion einzufügen, wenn Sie die Funktion unterhalb der main
-Funktion definieren.
Die main
-Funktion kann wie folgt übernommen werden:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int dividend = get_int("Input dividend: ");
int divisor = get_int("Input divisor: ");
int quotient = divide(dividend, divisor);
printf("%i / %i = %i\n", dividend, divisor, quotient);
}
Bei korrekter Implementierung sollte bei der Programmausführung der entsprechende Quotient ausgegeben werden. Jedoch wird aufgrund der Verwendung von int
-Typen die Berechnung jeweils trunkiert, d.h. die Nachkommastellen werden abgeschnitten (z.B. ist 7 / 5 = 1
eine korrekte Ausgabe).
Achten Sie auch darauf, zu prüfen, ob der Divisor 0
ist, um einen Fehler aufgrund der Division durch 0
abzufangen. Geben Sie in diesem Fall eine kurze Fehlermeldung aus und return
en Sie, sagen wir, den Wert 2147483647
, also z.B.:
Error: Division by zero is not allowed.
10 / 0 = 2147483647
Was würde bei einem Divisor mit dem Wert 0
ausgegeben werden, wenn Sie 2147483647 + 1
zurückgeben würden? Wie nennt man dieses Phänomen?
Übrigens, die Verwendung von 2147483647
direkt im Code ist ein Beispiel für eine sogenannte Magische Zahl.
Wo zu finden?
calculator.c
und die add()
-Funktion aus der Vorlesung. Was müssen Sie ändern, damit dividiert statt addiert wird? Bei Problemen und Unklarheiten schauen Sie sich zusätzlich noch einmal das Short zu Operatoren sowie die Folien und Notizen zur Vorlesung 1. C an.