Die Anzeige für den Info-Tag
AFB I–IILena aus der Robotik-AG soll für den Tag der offenen Tür eine kleine Begrüßungsanzeige programmieren, die auf einem Bildschirm im Flur läuft. Sie hat bisher nur in Python programmiert und schreibt nun ihr erstes C-Programm. Die Datei heißt infotag.c.
#include <stdio.h> /* Anzeige für den Tag der offenen Tür */ int main(void) { printf("Willkommen im Informatikraum!\n"); printf("Raum 204: Robotik-AG\n"); // Raum und AG printf("Beginn: 10 Uhr\n"); return 0; }
Im Terminal tippt sie gcc -Wall infotag.c -o infotag und danach ./infotag. Am Vormittag erfährt sie, dass die AG schon um 9 Uhr beginnt. Sie ändert im Editor die Zahl 10 in 9, speichert die Datei und startet sofort wieder mit ./infotag — auf dem Bildschirm steht aber weiterhin „Beginn: 10 Uhr“.
- Geben Sie für die Zeile
#include <stdio.h>, den Kommentar, die Zeileint main(void) {und die Anweisungreturn 0;jeweils an, wozu sie im Programm dient. - Beschreiben Sie, was nacheinander passiert, wenn Lena
gcc -Wall infotag.c -o infotageingibt. Gehen Sie dabei auf die drei Stationen der Übersetzung und auf die Bedeutung von-Wallund-o infotagein. - Erklären Sie, warum nach der Änderung weiterhin „Beginn: 10 Uhr“ erscheint, und geben Sie die Befehle in der richtigen Reihenfolge wieder, mit denen Lena die neue Uhrzeit anzeigen kann.
Hinweise
Hinweis zu Aufgabe a)
Hinweis zu Aufgabe b)
Hinweis zu Aufgabe c)
./infotag — mit dem Quelltext oder mit einer anderen Datei? Wann wurde diese Datei zuletzt erzeugt? Denken Sie an den Unterschied zu Python.Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
#include <stdio.h>: bindet die Bibliothek für Ein- und Ausgabe ein; ohne sie kennt der Compiler printf nicht.
Kommentar /* … */ bzw. // …: Erklärung für Menschen, wird beim Übersetzen ignoriert.
int main(void) {: Beginn der Funktion main; hier startet jedes C-Programm. Die geschweifte Klammer öffnet den Block mit den Anweisungen.
return 0;: beendet main und meldet dem Betriebssystem „Programm fehlerfrei beendet“.
Erwartungshorizont zu Aufgabe b)
- Präprozessor: führt die
#-Zeilen aus, fügt also den Inhalt vonstdio.hin den Quelltext ein; Kommentare werden entfernt. - Compiler: prüft die Syntax (Semikolons, Klammern, bekannte Funktionen) und übersetzt den Quelltext in Maschinencode (Objektcode).
- Linker: fügt fertige Bibliotheksfunktionen wie
printfhinzu und erzeugt die ausführbare Datei. -Wallschaltet zusätzliche Warnungen ein (verdächtige Stellen, die noch kein Fehler sind);-o infotaglegt den Namen der fertigen Datei fest:infotag.
Bei diesem fehlerfreien Programm erscheint keine Meldung; im Ordner liegt danach die ausführbare Datei infotag.
Erwartungshorizont zu Aufgabe c)
./infotag startet die ausführbare Datei, die beim letzten Übersetzen entstanden ist. Das Speichern ändert nur den Quelltext infotag.c; die ausführbare Datei enthält noch den alten Maschinencode mit „10 Uhr“. Anders als in Python wird der Quelltext beim Starten nicht neu gelesen.
$ gcc -Wall infotag.c -o infotag $ ./infotag Willkommen im Informatikraum! Raum 204: Robotik-AG Beginn: 9 Uhr
Vollständig ist die Antwort mit dem Unterschied Quelltext / ausführbare Datei und dem Hinweis, dass nach jeder Änderung neu übersetzt werden muss.
Fehlersuche in der Schulbibliothek
AFB II–IIITim soll für den Bildschirm am Eingang der Schulbibliothek die Öffnungszeiten ausgeben. Er schreibt schnell die Datei oeffnung.c und übersetzt sie.
#include <stdio.h> int main(void) { printf("Schulbibliothek - Oeffnungszeiten\n"); printf("Mo bis Do: 8 bis 15 Uhr\n"); prinft("Fr: 8 bis 13 Uhr\n"); return 0;
$ gcc -Wall oeffnung.c -o oeffnung
oeffnung.c: In function 'main':
oeffnung.c:6:5: warning: implicit declaration of function 'prinft'; did you mean 'printf'? [-Wimplicit-function-declaration]
6 | prinft("Fr: 8 bis 13 Uhr\n");
| ^~~~~~
| printf
oeffnung.c:7:5: error: expected declaration or statement at end of input
7 | return 0;
| ^~~~~~Tim sieht „end of input“, ergänzt am Ende eine schließende Klammer } und übersetzt erneut:
$ gcc -Wall oeffnung.c -o oeffnung
oeffnung.c: In function 'main':
oeffnung.c:6:5: warning: implicit declaration of function 'prinft'; did you mean 'printf'? [-Wimplicit-function-declaration]
6 | prinft("Fr: 8 bis 13 Uhr\n");
| ^~~~~~
| printf
/usr/bin/ld: /tmp/ccjLrG9p.o: in function `main':
oeffnung.c:(.text+0x36): undefined reference to `prinft'
collect2: error: ld returned 1 exit statusZum Vergleich hat Tim dasselbe Programm vorher in Python geschrieben, mit demselben Tippfehler:
print("Schulbibliothek - Oeffnungszeiten") print("Mo bis Do: 8 bis 15 Uhr") prinft("Fr: 8 bis 13 Uhr")
$ python3 oeffnung.py
Schulbibliothek - Oeffnungszeiten
Mo bis Do: 8 bis 15 Uhr
Traceback (most recent call last):
File "oeffnung.py", line 3, in <module>
prinft("Fr: 8 bis 13 Uhr")
NameError: name 'prinft' is not defined. Did you mean: 'print'?Tim meint: „Warnungen sind egal, wichtig sind nur die Errors. Ich lasse -Wall in Zukunft weg, dann ist die Ausgabe übersichtlicher.“
- Analysieren Sie die Meldungen beider Übersetzungsversuche: Stellen Sie zu jeder Meldung fest, in welcher Zeile sie entsteht, was ihre Ursache ist und welche Station der Übersetzung (Compiler oder Linker) sie ausgibt, und korrigieren Sie das Programm vollständig.
- Vergleichen Sie das Verhalten von C und Python bei Tims Tippfehler. Gehen Sie darauf ein, wann der Fehler jeweils bemerkt wird und was die Nutzerin bzw. der Nutzer davon zu sehen bekommt.
- Beurteilen Sie Tims Vorschlag, auf Warnungen und auf
-Wallzu verzichten.
Hinweise
Hinweis zu Aufgabe a)
6:5 bedeuten Zeile 6, Spalte 5. Meldungen, die mit /usr/bin/ld beginnen, stammen von einem anderen Programm als die übrigen. Warum kommt der zweite Fehler erst beim zweiten Versuch ans Licht?Hinweis zu Aufgabe b)
Hinweis zu Aufgabe c)
Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
| Versuch | Meldung | Zeile | Ursache | Station |
|---|---|---|---|---|
| 1 | warning: implicit declaration of function prinft | 6 | Tippfehler: prinft ist keine bekannte Funktion (gemeint: printf) | Compiler (nur Warnung) |
| 1 | error: expected declaration or statement at end of input | 7 | Die schließende Klammer } von main fehlt; die Datei endet mitten im Block. | Compiler |
| 2 | warning: implicit declaration … prinft | 6 | wie oben, weiterhin nicht behoben | Compiler (nur Warnung) |
| 2 | undefined reference to prinft / ld returned 1 | 6 | Der Linker findet keine Funktion namens prinft in den Bibliotheken. | Linker (ld) |
Beim ersten Versuch bricht der Compiler wegen der fehlenden Klammer ab, der Linker läuft gar nicht erst. Erst als der Compiler fehlerfrei durchkommt, kann der Linker feststellen, dass es prinft nicht gibt. Die Zeilenangabe 7 zeigt auf die letzte vorhandene Zeile — die Klammer fehlt danach.
#include <stdio.h> int main(void) { printf("Schulbibliothek - Oeffnungszeiten\n"); printf("Mo bis Do: 8 bis 15 Uhr\n"); printf("Fr: 8 bis 13 Uhr\n"); // Tippfehler prinft behoben return 0; } // schließende Klammer ergänzt
$ gcc -Wall oeffnung.c -o oeffnung $ ./oeffnung Schulbibliothek - Oeffnungszeiten Mo bis Do: 8 bis 15 Uhr Fr: 8 bis 13 Uhr
Erwartungshorizont zu Aufgabe b)
| Kriterium | C (Compiler) | Python (Interpreter) |
|---|---|---|
| Zeitpunkt der Prüfung | vor dem Start, das ganze Programm auf einmal | erst während des Laufs, Zeile für Zeile |
| Ausgabe trotz Fehler | keine — es entsteht gar kein Programm | Zeilen 1 und 2 erscheinen, dann Abbruch mit NameError |
| Wer sieht den Fehler? | nur Tim beim Übersetzen | im schlimmsten Fall erst die Person am Bildschirm, wenn die Zeile ausgeführt wird |
Gemeinsam ist beiden: Der Tippfehler wird erkannt und mit einem Verbesserungsvorschlag gemeldet („did you mean“). Vorteil C: Fehler in selten ausgeführten Zeilen fallen schon vor der Auslieferung auf. Vorteil Python: Man kann ein halb fertiges Programm schon ausprobieren.
Erwartungshorizont zu Aufgabe c)
Der Vorschlag ist abzulehnen. Gerade in diesem Beispiel hat die Warnung (implicit declaration, „did you mean printf?“) den späteren Linker-Fehler schon im ersten Versuch genau benannt — mit Beachtung der Warnung hätte Tim beide Fehler in einem Durchgang behoben. Warnungen stehen für Stellen, die zwar übersetzt werden, aber sehr wahrscheinlich falsch sind; ein Programm mit Warnungen kann laufen und trotzdem falsche Ergebnisse liefern oder abstürzen. -Wall kostet nichts und findet solche Stellen früh.
Berechtigt ist nur der Wunsch nach Übersicht: Die Lösung ist, Meldungen von oben nach unten abzuarbeiten, nicht, sie abzuschalten. Vollständig ist die Antwort mit einem klaren Urteil, dem Bezug auf Tims Beispiel und mindestens einem allgemeinen Argument.
