Analog zu Variablen: Vor der ersten Benutzung müssen Funktionen bekannt sein
Unterscheidung zwischen Deklaration und Definition
Deklaration macht Signatur bekannt
int sum(int a, int b);Definition spezifiziert die Anweisungen
→ Funktionsrumpf, als Code-Block {}
Deklaration und Definition können getrennt oder zusammen erfolgen
Platzverbrauch: Eine Zeile pro Deklaration ⇔ beliebig viele pro Definition
Vorteile einer Trennung
Für kleine Projekte (\(<\) 10000 Zeilen Code) ist die Geschwindigkeit nachrangig
Aber: Sehr wichtig bei großen Projekten mit mehreren Millionen Zeilen
#include-Direktivecircle_with_opengl.c oder circle_with_x11.ccircle.h ⇔ circle.cAber was ist jetzt dieses #include überhaupt?
#include-Direktive<> → „Suche im Systempfad nach der Datei ”"" → „Suche im an der aktuellen Stelle nach der Datei ”#define-Direktive legt Namen und Wert festPräprozessor ersetzt bloß
#include-Direktiven können gleichen Header mehrfach einfügen
→ Compiler bricht ab, da zwei Definitionen vorhanden sind
#include darauf achten müssen#pragma#pragma once (Nur C++)#pragma
#pragma nicht implementieren#pragma once wird aber von den meisten Compilern unterstützta.h und b.h bauen auf einander aufProblem: Gegenseitige Abhängigkeiten (Circular/Cyclic Dependencies)
Allgemein gilt: Sind ein starker Indikator für schlechte Software-Architektur
→ Gedanken über die Projektstruktur machen und restrukturieren
Nun wieder zurück zur Trennung von Quellcode.
externstatic→ Beginn mit lokalen Variablen
Deklaration außerhalb von Funktionen
Existieren während der gesamten Lebensdauer des Programms
Prinzipiell überall gültig und sichtbar, außer sie werden lokal überdeckt
#include <stdio.h>
int i = -10; // Global
int j; // Global
int main() {
printf("i = %d\n", i);
printf("j = %d\n", j);
return 0;
}
#include <stdio.h>
int i = 0;
int main() {
printf("(1) i = %d\n", i);
float i = 2.5;
printf("(2) i = %.1f\n", i);
{
char i = 'c';
printf("(3) i = %c\n", i);
}
++i;
printf("(4) i = %.1f\n", i);
return 0;
}
Variable im aktuellem Block überdeckt Variable aus übergeordnetem Block
Überdeckte Variablen existieren weiterhin, aber nicht sichtbar
Beachtet: Typ der Variable darf anders sein
extern„Wie teile ich eine Variable mit zwei (oder mehr) Source-Dateien?”
int foo = 42; hinschreiben
int-Variablen mit dem Namen fooint foo = 42; hinschreiben und darauf verweisen
externDatei a.c
int foo = 42;Datei b.c
extern int foo;Schlüsselwort extern sagt dem Compiler:
„Hey, es gibt hier irgendwo eine int-Variable namens foo”
Erst später im Übersetzungsprozess wird nach der Variablen gesucht
externexternstatic „bleiben” Funktionen in einer Source-Datei→ Compiler wird einen Fehler melden!
main()#include <stdio.h>
int counter() {
static int c = 0;
return ++c;
}
int main() {
for (int i = 0; i < 5; ++i) {
printf("%d ", counter());
}
}
→ Unnötige Komplexität und unübersichtliche
Vermeidet bitte globale Variablen.Nutzt Funktionsparameter.
extern dient dem Teilen von Variablen zw. Dateienstatic beschränkt Variablen/Funktionen auf eine Datei