Variablen vertiefend II
Du möchtest wissen, was es mit den Speicherklassen in C auf sich hat? Hier erklären wir sie dir genauer.
Inhaltsübersicht
Was sind Speicherklassen und welche verschiedenen Arten gibt es?
Variablen können einer von vier verschiedenen Speicherklassen angehören. Diese legen fest, wie Variablen beim Programmablauf behandelt und wo sie gespeichert werden. Die beiden Typen register oder auto werden nur vorübergehend bzw. bis zum Ende des Gültigkeitsbereiches der Variable gespeichert. Variablen vom Typ static oder extern behalten hingegen ihre zugewiesenen Werte.
Aber das ist noch nicht alles. Deswegen schauen wir uns die verschiedenen Varianten jetzt noch einmal genauer an.
C auto und register C
Variablen vom Typ auto sind nichts anderes als lokale Variablen. Deswegen wird auto auch nur selten explizit vorne angehängt. Compiler betrachten nämlich alle Variablen standardmäßig als „auto“-Variablen. Bei „register-Variablen“ ist das allerdings etwas anders. Dem Namen entsprechend werden diese Variablen nämlich nicht im RAM, sondern in einem Register deines Prozessors abgelegt. Durch die Ablage dieser Variablen im Register kann dein Programm viel schneller auf diese zugreifen. Das kann vor allem in Schleifen extrem nützlich sein.
Und warum legen wir nicht alle Variablen in Registern ab, wenn der Zugriff dann so viel schneller erfolgt? Das hat mehrere Gründe:
Erst einmal wird die Speicherklasse register nur für Variablen vom Typ int oder char erlaubt. Das heißt, Variablen vom Typ double oder float und auch deine Arrays können auf diese Weise nicht abgespeichert werden. Ebenso kannst du keine globalen Variablen auf diese Weise ablegen. Wenn dein Programm nur lokale int und char-Variablen enthält, kann es trotzdem vorkommen, dass du deine Variablen nicht auf diese Weise ablegen kannst. Die Anzahl der Register deines Prozessors ist nämlich von dessen Modell abhängig. Dementsprechend hast du nicht auf allen Rechnern die gleiche Anzahl an Registern zur Verfügung. Aber keine Angst – selbst wenn du eine Variable als register definierst und kein Register frei ist, läuft dein Programm fehlerfrei, denn der Compiler erkennt das und verwendet die Variable stattdessen wie eine normale Variable der Speicherklasse auto.
Nun hast du erfolgreich eine Variable als register deklariert und möchtest ihr einen Wert zuweisen. Dabei musst du noch einen letzten Punkt beachten. Da Variablen dieser Speicherklasse nicht im RAM liegen und damit keine Speicheradresse aufweisen, kannst du nicht einfach mit dem Adressoperator &variable_name arbeiten.
C extern
Im Vergleich dazu sind „extern-Variablen“ recht einfach zu handhaben. Wenn eine Variable auf diese Art abgelegt wird, macht es nichts aus, ob dein Programm aus mehreren Quellcode-Dateien besteht, oder nur aus einer. Deine Variable gilt in allen Teilen. Damit das reibungslos funktioniert, wird die Variable in einer Datei definiert und in den anderen jeweils nur auf diese Weise erwähnt: extern variable_name.
Allerdings würden wir beim Kompilieren eines Programms, das diese Variable enthält, dennoch einen Fehler erhalten. Das liegt daran, dass unser Variablenname mehr als sechs Zeichen aufweist. Reduzieren wir ihn auf die richtige Länge, verschwindet auch der Fehler. Das tolle an diesen Variablen ist, dass sie ‚case insensitive‚ sind, d.h, dass sie immer angesprochen werden, selbst, wenn du dich bei der Groß- und Kleinschreibung mal vertust.
C static
Auf geht’s zur letzten Speicherklasse: Den „static-Variablen“. Genau wie „extern-Variablen“ behalten diese ihren Wert zwischen Funktionsaufrufen. Allerdings sind sie, im Gegensatz zu globalen Variablen, praktisch immer mit anderen Programmteilen kompatibel.
Die Ursache ist, dass sie wie lokale Variablen in Funktionen definiert werden und nicht außerhalb. Es gibt außerdem eine weitere Besonderheit bei static. Es kann auch als Funktionstyp verwendet werden. Ist das der Fall, ist die betreffende Funktion nur noch für andere Funktionen in derselben Quellcode-Datei aufrufbar.
Stack-Overflow C
Damit haben wir alle Speicherklassen durch. Allerdings musst du auch bei lokalen Variablen auf deinen verwendeten Speicherplatz achten. Zwar brauchen sie weniger Speicher als globale Variablen, jedoch kann es sein, dass du von ihnen einmal so viele in einer Funktion brauchst, dass dieser Speicher ausgereizt wird. Bei diesem Szenario spricht man vom sogenannten „Stack-Overflow“. Ist das vorher bekannt, kann dieser Speicherüberlauf noch während der Übersetzung durch das Erweitern dieses Speichers verhindert werden. Die genaue Funktionsweise dieser Option ist allerdings Compiler abhängig und deswegen für jeden unterschiedlich.