Vorschau auf das nächste Semester, noch nicht veröffentlicht.
Zur aktuellen Seite

Warm-ups (freiwillig)

Sie müssen nicht alle Warm-ups machen. Suchen Sie sich in der Tabelle das heraus, was Ihnen für eine Aufgabe fehlt:

ÜbtHilft bei
Warm-up 1Strings anlegenScrabble, Lesbarkeit
Warm-up 2Über einen String iterierenScrabble, Lesbarkeit
Warm-up 3Zeichen prüfen mit isupperScrabble, Lesbarkeit
Warm-up 4Nur Buchstaben ausgebenLesbarkeit
Warm-up 5Mit Zeichen rechnen: Position im AlphabetScrabble
Warm-up 6Arrays als NachschlagetabelleScrabble
Warm-up 7Ganzzahl- und GleitkommadivisionLesbarkeit

Legen Sie für die Warm-ups eine eigene Datei an, zum Beispiel warmup_aufgaben_1.c für Übung 1, im selben Ordner wie Ihre Übungsaufgaben. Die meisten Warm-ups bauen aufeinander auf: Sie ergänzen die Datei Schritt für Schritt. Lösungen gibt es für die Warm-ups nicht. Unter „Wo zu finden?“ steht jeweils, wo das Thema in Vorlesung und Shorts vorkommt. Mehr dazu im FAQ zu den Warm-ups.

Mit diesem Gerüst lässt sich die Datei von Anfang an kompilieren:

#include <cs50.h>
#include <stdio.h>

int main(void)
{

    return 0;
}

cs50.h stellt Funktionen wie get_string bereit, stdio.h Funktionen wie printf.

Warm-up 1: Strings anlegen

Erstellen Sie einen string namens letters mit dem Inhalt "lol HerWdl!o".

Geben Sie anschließend den Inhalt an der fünften Position des Strings, also das H, mit printf aus. Erinnern Sie sich daran, dass die Zählung des Index-Wertes bei 0 beginnt.

Wo zu finden?
Bei Problemen und Unklarheiten schauen Sie sich am besten noch einmal die Folien und Notizen zur Vorlesung 2. Arrays sowie das Short zu Arrays an.

Warm-up 2: Über einen String iterieren

Erstellen Sie eine Schleife, die über den String iteriert und jeweils die einzelnen char-Werte des Strings ohne Zeilenumbruch ausgibt, sodass lol HerWdl!o ausgegeben wird. Verwenden Sie strlen um die Länge des Strings abzufragen. Geben Sie im Anschluss einen Zeilenumbruch aus.

Vergessen Sie nicht <string.h> in die Datei einzubinden.

Wo zu finden?
Bei Problemen und Unklarheiten schauen Sie sich am besten noch einmal die Folien und Notizen zur Vorlesung 2. Arrays an. Die Funktion und Verwendung von strlen finden Sie auch im CS50 Handbuch.

Warm-up 3: Zeichen prüfen mit isupper

In der Vorlesung wurde bereits die Funktion toupper aus der <ctype.h> Bibliothek vorgestellt. Eine weitere Funktion ist die isupper Funktion. Lesen Sie sich kurz die entsprechende Dokumentation durch.

Binden Sie die <ctype.h> Bibliothek in die Datei ein. Erweitern Sie die Schleife um eine if-Bedingung, die dafür sorgt, dass nur die Großbuchstaben des Strings ausgegeben werden.

Die Ausgabe sollte also folgendermaßen aussehen:

HW

Welchen booleschen Ausdruck müssten Sie in die if-Bedingung schreiben, wenn Ihnen isupper nicht zur Verfügung stünde?

Tipp: Überfliegen Sie die Liste der übrigen Funktionen der <ctype.h> Bibliothek (der Filter-Toggle “frequently used in CS50” sollte standardmäßig aktiviert sein, ansonsten aktivieren). Diese könnten Ihnen in Zukunft nützlich sein.

