Teil 1: Grundlagen


Lebensdauer und Sichtbarkeit von Daten

Lebensdauer

Die Lebendauer eines Datums, und damit auch dessen Sichtbarkeit, hängt u.a. von der Stellung der Definition des Datum ab.

Modul

Daten, welche nicht innerhalb von Blöcken {...} definiert sind, werden als globale Daten bezeichnet. Sie sind ab der Stelle im Programm gültig, an der sie definiert werden. Ihre Gültigkeit endet am Modulende (Dateiende). Globale Variablen werden vor dem Eintritt in die Funktion main() mit 0 initialisiert.

Funktion

Daten die innerhalb von Funktionen (wie z.B. innerhalb von main()) definiert sind, werden als lokale Daten bezeichnet. Lokale Daten sind nur in der Funktion gültig, in der sie definiert sind. Sie werden nicht automatisch initialisiert und haben damit zu Beginn einen zufälligen Inhalt.

Block

Daten die innerhalb eines Blocks {...} in einer Funktion definiert werden, verhalten sich wie lokale Daten. D.h., sie werden nicht automatisch initialisiert und verlieren beim Verlassen des Blocks ihre Gültigkeit.

Zugriff auf globale Daten (Gültigkeitsbereichsoperator)

Werden globale Daten durch funktions- oder blocklokale Daten verdeckt, kann mithilfe des Gültigkeitsbereichsoperators :: (scope resolution operator, das sind zwei Doppelpunkte!) vor dem Variablennamen auf die globalen Daten zugegriffen werden.

#include <iostream>
using std::cout;
using std::endl;

// Globales Datum
short var1 = 1;
// Ausgabe von Daten
void PrintData()
{
    // Lokales Datum
    long var2 = 2L;
    // Lokales Datum, verdeckt globales Datum
    int var1 = 111;
    // Ausgabe der lokalen Daten
    cout << "var2(lokal): " << var2 << " und var1(lokal): "
         << var1 << endl;
    // Ausgabe des globalen Datums
    cout << "var1(global): " << ::var1 << endl;
}

// Weiteres globales Datum
// Eine Definition von Daten zwischen Funktionen ist
// kein guter Programmierstil, aber moeglich
long var3 = 3L;

//main
int main()
{
    // Ausgabe lokaler und globaler Daten
    PrintData();
    cout << "var3(global): " << var3 << endl;
    for (auto index = 0; index < 4; index++)
    {
        // Blockdatum, verdeckt globales Datum
        auto var1 = index * 2;
        cout << "var1(block): " << var1 << endl;
    }
}

Spezifikationen

Um einem Datum eine von seiner Definition abweichende Sichtbarkeit bzw. Lebensdauer zuzuordnen, wird vor dem Datentyp des Datums einer der nachfolgenden Spezifizierer angegeben.

extern Speicherklasse

Daten oder Funktionen der Speicherklasse extern teilen dem Compiler mit, dass ihre Definition in einem anderen Modul (Quellcode-Datei) erfolgt als im aktuellen.

Eine andere Wirkung besitzt die Speicherklasse extern bei benannten Konstanten. Soll eine benannte Konstante definiert werden die in verschiedenen Modulen verwendet wird, muss sie sowohl bei ihrer Definition als auch bei den Verweisen darauf als externe Konstante definiert werden. Hierbei ist zu beachten, dass die Konstante nur einmal initialisiert werden darf.

// Datei print.cpp

// pText wird in main.cpp ausgegeben
const char* pText = "Externer Zaehler: ";
// Modul-globales Datum
int counter = 100;
// Konstante LOOP wird in main.cpp verwendet
extern int LOOP = 5;

// Funktion wird aus main.cpp aufgerufen
int GetCounter()
{
    return counter++;
}

// Datei main.cpp

#include <iostream>

// Verweis auf in print.cpp definiertes Datum
extern const char* pText;
// Verweis auf in print.cpp definierte Funktion
extern int GetCounter();
// Verweis auf in print.cpp definierte Konstante
extern int LOOP;

//main
int main()
{
    std::cout << pText << std::endl;
    for (auto index = 0; index < LOOP; index++)
        std::cout << GetCounter() << ',';
}

static Speicherklasse

Globale Daten und Funktionen der Speicherklasse static sind nur in dem Modul sichtbar in dem Sie definiert sind.

Lokale Daten der Speicherklasse static behalten ihren letzten Wert auch dann bei, wenn ihr Gültigkeitsbereich verlassen wird, d.h. sie werden beim Verlassen des Gültigkeitsbereichs nicht gelöscht. Auf das statische Datum kann aber weiterhin nur innerhalb dessen Gültigkeitsbereich zugegriffen werden.

#include <iostream>

// Ausgabe einer Fusszeile
void PrintFooter()
{
    // Statisches Datum fuer Seitennummer mit 1 initialisieren
    // Die Initialisierung erfolgt nur einmal!
    static unsigned short pageNum = 1;
    // Seitenummer ausgeben
    std::cout << "Seite " << pageNum << std::endl;
    // Seitennummer erhoehen
    pageNum++;
}

// main
int main()
{
    // Vier Fusszeilen ausgeben
    for (auto index = 0; index < 4; index++)
        PrintFooter();
}

mutable Speicherklasse

Die mutable Speicherklasse spielt nur im Zusammenhange mit Klassen eine Rolle und ist nur der Vollständigkeit halber hier erwähnt. Mehr dazu später bei der Einführung von Klassen.

const Qualifizierer

Der const Qualifizierer kennzeichnet u.a. ein Datum, das nach seiner Definition als nicht mehr veränderbar ist (siehe auch Abschnitt Konstanten auf der Seite Daten).

Später werden wir uns diesen Qualifizierer nochmals ansehen, und zwar im Zusammenhang mit Klassen.

volatile Qualifizierer

Ein als volatile definiertes Datum weist den Compiler an, keine Optimierung bezüglich des Inhalts des Datums vorzunehmen. Typische volatile Daten sind Daten die vom Betriebssystem bereitgestellt werden (z.B. die Systemzeit) oder in Interrupt-Routinen verändert werden.


nächstes Kapitel  >>>


Copyright © cpp-tutor.de
Impressum &Datenschutz