Programmiersprache C/C++

Speicherklassen

Folgende Speicherklassen stehen zur Verfügung:
  auto
  register 
  static 
  extern 
auto

  auto deklarator
Variablen mit der Speicherklasse auto sind lokale Variablen, die innerhalb eines Blocks gültig sind.
Diesen Variablen wird bei Eintritt in den Block dynamisch Speicherplatz zugewiesen, bei Verlassen des Blocks wird dieser Speicherplatz wieder frei gegeben. Dieser Speicherplatz befindet sich im allgemeinen auf dem Stack.
Wird Variablen keine Speicherklasse zugewiesen, so erhalten sie automatisch die Klasse auto.

static

  static deklarator
Variablen mit der Speicherklasse auto sind lokale Variablen, die innerhalb eines Blocks gültig sind.
Diesen Variablen wird statisch Speicherplatz zugewiesen. Dieser Speicherplatz steht während der gesamten Laufzeit des Programms zur Verfügung, also auch dann, wenn der Block, zu dem sie gehöhren, nicht aktiv ist.
Statische Variablen müssen explizit vereinbart werden.
Sie sind nur innerhalb ihrer Übersetzungseinheit gültig.

auto und static schließen sich gegenseitig aus.

Mit static deklarierte Funktionen sind nur innerhalb ihrer Übersetzungseinheit gültig.

Beispiel:

  static void func();
register

  register deklarator
Variablen der Speicherklasse register sind spezielle automatische Variablen.
Sie werden nach Möglichkeit in schnellem Speicher abgelegt (z.B. in einem Register des Prozessors).
Es gibt Beschränkungen hinsichtlich des Typs von Registervariablen: Steht kein schneller Speicher zur Verfügung, so werden die Variablen "normal" behandelt.

Die Zuordnung der Speicherklasse register kann als "Bitte" an das System aufgefaßt werden, eine Variable, auf die häufig zugegriffen werden muß, möglichst effektiv zu verwalten.
Es besteht keine Gewähr dafür, daß das System in der Lage ist, eine solche Vorzugsbehandlung einzuräumen.
Die Anzahl der Variablen, denen eine Vorzugsbehandlung zukommen kann, ist - systemspezifisch - eng begrenzt.
Bemerkung: In Bezug auf ein spezielles Zielsystem ist natürlich eine relativ gute Einschätzung möglich.

Für Microsoft Visual C++ 1.0 beispielsweise gilt:
Bei Compilierungen für Zielsysteme mit 16 Bit stehen zu diesem Zweck die Register SI und DI zur Verfügung, die jeweils einen Wert mit 16 Bit aufnehmen können. Wenn diese beiden Register bereits besetzt sind (oder sich das über deklarator angegebene Objekt aufgrund seiner Größe nicht in einem Register speichern läßt), ignoriert der Compiler das Schlüsselwort, d.h. legt die entsprechende Variable auf dem Stack ab.

extern

  extern deklarator
Variablen mit der Speicherklasse extern werden aus anderen Übersetzungseinheiten importiert.
Ihnen steht während der gesamten Programmausführung Speicherplatz zur Verfügung.
In der exportierenden Übersetzungseinheit müssen die betreffenden Variablen ohne Angabe einer Speicherklasse als globale Variablen, d.h. außerhalb einer Funktionsdefinition, deklariert worden sein.

Beispiel:

  /*---- Uebersetzungseinheit 1 ----*/
  
  int global;                         /* Speicherplatzreservierung */

  int function_1(...) { ... }


  /*---- Uebersetzungseinheit 2 ----*/
  
  extern int global;                  /* Verweis */

  int function_2(...) { ... }
extern wird vor allem auch zur Deklaration von externen Funktionen benutzt.

Beispiel:
Die folgenden Anweisungen sind in ihrer Wirkungsweise:

  extern int a;          /* statisch  */
  static int b;          /* statisch  */
  int const c = 0;       /* statisch  */
  void d                 /* statisch  */
    (int e,              /* dynamisch */
    register int f)      /* dynamisch */
    {
    extern int g;        /* statisch  */
    static int h;        /* statisch  */
    int i;               /* dynamisch */
    auto int j;          /* dynamisch */
    register int k;      /* dynamisch */
  }

C++:

  extern sprache deklarator
  extern sprache { deklaratorliste }
Werden Funktionen importiert, die in einer anderen Sprache als C++ geschrieben sind, so muß diese Form der Deklaration benutzt werden.

Beispiel:

  extern "C" int ext_function(int x);
Um die Nutzung der Funktionen des C-Laufzeitsystems unter C++ zu gestatten, enthalten die Header-Dateien neuerer Sprachsysteme Konstruktionen wie:
  #ifdef __cplusplus
  extern "C" {
  #endif
    ...
  #ifdef __cplusplus
  }
  #endif
Zu beachten ist, daß bei externen Funktionen/Variablen in einer Reihe von Systemen schärfere Restriktionen hinsichtlich der Anzahl signifikanter Zeichen im Namen gelten.


Beispiel:

  #include <stdio.h>

  void stat_func(void)
  {
    static int n;

    n++;
    printf("%d-ter Aufruf von stat_func\n", n);
  }                       /* liefert korrekte Ausgaben */

  void auto_func(void)
  {
    int n;                /* entspricht  auto int n;  */

    n++;
    printf("%d-ter Aufruf von auto_func\n", n);
  }                       /* liefert i.a. fehlerhafte Ausgaben */

  int main(void)
  {
    int i;

    for ( i=0; i<3; i++) {
      stat_func();
      auto_func();
    }

    return 0;
  }
Testergebnisse:
auto_func verhält beim Test des obigen Programms mit verschiedenen C-Systemen unterschiedlich - falsch.
Tückisch sind fast richtige Ergebnisse !
GCC
  1-ter Aufruf von stat_func
  2-ter Aufruf von auto_func
  2-ter Aufruf von stat_func
  3-ter Aufruf von auto_func
  3-ter Aufruf von stat_func
  4-ter Aufruf von auto_func

MSC 6.0
  1-ter Aufruf von stat_func
  5691-ter Aufruf von auto_func
  2-ter Aufruf von stat_func
  5691-ter Aufruf von auto_func
  3-ter Aufruf von stat_func
  5691-ter Aufruf von auto_func

Borland C++ 4.52
  1-ter Aufruf von stat_func
  28-ter Aufruf von auto_func
  2-ter Aufruf von stat_func
  28-ter Aufruf von auto_func
  3-ter Aufruf von stat_func
  28-ter Aufruf von auto_func

Beispiel:

  #include <stdio.h>      

  void auto_fct()
  {                            /* Initialisierung bei jedem Aufruf */
    int a[4] = { 0, 1, 2, 3 };
    int i;
  
    for ( i=0; i<4; i++ ) printf("%d ", a[i]);
    printf("\n");

    a[0] = 9;
    for ( i=0; i<4; i++ ) printf("%d ", a[i]);
    printf("\n");
  }

  void static_fct() 
  {                           /* Initialisierung nur bei Programmstart */
    static int a[4] = { 0, 1, 2, 3 };
    int i;
  
    for ( i=0; i<4; i++ ) printf("%d ", a[i]);
    printf("\n");

    a[0] = 9;
    for ( i=0; i<4; i++ ) printf("%d ", a[i]);
    printf("\n");
  }

  int main(void)
  {
    int i;

    for ( i=0; i<2; i++) auto_fct();      
    printf("\n");
    for ( i=0; i<2; i++) static_fct();

    return 0;
  }

Zurück zum Menü
Zurück zur vorigen Seite Weiter zur nächsten Seite

P. Böhme, 31.12.1995