C-Vorkurs, Tag 4, 14. April 2016

Inhalte heute

Projektstruktur für mehrere Dateien

Aufteilen eines Projekts

  • Manchmal ist es sinnvoll, große Projekte in mehrere Dateien aufzuteilen

    • Teile eines Projekts werden in mehreren Programmen benötigt

    • Teile bilden einen logischen Zusammenhang (Bibliothek)

  • Beispiel: Wir verwenden regelmäßig Funktionen / Konstanten zur Kreisberechnung (kreis_umfang, kreis_flaeche, pi)

  • Aufteilen unseres Programms in zwei Teile: programm.c und kreis.c

Aufteilen eines Projekts II

double pi = 3.141592653589793;
double flaeche(double radius) {
    return pi * radius * radius;
}
double umfang(double radius) {
    return pi * radius * 2;
}

#include <stdio.h>
int main() {
    const double rad = 42;
    printf("r=%f\U=%f\nA=%f\nPI=%f\n", rad,
        kreis_umfang(rad), kreis_flaeche(rad), pi);
    return 0;
}

Aufteilen eines Projekts III

  • Jetzt müssen wir beide Dateien kompilieren:

    gcc [..flags..] -o program program.c kreis.c

  • Funktioniert leider nicht :-(

  • Irgendwie müssen wir program.c mitteilen, dass die gesuchten Funktionen existieren

  • Erinnerung: Header-Dateien

Aufteilen eines Projekts IV

#ifndef KREIS_H_    // Doppeltes Einbinden des Codes
#define KREIS_H_    // verhindern. WICHTIG!

extern double pi;   // Variable pi existiert

double kreis_flaeche(double radius);
double kreis_umfang(double radius);

#endif   // #ifndef von oben beenden
  • In program.c und kreis.c noch #include "kreis.h" hinzufügen

    • Wichtig: "kreis.h" und nicht <kreis.h>

Dos and Don’ts

Allgemeines

Don’t:

  • Warnungen ignorieren

Do:

  • -Wall und -Wextra anschalten

Programmierstil

Don’t:

  • #define-Makros mit etwas außer A-Z, 0-9 und _

  • goto

  • Funktionen sehr oft rekursiv aufrufen (C ist nicht Haskell)

Do:

  • Rekursion als Iteration schreiben (ist auch schneller)

  • Quellcode einrücken in einheitlichem Stil

  • “Sprechende” Variablennamen in einheitlichem Stil

  • Sinnvolle Kommentare schreiben

if, while, …

Don’t:

  • if (a == b && func()) { ...

    • undefiniert, ob / wann func aufgerufen wird
  • if (text1 == text2) { ... um Strings zu vergleichen

    • siehe strncmp und strncasecmp
  • if (a = 10) { ...

    • Dies ist eine Zuweisung und kein Vergleich