Wo zu finden?
Bei Problemen und Unklarheiten schauen Sie sich am besten noch einmal die Folien und Notizen zum Programm uppercase.c aus der Vorlesung 2. Arrays an.

Warm-up 4: Nur Buchstaben ausgeben

Ändern Sie die if-Bedingung aus “Warm-up 3”, sodass nur alphabetische Zeichen ausgegeben werden:

lolHerWdlo

Wechseln Sie einmal kurz das Ausgabeformat von printf von %c auf %i, sodass die char-Werte als Integer ausgegeben werden. Erinnern Sie sich, was hinter der Ausgabe steckt?

Wo zu finden?
Bei Problemen und Unklarheiten schauen Sie sich am besten noch einmal die Folien und Notizen zur Vorlesung 2. Arrays an. Beachten Sie zudem den Tipp in Warm-up 3.

Warm-up 5: Mit Zeichen rechnen: Position im Alphabet

Errechnen Sie nun jeweils die Position des Buchstabens im Alphabet (d.h. für A die Position 1, B die Position 2 usw.). Erinnern Sie sich, dass Sie direkt mit char-Werten rechnen können (z.B. 'A' - 'A' == 0).

Ändern Sie dazu printf, sodass zunächst der Buchstabe gefolgt von einem : ausgegeben wird und anschließend seine Position im Alphabet. Fügen Sie außerdem einen Zeilenumbruch nach jedem Buchstaben ein.

Tipp: Unabhängig von der Groß- oder Kleinschreibung bleibt die Position eines Buchstabens im Alphabet gleich. Sie können den Buchstaben jeweils in einen Kleinbuchstaben (oder Großbuchstaben) umwandeln, bevor Sie seine Position im Alphabet errechnen. Erinnern Sie sich, dass es hierzu die Funktion tolower (oder toupper) gibt. Dadurch benötigen Sie keine if else Statements und können die Berechnung innerhalb einer Zeile direkt im printf-Aufruf durchführen.

Die Ausgabe sollte folgendermaßen aussehen:

l: 12
o: 15
l: 12
H: 8
e: 5
r: 18
W: 23
d: 4
l: 12
o: 15
Wo zu finden?
Bei Problemen und Unklarheiten schauen Sie sich am besten noch einmal die Folien und Notizen zum Programm uppercase.c aus der Vorlesung 2. Arrays an.

Warm-up 6: Arrays als Nachschlagetabelle

Dann wollen wir uns jetzt noch um die Entschlüsselung der Zeichenfolge lol HerWdl!o kümmern.

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 6

*/

Und fügen Sie folgenden Code oben in die Datei ein:

#include <cs50.h>
#include <stdio.h>
#include <string.h>

int main()
{
  string letters = "lol HerWdl!o";


  
  for (int i = 0, length = strlen(letters); i < length; i++)
  {
    printf("%c\n", letters[i]);
  }
  printf("\n");
  return 0;
}

Dieser Code kommt Ihnen hoffentlich bekannt vor! So (oder so ähnlich) sollte Ihr Code nach Warm-up 2 ausgesehen haben.

Beim Zugriff auf den Array-Index können auch Operationen und Funktionen ausgeführt und verschachtelt werden. Beispielsweise kann man mit letters[strlen(letters) - 1] auf das letzte Zeichen in diesem String zugreifen (strlen gibt die Anzahl aller Zeichen zurück und da ein Array mit dem 0-Index beginnt, muss noch eine 1 abgezogen werden).

Um die Zeichenfolge lol HerWdl!o zu entwirren, fügen Sie ein int-Array namens map wie folgt unterhalb der string-Deklaration ein:

int map[] = {4, 5, 2, 9, 1, 3, 7, 11, 6, 0, 8, 10};

Hinweis: Dies ist die “Instantiation Syntax”, mit der einem Array direkt alle seine Werte zugewiesen werden. In diesem Fall ist es nicht notwendig, die Anzahl der Elemente in die [] zu schreiben, wie es normalerweise der Fall ist.

