====== Scopes ====== Als Scope bezeichnet man den Bereich innerhalb zweier geschweifter Klammern. Man spricht auch von Anweisungsblöcken. ===== Abbau von Variablen am Ende von Scopes ===== Allerdings beschreiben Scopes nicht nur eine Reihe von Anweisungen, wie die Definition von Variablen, sondern auch implizit (also ohne dass der Programmierer es hinschreiben muss) werden am Ende eines Scopes auch alle definierten Variablen wieder entfernt. Daher lässt sich folgendes Programm nicht kompilieren. #include #include int global = 1234; int main( void ) { int local = 4; if( local == 4 ) { // Neuer Scope int i = 1; } // Ende des Scopes, alle lokalen Variablen des Scopes werden abgebaut. else { // Neuer Scope int i = 0; } // Ende des Scopes, alle lokalen Variablen des Scopes werden abgebaut. printf( "i hat den Wert: %d\n" i ); return EXIT_SUCCESS; } In diesem Programm gibt es zwei voneinander unabhängige Variablen i, die jeweils am Ende ihres Scopes wieder abgebaut werden, also zum Zeitpunkt, an dem i mit printf ausgegeben werden soll, gar nicht mehr existieren. Um derartiges zu schreiben, muss sich die Variable i in einem Scope befinden, der noch nicht abgebaut wurde, wenn i ausgegeben wird: #include #include int global = 1234; int main( void ) { int local = 4; int i; if( local == 4 ) { // Neuer Scope i = 1; } // Ende des Scopes, alle lokalen Variablen des Scopes werden abgebaut. else { // Neuer Scope i = 0; } // Ende des Scopes, alle lokalen Variablen des Scopes werden abgebaut. printf( "i hat den Wert: %d\n" i ); return EXIT_SUCCESS; } ===== Verdecken von lokalen Variablen ===== Bei lokalen Variablen glauben viele, dass die Variable nur innerhalb der Funktion sichtbar wäre. Ausschlaggebend ist allerdings der Anweisungsblock, also der Bereich zwischen den geschweiften Klammern, dem sogenannten [[glossary:Scope]]. Man kann die Sichtbarkeit auch innerhalb einer Funktion eingrenzen: #include #include int global = 1234; int main( void ) { int local = 4; int local2 = 10; printf( "main: Wert der lokalen Variable: %d/%d\; global: %dn", local, local2, global ); { // Neuer Scope int local = 4711; // neue Variable 'local', die die vorherige Variable überdeckt. printf( "main: Wert der lokalen Variable: %d/%d\; global: %dn", local, local2, global ); } // Ende des Scopes, alle lokalen Variablen des Scopes werden abgebaut. { // Neuer Scope int global = 4321; // neue Variable 'local', die die vorherige Variable überdeckt. printf( "main: Wert der lokalen Variable: %d/%d\; global: %dn", local, local2, global ); } // Ende des Scopes, alle lokalen Variablen des Scopes werden abgebaut. printf( "main: Wert der lokalen Variable: %d/%d\; global: %dn", local, local2, global ); return EXIT_SUCCESS; } // hier geht local verloren Das Ergebnis ist nun recht interessant: main: Wert der lokalen Variable: 4/10; global: 1234 main: Wert der lokalen Variable: 4711/10; global: 1234 main: Wert der lokalen Variable: 4/10; global: 4321 main: Wert der lokalen Variable: 4/10; global: 1234 Schauen wir uns zunächst local und local2 an: Für das erste printf() findet der Compiler im aktuellen Scope die Variable local, wie auch die Variable local2 und gibt sie aus. In der zweiten Ausgabe-Zeile findet der Compiler im aktuellen Scope local, nicht aber local2. Auf der Suche nach local2 wechselt er also in einen höher gelegenen Scope, wo local2 auch definiert wurde. Die lokale Variable ''lokal'' im Scope verdeckt also die Variable ''lokal'' im übergeordneten Scope. Zwischen der zweiten und der dritten Ausgabezeile, wird ein Scope vernichtet, also auch die Variable lokal im Scope, sowie ein neuer Scope angelegt, inklusive einer neuen Variable global. Wieder muss der Compiler printf() mit passenden Variablen bestücken und während er local und local2 aus dem höher gelegenen Scope nehmen muss, findet er global bereits im aktuellen Scope. Die lokale Variable ''global'' verdeckt also die globale Variable ''global''. Für die letzte Zeile finden sich die beiden lokalen Variablen ''local'' und ''local2'' im aktuellen Scope und ''global'' findet sich wieder global. Hier sieht man auch nochmal deutlich, dass in den Scopes neue Variablen verwendet wurde, denn die alten Variablen haben ihre Werte behalten. Wenn ihr nun verstanden habt, dass der Compiler einen Bezeichner zunächst im lokalen Scope sucht und sich dann Scope für Scope hocharbeitet, so erkennt ihr, dass die globalen Variablen einfach nur im höchsten Scope liegen, also eigentlich gar keine Besonderheit darstellen. Für den höchsten Scope spart man sich lediglich die geschweiften Klammern vor und nach dem Programm.