Der Sparplan
AFB I–IIJonas spart für Kopfhörer, die 60 € kosten. Er bekommt jede Woche 7 € Taschengeld und legt alles zur Seite. Seine Schwester hat ihm dafür ein kleines C#-Konsolenprogramm geschrieben:
using System;
class Sparplan
{
static void Main()
{
int wochengeld = 7;
int ziel = 60;
int erspart = 0;
int wochen = 0;
while (erspart < ziel)
{
erspart = erspart + wochengeld;
wochen++;
}
Console.WriteLine("Ziel nach " + wochen + " Wochen erreicht.");
Console.WriteLine("Erspart: " + erspart + " Euro");
}
}- Gib die beiden Zeilen an, die das Programm in der Konsole ausgibt.
- Beschreibe, welche Schritte der Quelltext durchläuft, bis er auf dem Computer ausgeführt wird. Verwende die Begriffe CIL, .NET und JIT-Compiler.
- Jonas ergänzt vor der Schleife die Zeile
erspart = 2.5;. Erkläre, warum das Programm dann überhaupt nicht startet — und nicht erst in dieser Zeile abbricht.
Hinweise
Hinweis zu Aufgabe a)
erspart < ziel zum ersten Mal falsch?Hinweis zu Aufgabe b)
Hinweis zu Aufgabe c)
erspart? Wer prüft Typen in C#, und wann?Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
erspart: 7, 14, 21, 28, 35, 42, 49, 56, 63. Nach 8 Wochen sind es 56 € < 60 €, erst nach der 9. Woche ist die Bedingung falsch. Ausgabe:
Ziel nach 9 Wochen erreicht.Erspart: 63 Euro
Erwartungshorizont zu Aufgabe b)
Der C#-Compiler prüft den Quelltext (Syntax, Typen) und übersetzt ihn in die Zwischensprache CIL, die in einer Programmdatei gespeichert wird. Beim Start lädt die .NET-Laufzeitumgebung die CIL; ein JIT-Compiler übersetzt die Methoden während des Laufs in Maschinencode für den jeweiligen Prozessor, der ihn dann ausführt.
Erwartungshorizont zu Aufgabe c)
erspart ist als int deklariert, 2.5 ist aber eine Kommazahl (double). C# ist statisch typisiert: Der Compiler prüft alle Typen schon vor dem Start und meldet einen Fehler („double kann nicht implizit in int umgewandelt werden“). Weil ohne fehlerfreie Übersetzung keine CIL entsteht, gibt es gar kein Programm, das starten könnte — anders als bei einem Interpreter wie Python, der erst beim Erreichen der Zeile abbricht.
Der platzende Ballon
AFB II–IIIMira programmiert für den Tag der offenen Tür ein Geschicklichkeitsspiel in Unity. Ein Ballon soll genau 10 Sekunden nach Spielbeginn platzen (Destroy(gameObject) entfernt ihn aus dem Spiel). Auf ihrem Laptop läuft das Spiel mit 60 fps, und dort klappt alles. Ihr Skript:
using UnityEngine;
public class Ballon : MonoBehaviour
{
float zeit;
int frames;
void Start()
{
zeit = 0f;
frames = 0;
Debug.Log("Ballon startet");
}
void Update()
{
frames++;
zeit += Time.deltaTime;
if (frames >= 600)
{
Destroy(gameObject);
}
}
}- Erläutere mithilfe der Abbildung, wie oft die Meldung „Ballon startet“ erscheint und wie oft
Update()in den ersten 10 Sekunden auf Miras Laptop aufgerufen wird. - Ermittle, nach wie vielen Sekunden der Ballon auf einem Tablet mit 30 fps und auf einem Gaming-PC mit 120 fps platzt.
- Verändere das Skript so, dass der Ballon auf jedem Gerät nach 10 Sekunden platzt. Gib die geänderten Zeilen an.
- Ihr Mitschüler meint: „Einfacher: Stell die Bildrate fest auf 60 fps ein, dann stimmt die Zählung mit
framesimmer.“ Beurteile diesen Vorschlag.
Hinweise
Hinweis zu Aufgabe a)
Hinweis zu Aufgabe b)
Hinweis zu Aufgabe c)
Hinweis zu Aufgabe d)
Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
„Ballon startet“ steht in Start(), das Unity genau einmal vor dem ersten Frame aufruft — die Meldung erscheint also einmal. Update() wird in jedem Frame aufgerufen: bei 60 fps in 10 s etwa 60 · 10 = 600-mal. Deshalb platzt der Ballon auf Miras Laptop tatsächlich nach 10 s.
Erwartungshorizont zu Aufgabe b)
Der Ballon platzt immer nach 600 Frames. Tablet: 600 : 30 = 20 s. Gaming-PC: 600 : 120 = 5 s. Die Wartezeit hängt also von der Bildrate ab — auf dem schnellen PC platzt er doppelt so früh, auf dem Tablet doppelt so spät.
Erwartungshorizont zu Aufgabe c)
Statt der Frames die vergangene Zeit prüfen, die ohnehin in zeit aufsummiert wird:
if (zeit >= 10f){ Destroy(gameObject); }
Die Zeilen mit frames können entfallen. Weil Time.deltaTime die echte Dauer jedes Frames enthält, ergibt die Summe nach 10 s immer etwa 10 — egal wie viele Frames es waren.
Erwartungshorizont zu Aufgabe d)
Der Vorschlag löst das Problem nur scheinbar: Eine feste Bildrate ist nur eine Obergrenze. Schafft ein schwaches Gerät keine 60 fps oder ruckelt das Spiel kurz, laufen weniger Frames und der Ballon platzt zu spät. Außerdem verschenkt man auf schnellen Geräten flüssigere Bilder. Die Lösung mit Time.deltaTime ist robuster und genauso einfach — sie ist deshalb vorzuziehen. (Vollständig ist eine Antwort, die mindestens ein Gegenargument nennt und zu einem begründeten Urteil kommt.)