Statt wie bisher einfach die Buchstaben nacheinander entsprechend des Schleifen-Indexes auszugeben, greifen Sie jeweils auf den Wert des map-Arrays am aktuellen Schleifen-Index zu. Verwenden Sie nun diesen Wert als Index, um auf das entsprechende Zeichen in letters zuzugreifen. Wie eingangs beschrieben, können Sie alle diese Operationen direkt innerhalb der printf-Funktion schachteln.

Erklärung

Anstatt mit dem Index der Schleife nacheinander auf die einzelnen Zeichen des Strings zuzugreifen, greifen Sie nun auf map zu. Als dessen Index verwenden Sie den Index der Schleife, also map[i].

Um dann mit diesem Wert auf den entsprechenden Array-Index von letters zuzugreifen, verschachteln wir die Array-Zugriffe zu letters[map[i]]. Im ersten Schleifendurchlauf bedeutet dies, dass zunächst map[0] abgefragt wird. Dahinter verbirgt sich die Zahl 4. Diese Zahl ist nun der Index, mit dem wir auf den String zugreifen (d.h. letters[4]). Das bedeutet, wir greifen im ersten Schleifendurchlauf auf den Inhalt des Strings an der fünften Position zu, also dem H.

Wahrscheinlich haben Sie es anhand der Buchstaben schon geahnt: Welcher bekannte Ausspruch verbirgt sich hinter der Zeichenfolge?

Wo zu finden?
Bei Fragen und Unklarheiten schauen Sie sich zusätzlich zur obigen Erklärung am besten noch einmal das Short zu Arrays an.

Warm-up 7: Ganzzahl- und Gleitkommadivision

Nun noch ein letzter kleiner Test Ihres Wissens. Überfliegen Sie das folgende Code-Snippet und führen Sie es aus:

#include <stdio.h>
#include <math.h>

int main() {
  int integerA = 11;
  int integerB = 3;
  float floatB = 3;
  int c = 11 / 3;
  float d = 11 / 3;
  float e = 11 / 3.0;
  float f = integerA / floatB;
  float g = (float) 11 / 3;
  float h = integerA / (float) integerB;
  int i = round(11 / 3);
  int j = round(11.0 / 3);
  int k = round(h);
  float l = round(11) / 3;
  
  printf("int c = 11 / 3                         --> %i        (printed with %%i)\n", c);
  printf("float d = 11 / 3;                      --> %f (printed with %%f)\n", d);
  printf("float e = 11 / 3.0;                    --> %f (printed with %%f)\n", e);
  printf("float f = integerA / floatB;           --> %f (printed with %%f)\n", f);
  printf("float g = (float) 11 / 3;              --> %f (printed with %%f)\n", g);
  printf("float h = integerA / (float) integerB; --> %f (printed with %%f)\n", h);
  printf("int i = round(11 / 3);  	       --> %i        (printed with %%i)\n", i);
  printf("int j = round(11.0 / 3); 	       --> %i        (printed with %%i)\n", j);
  printf("int k = round(h); 	               --> %i        (printed with %%i)\n", k);
  printf("float l = round(11) / 3;	       --> %f (printed with %%f)\n", l);
  
  return 0;
}

Wie kommt die jeweilige Ausgabe zustande? Worauf müssen Sie beim Rechnen in C demnach achten? Und warum genau funktioniert eigentlich die letzte Berechnung mit round wie gewünscht? Lesen Sie ggf. die Spezifikation von round in der Dokumentation nach.

Beachten Sie auch, dass zur Verwendung von round <math.h> eingebunden werden muss.

Wo zu finden?
Bei Fragen und Unklarheiten schauen Sie sich am besten noch einmal die Folien und Notizen zum Programm scores.c aus der Vorlesung 2. Arrays und insbesondere das Short zu Datentypen und Variablen an.