Twitter und Facebook-Anbindung
X
Tweet Follow @twitterapi
!!! Anbindung an twitter und facebook öffnen !!!

Wenn Ihnen mein Online-Buch gefällt,
dann bedanken Sie sich doch mit einer kleinen Spende...

8.1 Gültigkeitsbereiche von Variablen

8.1 Gültigkeitsbereiche von Variablen

Wie in den meisten Programmiersprachen kann man auch in C bzw. Auch C++ nicht von überall auf alle Variablen zugreifen und evtl. ist Ihnen das auch schon passiert. Aber warum ist das so? Dies hängt immer vom Gültigkeitsbereich der Variable ab. Prinzipiell kann auf eine Variable zugegriffen werden, wenn sie im selben Block (gekennzeichnet durch geöffnete und geschlossene geschweifte Klammern) bzw. in einem darüber liegenden Block, definiert wurde und im Quelltext oberhalb des Zugriffsortes steht und somit Speicher für Sie zur Verfügung steht.

Variablen die außerhalb einer Funktion deklariert wurden, nennt man globale Variablen und alle anderen lokale. Allerdings hängt diese Sichtweise, ganz streng genommen, immer vom Ort der Betrachtung ab. Definiere ich mir am Anfang einer Funktion eine Variable A und anschließend innerhalb einer Schleife eine Variable B, dann ist B für die Schleife lokal und A im Bezug auf die Schleife global. Betrachtet man das Projekt als ganzes, sind A und B lokal.

Anfänger sollten sich aus Gründen der Übersichtlichkeit alle Variablen die sie brauchen, im obersten Bereich einer Funktion definieren. Somit ist zum einen sichergestellt, dass sie im Quelltext oberhalb stehen und zum anderen fördert es die Lesbarkeit. Erfahrene Programmierer definieren sich die Variablen erst kurz bevor sie sie benötigen.

Beide Vorgehensweisen haben klare Vor - und Nachteile. Wie erwähnt ist das Definieren aller Variablen am Funktionsanfang übersichtlicher und ich erwähnte auch schon, dass sie sowieso alle an dieser Stelle angelegt werden, da der Compiler ja nicht entscheiden kann, ob ein weiter darunter liegender Quelltextabschnitt erreicht wird oder nicht. Ich war früher auch dem Irrglaube verfallen, dass eine Variable erst dann angelegt wird, wenn man sie im Quelltext definiert. Der Grund, warum man es später macht ist ein anderer. Möchte man in einem neuen Projekt Sachen aus einem alten Projekt übernehmen, ist es selten, dass man ganze Funktionen benutzt. Meistens braucht man nur kleine Abschnitte. Kopiert man jetzt z.B. nur eine Berechnung, fehlen einem immer die benötigten Variablen. Wenn diese alle am Funktionsanfang stehen, neigt man dazu, einfach alle zu kopieren. Ansonsten müsste man ja wieder nachdenken, welche man tatsächlich braucht und welche einem anderen Zweck dienen. Definiert man die benötigten Variablen aber unmittelbar vor einer Berechnung, ist später klar, dass nur diese benötigt werden. Sie müssen also abwägen, was für Sie besser ist und von Fall zu Fall selber entscheiden.

Immer dann, wenn man den Gültigkeitsbereich einer Variablen verlässt, wird sie freigegeben und der Speicherplatz im RAM steht wieder zur Verfügung.

Folgender Grundsatz gilt: So lokal wie möglich und so global wie nötig! (Gilt aber nur für primitive Datentypen, die auf dem Stack abgelegt werden.)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
					
///////////////////////////////////////////////////////////////////////////////
void Aufgabe1() {
	// Hier kann nicht auf iZahl zugegriffen werden.
	// Hier kann nicht auf iAnzahl zugegriffen werden.

	int iAnzahl;	// lokale Variable

	// Hier kann auf iAnzahl zugegriffen werden.
} // Aufgabe1 /////////////////////////////////////////////////////////////////



// Hier steht iAnzahl nicht mehr zur Verfügung
int iZahl = 10;	// globale Variable



///////////////////////////////////////////////////////////////////////////////
void Aufgabe2() {
	// Hier kann auf iZahl zugegriffen werden

	int iZahl;	// lokale Variable

	// Hier wird ab jetzt immer die lokale iZahl benutzt.
	// An die globale kommt man nicht mehr ran.
} // Aufgabe2 /////////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////////////////
void Aufgabe3(int iZahl) {
	// Hier gibt es eine eigene iZahl und somit kommt man
	// an die globale nicht mehr ran.
} // Aufgabe3 /////////////////////////////////////////////////////////////////
				

oder

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
					
///////////////////////////////////////////////////////////////////////////////
void BeispielFunktion() {
	for (int iCounter=0; iCounter<10; iCounter++) {
		// Nur hier kann man auf iCounter zugreifen.
	} // end of for

	// Hier kann man auf iCounter nicht mehr zugreifen.

	if (1 < 19) {
		int iMaximum;

		// Hier kann man auf iMaximum zugreifen.
	} else {
		// Hier kann man nicht auf iMaximum zugreifen, da die Variable
		// zwar oberhalb definiert wurde, aber in einem Block steht,
		// auf welchen nicht zugegriffen werden kann, weil er in der
		// Hierarchie nicht oberhalb steht, sondern parallel.
	} // end of if

	// !!! ACHTUNG !!!

	do {
		int iGesammt	= 10;
	} while (iGesammt < 5);	// BÖSE

	// Das wird dem Compiler nicht gefallen, da iGesammt innerhalb
	// des Schleifenblockes definiert wurde und die Bedingung
	// außerhalb steht.
} // BeispielFunktion /////////////////////////////////////////////////////////
					

Um besser zwischen rein lokalen Variablen, die es nur innerhalb einer Funktion gibt und rein globalen Variablen, die es die ganze Zeit über gibt, unterscheiden zu können, ist es ratsam, vor den Variablenname einer globalen Variable ein "g_" voranzustellen (z.B. g_iGlobaleZahl). Dies verdeutlicht die Verfügbarkeit der Variable und zeigt außerdem, dass der beinhaltete Wert von überall verändert werden kann.

Zum Seitenanfang
Zum Inhaltsverzeichnis

© Copyright by Thomas Weiß, 2009 - 2012