Immer wieder werden die gleichen Fehler gemacht... Diese Liste enthält die zwölf am häufigsten vorkommenden Fehler in der C-Programmierung und soll dabei helfen, selbige zu vermeiden.
Die Liste ist eine Übersetzung und Erweiterung der englischen Originalversion von Jeppe Cramon.
if (number = 9) { /* falsch */ number = 0; }Diese Sequenz ist syntaktisch korrekt, compiliert fehlerfrei, wird jedoch bei der Abarbeitung nicht das gewünschte tun. Anstatt der Variablen number den Wert 0 zuzuweisen, falls diese gleich 9 ist, wird number immer auf 0 gesetzt, da die Zuweisung number = 9 immer den logischen Wert true zurückliefert!
if (9 == number) { /* richtig */ number = 0; }Wird hier statt == aus Versehen = geschrieben, so wird schon der Compiler eine Fehlermeldung ausgeben.
while (ch = getchar() != EOF) /* falsch */Dies wird der Variablen ch den Wert 1 für TRUE zuweisen bis getchar() EOF zurückliefert. Dann erhält ch den Wert 0 für FALSE.
while ((ch = getchar()) != EOF) /* richtig */
int a[10];definiert zehn Feldelemente a[0], a[1], ..., a[9]. Ein Versuch, auf a[10] zuzugreifen, wird weder vom Compiler noch vom Laufzeitsystem bemerkt:
for (i=0; i <= 10; i++) /* falsch! Der höchste Index ist 9 */ a[i] = i;Dieses Beispiel wird zur Laufzeit der Variablen a[10] den Wert 10 zuweisen. Da es die Variable a[10] jedoch nicht gibt, wird unter Umständen eine andere Variable überschrieben.
x = getValue; /* falsch */falsch.
x = getValue(); /* richtig */
void convert(int *px);deklariert. Da der Parameter px ein Pointer auf eine Integer Variable ist, muß auch der Funktionsaufruf mit einem Pointer als Parameter erfolgen. Also zum Beispiel:
int result; convert(&result);Ein typischer Fehler ist, daß der Adreßoperator & hier vergessen wird.
double a; a = getdouble(); /* falsch */Hier wird a ein int anstatt des erwarteten double zugewiesen, da der Compiler annimmt, daß getdouble() ein int zurückliefert. Um dies zu korrigieren, muß die Funktion zunächst deklariert werden (dies wird auch als Prototype bezeichnet):
double getdouble(); double a; a = getdouble(); /* richtig */
switch (weekday) { case MONDAY : printf("Start a new week"); case TUESDAY: /* no break here */ case FRIDAY : workday++; break; default: weekday++; }Ist weekday gleich MONDAY, so wird ebenfalls der Code für TUESDAY und FRIDAY ausgeführt, da nach MONDAY und TUESDAY kein break steht. Ist dieses Verhalten vom Programmierer beabsichtigt, so sollte es wie im Beispiel kommentiert werden.
a[n] = n++;Ist equivalent entweder zu:
a[n] = n; n = n + 1;oder zu:
a[n + 1] = n; n = n + 1;Welcher der beiden Fälle eintritt, hängt vom Compiler ab.
char a; a = 228; /* iso code for the german a-umlaut */ printf( "%d\n", a); /* implicit conversion to int */Es wird entweder -28 oder 228 ausgegeben. Beim GNU Compiler gcc läßt sich dieses Verhalten durch Verwenden der Kommandozeilenschalter -funsigned-char oder -fsigned-char steuern.
char line[80]; *lp = line; ch = *lp++; /* the same as *(lp++) */In diesem Beispiel wird ch das Zeichen zugewiesen, auf welches lp zeigt. Anschließend wird lp inkrementiert. Verwendet man jedoch
ch = (*lp)++;so wird ch ebenfalls das Zeichen zugewiesen, auf welches lp zeigt. Anschließend wird jedoch nicht lp, sondern das Zeichen, auf welches lp zeigt, inkrementiert!