Algorithmen
Inf-Einf-B · Vorlesung 3, erster Teil
Prof. Dr. Dominik Herrmann
Einführung in die Informatik (Inf-Einf-B)
Otto-Friedrich-Universität Bamberg
WiSe 2026/27
Inf-Einf-B · Vorlesung 3, erster Teil
Prof. Dr. Dominik Herrmann
Einführung in die Informatik (Inf-Einf-B)
Otto-Friedrich-Universität Bamberg
WiSe 2026/27
strlen aufgerufen?string s = "Hallo";
for (int i = 0; i < strlen(s); i++)
{
printf("%c", s[i]);
}
6-mal: Die Bedingung wird vor jedem Durchlauf geprüft, auch vor dem, der nicht mehr stattfindet.
Die letzte Quizfrage war: Wie oft wird strlen in dieser Schleife aufgerufen?
string s = "Hallo";
for (int i = 0; i < strlen(s); i++)
{
printf("%c", s[i]);
}
Die Antwort ist 6: Die Bedingung i < strlen(s) wird vor jedem Durchlauf geprüft, auch vor dem, der nicht mehr stattfindet. Fünf Buchstaben, also fünf Durchläufe und eine sechste Prüfung.
char s[4000001];
...
int zaehler = 0;
for (int i = 0; i < strlen(s); i++)
{
if (s[i] == 'a')
{
zaehler++;
}
}
$ time ./laenge 250000
250000
real 0m0.595s
Macht das einen Unterschied? Bei "Hallo" nicht. Bei einem sehr langen String schon: strlen zählt jedes Mal alle Zeichen bis zum \0, und das in jedem Durchlauf. Das folgende Programm baut einen String aus lauter a, so lang, wie Sie es beim Aufruf angeben, und zählt dann die a. Der String liegt in einem globalen Array oben in der Datei, außerhalb von main. Ein globales Array ist mit Nullen vorbelegt: Das \0 hinter dem letzten a steht also schon da, und vier Millionen Zeichen haben sicher Platz. Wie man so viel Speicher besser anfordert, sehen Sie in Vorlesung 4.
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s[4000001];
int main(int argc, string argv[])
{
// Einen String aus lauter 'a' bauen, so lang wie angegeben
int laenge = atoi(argv[1]);
for (int i = 0; i < laenge; i++)
{
s[i] = 'a';
}
// Jedes Zeichen einmal ansehen
int zaehler = 0;
for (int i = 0; i < strlen(s); i++)
{
if (s[i] == 'a')
{
zaehler++;
}
}
printf("%i\n", zaehler);
}
Mit time vor dem Aufruf misst das Terminal, wie lange ein Programm läuft (Zeile real):
$ time ./laenge 250000
250000
real 0m0.595s
Gemessen auf dem Rechner der Vorlesung (im Kurs-Image):
| Zeichen | i < strlen(s) |
n = strlen(s) (siehe unten) |
|---|---|---|
| 250 000 | 0,6 s | wenige Tausendstel |
| 500 000 | 2,4 s | wenige Tausendstel |
| 1 000 000 | 9,6 s | wenige Tausendstel |
| 2 000 000 | etwa 38 s | wenige Tausendstel |
Doppelt so viele Zeichen, viermal so lange. Bei n Zeichen läuft die Schleife n-mal, und jeder Aufruf von strlen zählt wieder n Zeichen: zusammen etwa n · n Schritte.
for (int i = 0, n = strlen(s); i < n; i++)
Erster Teil: läuft einmal und legt i und n an.
Bedingung: vor jedem Durchlauf, nur noch i < n.
$ time ./laenge1 2000000
2000000
real 0m0.003s
Die Abhilfe stand schon in Notes 2 (Abschnitt Stringlänge), hier noch einmal Schritt für Schritt. Der Kopf einer for-Schleife hat drei Teile, getrennt durch Semikolons. Der erste Teil läuft genau einmal, vor dem ersten Durchlauf. Die Bedingung in der Mitte prüft das Programm vor jedem Durchlauf neu. Steht strlen(s) dort, zählt es also vor jedem Durchlauf wieder alle Zeichen.
Deshalb kommt der Aufruf in den ersten Teil: Die Länge wird einmal vor der Schleife bestimmt und in n gemerkt.
for (int i = 0, n = strlen(s); i < n; i++)
Im ersten Teil dürfen Sie mehrere Variablen desselben Typs anlegen, durch ein Komma getrennt: hier i mit 0 und n mit der Länge. Die Bedingung vergleicht danach nur noch zwei Zahlen. Jetzt ruft das Programm strlen genau einmal auf. Eine Million Zeichen dauern nur noch wenige Tausendstel Sekunden. Die Zeit steigt jetzt nur noch so wie die Länge: Doppelt so viele Zeichen, doppelt so lange, aber auf dem Niveau von Tausendsteln.
Moderne Compiler können so einen Aufruf oft selbst aus der Schleife ziehen, wenn man sie optimieren lässt (-O2). make übersetzt in unserer Kursumgebung ohne Optimierung, deshalb sehen Sie den Unterschied hier so deutlich. Verlassen sollten Sie sich darauf ohnehin nicht.
Wie man so etwas abschätzt, ohne zu messen, sehen Sie im Abschnitt Laufzeit. Mit time messen Sie in Übung 4 auch die Sortierprogramme.
In Vorlesung 0 haben Sie drei Arten gesehen, in einem Telefonbuch einen Namen zu finden: Seite für Seite blättern, immer zwei Seiten auf einmal, oder das Buch in der Mitte aufschlagen und die falsche Hälfte wegwerfen. Wie viele Schritte das jeweils braucht, hängt von der Zahl der Seiten n ab:
| Seiten n | Seite für Seite | zwei auf einmal | Halbierungen |
|---|---|---|---|
| 8 | 8 | 4 | 3 |
| 16 | 16 | 8 | 4 |
| 32 | 32 | 16 | 5 |
Beim Halbieren kommt mit jeder Verdopplung von n nur ein Schritt dazu. Die Zahl der Schritte ist dann der Logarithmus zur Basis 2 von n, kurz log₂ n: wie oft man n halbieren kann, bis 1 übrig bleibt.
Dasselbe Prinzip funktioniert im Hörsaal. Um herauszufinden, wie viele Personen im Raum sind, gehen alle so vor:
true oder false.Für jede Kiste von links nach rechts
Wenn 50 in der Kiste ist
Gib true zurück
Gib false zurück
Für i von 0 bis n-1
Wenn 50 in kisten[i] ist
Gib true zurück
Gib false zurück
Die einfachste Lösung: Kiste für Kiste von links nach rechts öffnen, bis die 50 auftaucht. Das heißt lineare Suche. Als Pseudocode, also als für Menschen lesbare Anleitung, die schon nach Programm aussieht:
Für jede Kiste von links nach rechts
Wenn 50 in der Kiste ist
Gib true zurück
Gib false zurück
Mit Array-Schreibweise, wie Sie es gleich in C programmieren:
Für i von 0 bis n-1
Wenn 50 in kisten[i] ist
Gib true zurück
Gib false zurück
Für jede Kiste von links nach rechts
Wenn 50 in der Kiste ist
Gib true zurück
Sonst
Gib false zurück
Gibt nach der ersten Kiste auf: Gib false zurück gehört hinter die Schleife.
Das Gib false zurück steht nach der Schleife. Eine häufige falsche Fassung sieht so aus:
Für jede Kiste von links nach rechts
Wenn 50 in der Kiste ist
Gib true zurück
Sonst
Gib false zurück
Sie gibt schon nach der ersten Kiste auf: Liegt dort nicht die 50, kommt false heraus, ohne dass die anderen Kisten geöffnet wurden.
Im schlimmsten Fall liegt die 50 in der letzten Kiste oder gar nicht da. Dann öffnet die lineare Suche alle n Kisten.
Jetzt liegen die Scheine sortiert in den Kisten, vom kleinsten zum größten:
| Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| Schein | 1 | 5 | 10 | 20 | 50 | 100 | 500 |
Dann geht es schneller, wie beim Telefonbuch: Öffnen Sie die mittlere Kiste (Index 3, die 20). Die 50 ist größer, also kann sie nur rechts liegen; die linke Hälfte fällt weg. In den Kisten 4 bis 6 ist die mittlere die 100. Die 50 ist kleiner, also bleibt nur Kiste 4: die 50. Drei Kisten statt sieben. Das ist die binäre Suche.
Wenn 50 in der mittleren Kiste ist
Gib true zurück
Sonst wenn 50 < mittlere Kiste
Durchsuche die linke Hälfte
Sonst wenn 50 > mittlere Kiste
Durchsuche die rechte Hälfte
Wenn keine Kisten übrig sind
Gib false zurück
Wenn 50 in der mittleren Kiste ist
Gib true zurück
Sonst wenn 50 < mittlere Kiste
Durchsuche die linke Hälfte
Sonst wenn 50 > mittlere Kiste
Durchsuche die rechte Hälfte
Als Pseudocode:
Wenn keine Kisten übrig sind
Gib false zurück
Wenn 50 in der mittleren Kiste ist
Gib true zurück
Sonst wenn 50 < mittlere Kiste
Durchsuche die linke Hälfte
Sonst wenn 50 > mittlere Kiste
Durchsuche die rechte Hälfte
Die erste Zeile ist wichtig: Ohne sie würde der Algorithmus nie aufhören, wenn die 50 gar nicht da ist. Mit Array-Schreibweise werden aus den Hälften Bereiche von Indizes. Zwei Grenzen merken sich, welcher Bereich noch übrig ist: Am Anfang ist links 0 und rechts n − 1.
Solange links <= rechts
mitte = (links + rechts) / 2
Wenn 50 in kisten[mitte] ist
Gib true zurück
Sonst wenn 50 < kisten[mitte]
rechts = mitte - 1
Sonst
links = mitte + 1
Gib false zurück
„Keine Kisten übrig“ heißt jetzt: links ist größer als rechts. Bei einer geraden Zahl von Kisten gibt es zwei mittlere; (links + rechts) / 2 rundet als Ganzzahldivision ab und nimmt die linke.
Bei jeder geöffneten Kiste fällt die Hälfte der übrigen weg. Die binäre Suche öffnet auch die letzte übrige Kiste noch: Bei n Kisten sind es höchstens k Blicke, wenn 2^k größer als n ist. Bei 7 Kisten also höchstens 3, bei 8 schon 4, bei 15 höchstens 4. Das ist dasselbe Prinzip wie beim Zählen im Hörsaal.
Dieses Vorgehen heißt Teile und herrsche (Vorlesung 0): Das Problem wird in jedem Schritt kleiner, und auf dem kleineren Stück macht man dasselbe noch einmal. Wie man „mach dasselbe auf der Hälfte noch einmal“ direkt in C schreibt, sehen Sie im zweiten Teil (Rekursion).
Sie waren es nicht.
Die binäre Suche prüft das nie, sie vertraut Ihnen.
3 8 15 23 42 57 91 Gesucht: 15. Welche Zahlen sehen Sie nacheinander an?2 4 7 11 16 22 29 37 46 56 67 79 92 106 121 Gesucht: 40. Welche Zahlen, und woran merken Sie, dass die 40 fehlt?Übung: Binäre Suche von Hand
Wählen Sie die Stufe, die Sie schaffen; alle drei sind gleich viel wert. Ohne Laptop, auf Papier.
3 8 15 23 42 57 91 suchen Sie mit der binären Suche die 15. Welche Zahlen sehen Sie nacheinander an?2 4 7 11 16 22 29 37 46 56 67 79 92 106 121 (15 Zahlen) suchen Sie die 40. Welche Zahlen sehen Sie an, und woran merken Sie, dass die 40 fehlt?3 8 15 23 42 57 91 die 15 suchen: 23, 8, 152 4 7 11 16 22 29 37 46 56 67 79 92 106 121 die 40 suchen: 37, 79, 56, 46. Links von der 46 ist nichts mehr übrig: Die 40 fehlt.Stufe 1. 23, 8, 15. Die Mitte der 7 Zahlen ist die 23; 15 ist kleiner, also bleiben 3 8 15. Deren Mitte ist die 8; 15 ist größer, also bleibt die 15.
Stufe 2. 37, 79, 56, 46, dann ist kein Bereich mehr übrig. Die Mitte der 15 Zahlen ist die 37 (40 ist größer, rechts weiter: 46 … 121). Mitte 79 (kleiner, links: 46 56 67). Mitte 56 (kleiner, links: 46). 46 ist nicht 40, und links von der 46 ist nichts mehr: Die 40 kommt nicht vor.
Stufe 3. 10 bei 1000 Zahlen und 20 bei einer Million. Jeder Blick halbiert den Rest: Nach 10 Blicken ist von 1000 Zahlen nichts mehr übrig, weil 2¹⁰ = 1024 größer als 1000 ist. Bei einer Million: 2²⁰ = 1 048 576.
Die wichtigsten Klassen, von langsam nach schnell:
| Klasse | Name | Beispiel |
|---|---|---|
| O(n²) | quadratisch | strlen in der Bedingung der Schleife (oben gemessen) |
| O(n log n) | n log n | kommt im zweiten Teil (Merge Sort) |
| O(n) | linear | lineare Suche; die Schleife mit n = strlen(s) |
| O(log n) | logarithmisch | binäre Suche |
| O(1) | konstant | ein Element eines Arrays über seinen Index lesen |
Zwei ineinander geschachtelte Schleifen über n Elemente brauchen n · n Schritte, also O(n²). So eine Schleife steckt auch in strlen in der Bedingung: Die äußere ist Ihre for-Schleife, die innere zählt strlen. Beim Sortieren im zweiten Teil sehen Sie weitere.
O gibt eine Obergrenze an: So lange dauert es höchstens. Wir verwenden sie für den schlechtesten Fall (Worst Case). Die lineare Suche braucht im schlechtesten Fall n Schritte, die binäre Suche etwa log₂ n.
int numbers[] = {20, 500, 10, 5, 100, 1, 50};
int n = get_int("Zahl: ");
for (int i = 0; i < 7; i++)
{
if (numbers[i] == n)
{
printf("Gefunden\n");
}
else
{
printf("Nicht gefunden\n");
}
}
code search.c):search.c$ ./search
Zahl: 50
Nicht gefunden
Nicht gefunden
Nicht gefunden
Nicht gefunden
Nicht gefunden
Nicht gefunden
Gefunden
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int numbers[] = {20, 500, 10, 5, 100, 1, 50};
int n = get_int("Zahl: ");
for (int i = 0; i < 7; i++)
{
if (numbers[i] == n)
{
printf("Gefunden\n");
}
else
{
printf("Nicht gefunden\n");
}
}
}
int numbers[] = {20, 500, 10, 5, 100, 1, 50}; legt das Array an und füllt es gleich; die Länge (7) bestimmt der Compiler aus der Zahl der Werte.elsefor (int i = 0; i < 7; i++)
{
if (numbers[i] == n)
{
printf("Gefunden\n");
}
}
printf("Nicht gefunden\n");
$ ./search
Zahl: 50
Gefunden
Nicht gefunden
for (int i = 0; i < 7; i++)
{
if (numbers[i] == n)
{
printf("Gefunden\n");
}
}
printf("Nicht gefunden\n");
Gefunden und Nicht gefunden aus: Die Schleife läuft nach dem Fund weiter bis zum Ende, und danach kommt die Zeile mit Nicht gefunden in jedem Fall.for (int i = 0; i < 7; i++)
{
if (numbers[i] == n)
{
printf("Gefunden\n");
break;
}
}
printf("Nicht gefunden\n");
Eingabe 50: A nur Gefunden · B Gefunden und Nicht gefunden
B: break verlässt nur die Schleife, danach geht es darunter weiter.
Um eine Schleife vorzeitig zu verlassen, gibt es in C die Anweisung break. Sobald das Programm auf break trifft, springt es hinter das Ende der Schleife, egal wie oft sie noch laufen würde:
for (int i = 0; i < 7; i++)
{
if (numbers[i] == n)
{
printf("Gefunden\n");
break;
}
}
printf("Nicht gefunden\n");
Bei 50 erscheint trotzdem Gefunden und Nicht gefunden. break beendet nur die Schleife, nicht das Programm. Die Zeile hinter der Schleife läuft weiter.
return beendet mainfor (int i = 0; i < 7; i++)
{
if (numbers[i] == n)
{
printf("Gefunden\n");
return 0;
}
}
printf("Nicht gefunden\n");
return 1;
break verlässt die Schleife, return die Funktion, in main also das Programm.
Was wir eigentlich wollen: Sobald die Zahl gefunden ist, ist das ganze Programm fertig. Das erledigt return. In main beendet return 0; das Programm mit dem Exit-Code 0 (Erfolg), wie Sie es aus Vorlesung 2 kennen:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int numbers[] = {20, 500, 10, 5, 100, 1, 50};
int n = get_int("Zahl: ");
for (int i = 0; i < 7; i++)
{
if (numbers[i] == n)
{
printf("Gefunden\n");
return 0;
}
}
printf("Nicht gefunden\n");
return 1;
}
$ ./search
Zahl: 50
Gefunden
$ echo $?
0
$ ./search
Zahl: 7
Nicht gefunden
$ echo $?
1
Die Zeile mit Nicht gefunden erreicht das Programm jetzt nur, wenn die Schleife ganz durchgelaufen ist, ohne die Zahl zu finden. Dann endet es mit return 1. Für den Erfolg nimmt man die 0, weil es meist nur einen Erfolgsfall gibt, aber viele mögliche Fehler; die übrigen Zahlen bleiben für die verschiedenen Fehler.
Der Unterschied in einem Satz: break verlässt die Schleife, return verlässt die Funktion (in main also das Programm).
break mit Merkvariablebool gefunden = false;
for (int i = 0; i < 7; i++)
{
if (numbers[i] == n)
{
gefunden = true;
break;
}
}
if (gefunden)
...
break ist dann richtig, wenn nach der Schleife noch etwas passieren soll. Dann merkt man sich in einer Variablen, ob die Zahl gefunden wurde:
bool gefunden = false;
for (int i = 0; i < 7; i++)
{
if (numbers[i] == n)
{
gefunden = true;
break;
}
}
if (gefunden)
{
printf("Gefunden\n");
}
else
{
printf("Nicht gefunden\n");
}
int scheine[] = {20, 500, 10, 5, 100, 1, 50};
int summe = 0;
for (int i = 0; i < 7; i++)
{
if (scheine[i] < 10)
{
continue;
}
summe += scheine[i];
}
printf("%i\n", summe);
A 686 · B 680 · C 530
B: 680, denn die 5 und die 1 überspringt continue.
Neben break gibt es continue: Es überspringt nur den Rest dieses einen Durchlaufs und macht mit dem nächsten weiter. Das folgende Programm zählt die Scheine aus den Kisten zusammen, lässt aber das Kleingeld unter 10 aus:
#include <stdio.h>
int main(void)
{
int scheine[] = {20, 500, 10, 5, 100, 1, 50};
int summe = 0;
for (int i = 0; i < 7; i++)
{
if (scheine[i] < 10)
{
continue;
}
summe += scheine[i];
}
printf("%i\n", summe);
}
Es gibt 680 aus: 20 + 500 + 10 + 100 + 50. Bei der 5 und der 1 springt continue zum nächsten Durchlauf, die Zeile summe += scheine[i]; läuft für sie nicht.
break oder continueMit break statt continue käme 530 heraus (20 + 500 + 10): Bei der 5 endet die ganze Schleife.
Zusammengefasst:
| Anweisung | Was sie beendet |
|---|---|
continue |
den aktuellen Durchlauf der Schleife, weiter mit dem nächsten |
break |
die ganze Schleife, weiter hinter der Schleife |
return |
die ganze Funktion (in main: das Programm) |
continue und break machen eine Schleife oft kürzer, aber nicht immer leichter zu lesen. Häufig lässt sich dasselbe auch mit einem if ausdrücken (hier: if (scheine[i] >= 10)).
Hund?string strings[] = {"Schiff", "Auto", "Hund", "Katze", "Hut"};
// A
if (strings[i] == s)
// B
if (strcmp(strings[i], s))
// C
if (strcmp(strings[i], s) == 0)
C ist richtig. A findet nie etwas: == taugt für Strings nicht.
B findet alles: wahr, sobald die Wörter verschieden sind.
Was, wenn die Kisten Wörter enthalten? Dann ändert sich nur die Bedingung: Statt zwei Zahlen vergleicht das Programm zwei Strings.
Dafür gibt es die Funktion strcmp (string compare) aus string.h. Sie kam in Notes 2 schon vor (Abschnitt Stringlänge), hier noch einmal: strcmp geht beide Strings Zeichen für Zeichen durch und gibt eine Zahl zurück, kein true oder false.
strcmp("Hund", "Hund") // 0: gleich
strcmp("Hund", "Katze") // negativ: "Hund" kommt vorher
strcmp("Katze", "Hund") // positiv: "Katze" kommt später
Gleich heißt 0. Vorher und später richten sich nach den ASCII-Werten der Zeichen.
Welche dieser Bedingungen findet das Wort?
// A
if (strings[i] == s)
// B
if (strcmp(strings[i], s))
// C
if (strcmp(strings[i], s) == 0)
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
string strings[] = {"Schiff", "Auto", "Hund", "Katze", "Hut"};
string s = get_string("Wort: ");
for (int i = 0; i < 5; i++)
{
if (strcmp(strings[i], s) == 0)
{
printf("Gefunden\n");
return 0;
}
}
printf("Nicht gefunden\n");
return 1;
}
strcmp gibt 0 zurück, wenn beide Strings gleich sind.== vergleicht bei Strings, wo sie im Speicher stehen, nicht welche Zeichen darin stehen.Maus: Ohne == 0 ist die Bedingung wahr, sobald strcmp nicht 0 zurückgibt, also sobald die Wörter verschieden sind. Schon beim ersten Wort im Array, das nicht passt, meldet das Programm Gefunden. Der Compiler warnt bei A und B nicht.strcmp bei Gleichheit 0 zurück und nicht true? Weil es mehr kann: Das Vorzeichen sagt, welcher String zuerst kommt. Das ist nützlich zum Sortieren. Weil Großbuchstaben in ASCII vor den Kleinbuchstaben kommen, steht "Zebra" dabei vor "apfel".string s = get_string("s: "); // Hallo
string t = get_string("t: "); // Hallo
if (s == t)
{
printf("Gleich\n");
}
Gibt nichts aus: == vergleicht bei Strings nicht die Zeichen.
Warum, sehen wir in ein paar Wochen.
Warum findet A nie etwas? Ein kleineres Beispiel: Zweimal Hallo eingeben, und trotzdem ist s == t falsch.
string s = get_string("s: "); // Hallo
string t = get_string("t: "); // Hallo
if (s == t)
{
printf("Gleich\n");
}
== vergleicht bei Strings nicht die Zeichen, sondern wo die Strings im Speicher stehen. Was das genau heißt, kommt in ein paar Wochen, wenn es um den Speicher geht. Bis dahin: Strings vergleichen Sie immer mit strcmp.
strcmp#include <string.h>
strcmp("Hund", "Hund") // 0: gleich
strcmp("Hund", "Katze") // negativ: "Hund" kommt vorher
strcmp("Katze", "Hund") // positiv: "Katze" kommt später
Gleich heißt 0. Zeichen für Zeichen, nach ASCII.
Alles außer 0 ist wahr: Darum findet B alles.
string names[] = {"Office", "Dominik", "Bittle"};
string numbers[] = {"+49-951-863-2795",
"+49-951-863-2661",
"+49-951-863-2661"};
for (int i = 0; i < 3; i++)
{
if (strcmp(names[i], name) == 0)
{
printf("Gefunden: %s\n", numbers[i]);
return 0;
}
}
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
string names[] = {"Office", "Dominik", "Bittle"};
string numbers[] = {"+49-951-863-2795", "+49-951-863-2661", "+49-951-863-2661"};
string name = get_string("Name: ");
for (int i = 0; i < 3; i++)
{
if (strcmp(names[i], name) == 0)
{
printf("Gefunden: %s\n", numbers[i]);
return 0;
}
}
printf("Nicht gefunden\n");
return 1;
}
+ und -, eine führende 0 ginge bei einem int verloren, und rechnen will mit ihnen niemand.persontypedef struct
{
string name;
string number;
}
person;
person people[3];
people[0].name = "Office";
people[0].number = "+49-951-863-2795";
In C können Sie eigene Datentypen anlegen, die mehrere Werte zusammenfassen. Für das Telefonbuch ist das eine person mit einem Namen und einer Nummer:
typedef struct
{
string name;
string number;
}
person;
struct heißt: ein Datentyp, der aus mehreren Feldern (englisch members) besteht, hier name und number. typedef gibt ihm einen Namen, person. Diese Zeilen stehen oben in der Datei, vor main. Danach ist person ein Typ wie int oder string: Sie können Variablen und Arrays davon anlegen.
personstring name = get_string("Name: ");
for (int i = 0; i < 3; i++)
{
if (strcmp(people[i].name, name) == 0)
{
printf("Gefunden: %s\n", people[i].number);
return 0;
}
}
#include <cs50.h>
#include <stdio.h>
#include <string.h>
typedef struct
{
string name;
string number;
}
person;
int main(void)
{
person people[3];
people[0].name = "Office";
people[0].number = "+49-951-863-2795";
people[1].name = "Dominik";
people[1].number = "+49-951-863-2661";
people[2].name = "Bittle";
people[2].number = "+49-951-863-2661";
string name = get_string("Name: ");
for (int i = 0; i < 3; i++)
{
if (strcmp(people[i].name, name) == 0)
{
printf("Gefunden: %s\n", people[i].number);
return 0;
}
}
printf("Nicht gefunden\n");
return 1;
}
person people[3]; legt ein Array aus drei Personen an. Auf die Felder greifen Sie mit der Punktschreibweise zu: people[0].name ist der Name der Person an Stelle 0, people[0].number ihre Nummer.people sortiert, verschiebt immer ganze Personen, und die Nummer wandert mit.struct lässt sich leicht erweitern: Ein weiteres Feld (etwa eine E-Mail-Adresse) kommt in die Definition, der Rest des Programms bleibt, wie er ist.song?typedef struct
{
...
}
song;
typedef struct
{
string titel;
string kuenstler;
int jahr;
}
song;
Was gehört in einen Datentyp für Songs? Ein Titel, wer ihn singt, das Jahr:
typedef struct
{
string titel;
string kuenstler;
int jahr;
}
song;
Die Felder eines struct dürfen verschiedene Typen haben, hier zweimal string und einmal int.
playlist aus?Bohemian Rhapsody 1975 · Flowers 2023 · Blinding Lights 2019
for (int i = 0; i < 3; i++)
{
if (playlist[i].jahr > 2020)
{
printf("%s\n", playlist[i].titel);
}
}
A 1 · B 2 · C 3
A. Nur Flowers ist nach 2020 erschienen.
#include <cs50.h>
#include <stdio.h>
typedef struct
{
string titel;
string kuenstler;
int jahr;
}
song;
int main(void)
{
song playlist[3];
playlist[0].titel = "Bohemian Rhapsody";
playlist[0].kuenstler = "Queen";
playlist[0].jahr = 1975;
playlist[1].titel = "Flowers";
playlist[1].kuenstler = "Miley Cyrus";
playlist[1].jahr = 2023;
playlist[2].titel = "Blinding Lights";
playlist[2].kuenstler = "The Weeknd";
playlist[2].jahr = 2019;
for (int i = 0; i < 3; i++)
{
if (playlist[i].jahr > 2020)
{
printf("%s\n", playlist[i].titel);
}
}
}
Flowers: Nur dieser Song ist nach 2020 erschienen.In diesem Teil haben Sie algorithmisch gedacht und Ihren ersten eigenen Datentyp gebaut.
Übung 3 startet heute: Cäsar, Abgabe bis Montag, 16. November.
Übung 2 läuft: Scrabble und Lesbarkeit, Abgabe bis Montag, 9. November.
Shorts 3.1 (lineare Suche) und 3.2 (binäre Suche).
Sie haben gelernt:
strlen in der Bedingung einer Schleife bei jedem Durchlauf neu zählt und eine Schleife so von O(n) zu O(n²) macht;break verlassen, mit continue einen Durchlauf überspringen und mit return die ganze Funktion beenden;strcmp(…) == 0 verglichen werden;typedef struct eigene Datentypen anlegen und mit der Punktschreibweise auf ihre Felder zugreifen.Sortieren (Selection Sort, Bubble Sort, Merge Sort) und Rekursion folgen im zweiten Teil der Vorlesung.
Keine Taste und keine Aktion passt
pitchblack: on in the frontmatter opens that wayFor reference – the mouse, and keys that answer in one place