Organisatorisches zur Übungsabgabe

Tutorium

Im Tutorium gibt es

Typische Fehler zur 1. Übung

Konstanten

Konstanten wie pi oder Zinsfüße sollen als solche gekennzeichnet sein.

Falsch:
float zinsfuss = 5.3;

Richtig (aber nicht optimal):
#define zinsfuss 5.3;

Optimal:
const float zinsfuss = 5.3;

Datentypen geeignet wählen

Beispiel (zu 1.):
Tage sind von Natur aus ganzzahlig (man kann nicht 3.5 Tage verzinsen lassen)

Falsch:
float tage;

Richtig:
int tage;
oder
unsigned int tage;

Bemerkung: Man kann zwar auch nicht -2 Tage verzinsen, dank kürzerer Schreibweise wird aber auf unsigned gern verzichtet.

Testläufe...

... sind nicht nur Schikane des Praktikums. Sie dienen u.a. dazu, die Funktionsweise des Programms zu überprüfen, und damit Fehlern auf die Spur zu kommen. Dabei ist es wichtig, Testergebnisse zu interpretieren. Oft macht es Sinn, für sich selbst mehr Tests als vorgegeben durchzuführen und Kopf- bzw. Überschlagsrechnungen zu machen.

Beispiel (zu 1.):
Zinsfuß 5.3%, Kapital 100 Euro, 360 Tage, Ergebnis (Zins): 0.053 Euro
Das entsprechende Programm muß einen (Skalierungs-)Fehler in der Berechnung des Zins haben, 5.30 Euro herauskommen muß (Kopfrechnung).

Beispiel (zu 2.):
Radius 1.732, Kleinste Höhe 3, Größte Höhe 5, Winkel 30°, Ergebnis für Schwerpunkthöhe: 5.84617
Das Programm muß einen Fehler in der Berechnung der Schwerpunkthöhe haben, da der Schwerpunkt nicht außerhalb des Zylinders liegen kann (Interpretation).

Vorsicht bei Berechnungen mit ganzen Zahlen, insbesondere bei Divisionen

Ganze Zahlenkonstanten wie 1, 4, -14 werden vom Compiler als int interpretiert. Folglich ergibt 1/4 den Wert 0, weil eine Integerdivision durchgeführt wird.

Richtig:
1./4,
1./4.,
1.0/4.0
etc.

Tip:
Sobald in einer Formel Gleitkommazahlen oder -variablen vorkommen, alle ganzen Zahlen mit Komma versehen (1. statt 1); reduziert die Fehleranfälligkeit.

Bei Divisionen generell aufpassen (was ist gewollt):

int a, b;
[...]
cout << a/b << endl;

Richtig, falls wirklich die ganzzahlige Division gewollt ist,
falsch, falls ein Bruch gewollt war (dann type-casting verwenden: z.B. (double)a/(double)b.

Winkelfunktionen...

... wie sin, cos, tan verlangen Winkelangaben in Radianten statt Grad!
Grad-in-Radianten-Umrechnung mit alpha*M_PI/180.0.

Rechenregeln

Die Auswertung von mathematischen Ausdrücken funktioniert wie beim Taschenrechner mit Punkt-vor-Strichrechnung von links nach rechts.

Beispiel: Bestimmung von
a
c = ----
2 b

Falsch:
c = a/2*b

Richtig:
c = a/(2*b)
oder
c = a/2/b

Redundante Berechnungen

In den Formeln für Volumen, Oberfläche und Schwerpunkthöhe in Beispiel 2 kommt die Berechnung von

vor. Wenigstens für einen der beiden Terme sollte man mit einer Hilfsvariable diese Mehrfachberechnung vermeiden. Siehe Musterlösung.

Unterschied zwischen pow(x, 2) und x*x

Fallbeispiel:

int n;
long long int n2;
[...]
n2 = pow(n, 2);

pow(n, 2) liefert einen Wert vom Typ double oder float zurück. Dieser wird dann in einen int konvertiert (Vorsicht: evtl. werden Stellen abgeschnitten).

Richtig:
n2 = n*n;

Dieser Fehler kam gehäuft in Beispiel 3 vor. Siehe dazu das Programm pow-test.cc und die entsprechenden Ausgaben dort.

Globale Variablen/Konstantenvereinbarungen...

... sind nicht erwünscht und in den Beispielen auch nicht notwendig.

Falsch:

const float zinsfuss = 5.3;
int tage;
float kapital, zins;

void main ()
{
[...]

Richtig:

void main ()
{
const float zinsfuss = 5.3;
int tage;
float kapital, zins;

[...]