Die automatische Pflanzenbewässerung
AFB I–IIDie Bio-AG möchte, dass die Tomatenpflanzen im Klassenzimmer auch in den Ferien Wasser bekommen. Ein Feuchtesensor im Topf misst die Bodenfeuchte in Prozent, eine Pumpe fördert pro Gießgang 250 ml aus einem Tank. Erfahrungsgemäß steigt die Bodenfeuchte pro Gießgang um 8 Prozentpunkte. Samira programmiert die Steuerung zunächst als Testprogramm am PC; der Sensorwert ist dazu fest eingetragen.
#include <stdio.h> int main(void) { int feuchte = 22; // Bodenfeuchte in Prozent (vom Sensor) int tank = 1000; // Wasser im Tank in ml if (feuchte < 20) { printf("Sofort giessen!\n"); } else if (feuchte < 40) { printf("Bald giessen.\n"); } else { printf("Alles gut.\n"); } while (feuchte < 40 && tank >= 250) { tank = tank - 250; // ein Giessgang feuchte = feuchte + 8; printf("Giessgang: %d %%, Tank %d ml\n", feuchte, tank); } return 0; }
Finn findet die else if-Kette zu lang und schlägt für die Meldung „Bald giessen.“ diese kürzere Bedingung vor:
if (20 <= feuchte < 40) { printf("Bald giessen.\n"); }
- Geben Sie an, welche Meldung der
if-Teil ausgibt, wenn der Sensor 34 %, 20 %, 40 % bzw. 5 % meldet. - Stellen Sie den Ablauf der
while-Schleife für den Startwert 22 % in einer Tracetabelle mit den Spaltenfeuchte,tank, Wert der Bedingung und Ausgabe dar. Notieren Sie außerdem, welche Teilbedingung die Schleife beendet. - Erläutern Sie, was Finns Bedingung in C tatsächlich prüft und warum sie für jeden Sensorwert wahr ist.
Hinweise
Hinweis zu Aufgabe a)
< und die Grenzwerte.Hinweis zu Aufgabe b)
&& ist nur wahr, wenn beide Teile wahr sind.„Darstellen“ heißt hier: den Ablauf in einer fachüblichen Form (Tracetabelle) vollständig wiedergeben.Hinweis zu Aufgabe c)
20 <= feuchte < 40 von links nach rechts aus, also wie (20 <= feuchte) < 40. Welchen Wert hat ein Vergleich in C?Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
| Sensorwert | Meldung |
|---|---|
| 34 % | Bald giessen. |
| 20 % | Bald giessen. (20 < 20 ist falsch, 20 < 40 wahr) |
| 40 % | Alles gut. (40 < 40 ist falsch) |
| 5 % | Sofort giessen! |
Mit gcc und den vier Werten getestet.
Erwartungshorizont zu Aufgabe b)
| Prüfung | feuchte | tank | Bedingung | Ausgabe |
|---|---|---|---|---|
| 1 | 22 | 1000 | 22 < 40 && 1000 ≥ 250 → wahr | Giessgang: 30 %, Tank 750 ml |
| 2 | 30 | 750 | 30 < 40 && 750 ≥ 250 → wahr | Giessgang: 38 %, Tank 500 ml |
| 3 | 38 | 500 | 38 < 40 && 500 ≥ 250 → wahr | Giessgang: 46 %, Tank 250 ml |
| 4 | 46 | 250 | 46 < 40 ist falsch → falsch | — (Schleife endet) |
Die Werte in den Spalten feuchte und tank sind die Werte zum Zeitpunkt der Prüfung. Die Schleife endet, weil die Teilbedingung feuchte < 40 falsch wird; im Tank wären noch 250 ml für einen weiteren Gang. Vor der Schleife erscheint außerdem „Bald giessen.“
Erwartungshorizont zu Aufgabe c)
Der erste Vergleich 20 <= feuchte liefert in C eine Zahl: 1 (wahr) oder 0 (falsch). Danach wird diese Zahl mit 40 verglichen: 1 < 40 und 0 < 40 sind beide wahr. Die Bedingung ist also immer erfüllt — bei 5 % ebenso wie bei 70 % erscheint „Bald giessen.“ (mit gcc getestet; -Wall warnt: „comparisons like X<=Y<=Z do not have their mathematical meaning“).
Richtig wäre if (feuchte >= 20 && feuchte < 40). Vollständig ist die Erläuterung mit der Auswertungsreihenfolge, dem Zahlenwert eines Vergleichs und einem Beispielwert.
Punkte und Level im Brettspiel
AFB II–IIIEmre und Paula programmieren ein Konsolen-Brettspiel. Landet die Spielfigur auf einem Feld, ändert sich der Punktestand: Gold bringt laut Spielregel 10 Punkte, Silber 5 Punkte, eine Falle kostet 20 Punkte, jedes andere Feld bringt 1 Punkt. Paula hat die Auswertung eines Feldes mit switch geschrieben; zum Testen ist das Feld fest eingetragen.
#include <stdio.h> int main(void) { char feld = 'G'; // G = Gold, S = Silber, F = Falle int punkte = 100; switch (feld) { case 'G': punkte += 10; case 'S': punkte += 5; break; case 'F': punkte -= 20; break; default: punkte += 1; } printf("Punkte: %d\n", punkte); return 0; }
Emre hat dieselbe Regel vorher als if-Kette notiert und sagt: „Paulas switch macht genau das Gleiche wie meine Kette, nur übersichtlicher.“
if (feld == 'G') { punkte += 10; } else if (feld == 'S') { punkte += 5; } else if (feld == 'F') { punkte -= 20; } else { punkte += 1; }
Außerdem soll das Spiel Level anzeigen. Man startet in Level 1. Für den Aufstieg in Level 2 braucht man 50 Punkte insgesamt; der Abstand zum jeweils nächsten Level verdoppelt sich jedes Mal: Level 3 ab 150 Punkten (50 + 100), Level 4 ab 350 Punkten (150 + 200) usw.
- Bestimmen Sie den Wert von
punktenach Paulasswitch, wennfeldden Wert'G','S','F'bzw.'X'hat. - Überprüfen Sie Emres Aussage und korrigieren Sie gegebenenfalls Paulas Code so, dass er der Spielregel entspricht.
- Entwerfen Sie ein vollständiges C-Programm, das zu einem Punktestand das erreichte Level und die fehlenden Punkte bis zum nächsten Level ausgibt, z. B. „Level 5, noch 550 Punkte bis Level 6“ für 1000 Punkte. Ein negativer Punktestand soll als ungültig gemeldet werden. Begründen Sie die Wahl Ihrer Schleife kurz.
Hinweise
Hinweis zu Aufgabe a)
case ist nur eine Sprungmarke. Was passiert nach der Anweisung eines case, wenn kein break folgt?Hinweis zu Aufgabe b)
switch mit dem von Emres Kette. Eine einzige Abweichung genügt, um die Aussage zu entkräften.Hinweis zu Aufgabe c)
Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
| feld | punkte | Begründung |
|---|---|---|
| 'G' | 115 | Einsprung bei case 'G': +10, kein break, also weiter mit +5 (Durchfallen), dann break |
| 'S' | 105 | +5, dann break |
| 'F' | 80 | −20, dann break |
| 'X' | 101 | kein passender case → default: +1 |
Mit gcc für alle vier Werte getestet.
Erwartungshorizont zu Aufgabe b)
Die Aussage ist falsch. Für 'S', 'F' und 'X' stimmen beide Versionen überein (105, 80, 101). Für 'G' liefert Emres Kette 110, Paulas switch aber 115, weil nach case 'G' das break fehlt und die Ausführung in case 'S' weiterläuft. Die Kette entspricht der Spielregel, der switch nicht.
Korrektur: hinter punkte += 10; ein break; ergänzen (sinnvoll auch nach default). Danach liefert der switch 110, 105, 80 und 101 — wie die Kette.
Erwartungshorizont zu Aufgabe c)
#include <stdio.h> int main(void) { int punkte = 1000; // aktueller Punktestand (zum Testen fest) int level = 1; int schritt = 50; // Punkte, die für den nächsten Aufstieg dazukommen müssen int schwelle = 50; // Gesamtpunkte, ab denen das nächste Level erreicht ist if (punkte < 0) { printf("Ungueltiger Punktestand\n"); } else { while (punkte >= schwelle) { level++; schritt = schritt * 2; schwelle = schwelle + schritt; } printf("Level %d, noch %d Punkte bis Level %d\n", level, schwelle - punkte, level + 1); } return 0; }
| punkte | Ausgabe |
|---|---|
| −5 | Ungueltiger Punktestand |
| 0 | Level 1, noch 50 Punkte bis Level 2 |
| 49 | Level 1, noch 1 Punkte bis Level 2 |
| 50 | Level 2, noch 100 Punkte bis Level 3 |
| 150 | Level 3, noch 200 Punkte bis Level 4 |
| 1000 | Level 5, noch 550 Punkte bis Level 6 |
Schleifenwahl: Die Anzahl der Aufstiege steht vorher nicht fest, sie hängt vom Punktestand ab — deshalb eine while-Schleife mit der Bedingung „Punkte reichen für die nächste Schwelle“. Eine do … while-Schleife wäre falsch, weil sie mindestens einmal aufsteigen würde (0 Punkte ergäben Level 2). Gleichwertig sind Lösungen, die die Schwelle anders berechnen, solange die Testfälle stimmen.
