next up previous contents index
Next: Referenzen Up: Grundtypen und abgeleitete Typen Previous: Konstanten

Abgeleitete Typen

  Aus Grundtypen und Benutzer-definierten Typen können mit den Deklarationsoperatoren neue Typen abgeleitet werden:

* Zeiger
[]Array
& Referenz
()Funktion

Die Deklaration soll dabei die spätere Anwendung widerspiegeln:  

    int a[10];            i = a[3];
    int *ptr;             i = *ptr;
    int f(int);           i = f(99);

Verwirrung entsteht oft dadurch, daß

* und & Präfix-Operatoren und
[] und () Postfix-Operatoren

    sind und unterschiedliche Präzedenzen haben:

    int *v[10];    // Array aus 10 int-Zeigern
    int (*v)[10];  // Zeiger auf Array aus 10 ints

Die meisten Menschen merken sich einfach die Gestalt der häufigsten Typen.

B. Stroustrup

Der Typ void

  Syntaktisch: wie ein Grundtyp.

Aber: void-Objekte gibt es nicht!

Zweck:

Einer Variablen vom Typ void* können beliebige Zeiger zugewiesen werden. Sie darf jedoch nicht dereferenziert werden.

Zum Zugriff muß die explizite Typumwandlung benutzt werden:

    void *f(unsigned int);
    ...
    int *iptr = (int*) f(10);

Zeiger-Typen

   Für die meisten Typen T ist T* ein Zeiger auf T.

B. Stroustrup

Ein T* kann die Adresse eines Objekts vom Typ T enthalten.

Für Arrays und Funktionen ist die Notation komplizierter:

    int *p;         // Zeiger auf int
    char **cpp;     // Zeiger auf char-Zeiger
    int (*vp)[7];   // Zeiger auf ein int-Array
    int (*fp)(t)    // Zeiger auf Fkt. "int f(t)"

Die elementare Operation auf Zeigern ist die Dereferenzierung mit dem Operator *:    

    char c = 'P';
    char *cp = &c;    // Addresse von c
    char c2 = *cp;    // c2 = 'P'
    class date 
    {public: long julian;} *dp;
    cout << (*dp).julian;   // Klammern!
    cout << dp->julian;     // dto. aber schoener!

Arithmetik mit Zeigern    

Erlaubt sind

Voraussetzung: Der Zeiger zeigt auf ein ``Datenobjekt'', d.h. nicht auf void oder eine Funktion.

    int strlen(char *p)
    { int l=0;
      while (*p++) l++;
      return l;
    }
oder
    int strlen(char *p)
    { char *pos = p;
      while (*pos++);
      return (pos-p)+1;
    }
aber nicht
    // Ein Zeiger auf "strlen":
    int (*fp)(char*) = strlen;  
    fp++;         // VERBOTEN!

Arrays

  Für einen Typ T ist T[size] ein Array aus size Elementen vom Typ T, indiziert von 0 bis size-1:

    float v[100];    // 100 floats
    int d[24][80];   // 24 80-elementige int-Arrays
    char *texte[50]; // 50 char-Zeiger
    date urlaub[29]; // 29 Urlaubstage

Die Länge eines Arrays muß nicht angegeben werden, wenn ein Initialisierer spezifiziert ist:

 

    int v1[] = {1, 2, 3, 4};      // 4 Elemente
    char c[] = {'a', 'b', 'c'};   // 3 Elemente

Sonderform für char-Arrays:

 

    char c[] = "abc";  // 4 Elemente !!!

Vorsicht: Eine entsprechende Zuweisung ist nicht definiert:

    char c[4];
    c = "abc";   // FEHLER

Ist der Initialisierer zu kurz, wird mit Nullen von entsprechendem Typ aufgefüllt:

    int a[5] = {1,2,3}; // {1,2,3,0,0}
    char c[5] = "abc"   // {'a','b','c','\0','\0'}
    float y[4][2] = {{1,2},    // |1,2|
                     {3,4},    // |3,4|
                     {5,6}};   // |5,6|
                               // |0,0|

Zeiger und Arrays

    Der Name eines Arrays kann als Zeiger auf das erste Element verwendet werden.

    char text[] = "hallo";
    char *p = text;
ist dasselbe wie
    char text[] = "hallo";
    char *p = &text[0];

Wird oft in Funktionsaufrufen ausgenutzt:

    char text[] = "C++ is Fun";
    int length = strlen(text);

übergeben wird der Zeiger auf text[0]

    tex2html_wrap_inline5173 Wert-Parameter-Übergabe (call-by-value) mit Arrays geht nicht!

Arithmetik auf Zeigern hängt vom Typ ab, auf den gezeigt wird:   

Wenn p vom Typ T* auf ein Element eines T-Arrays zeigt, liefert p+1 die Adresse des nächsten Elementes.

int main()
{
    double d[2];
    double* dp1 = &d[0];
    double* dp2 = &d[1];
    
    cout << "Zeigerdifferenz: " << dp2 - dp1;
    cout << " Adressendifferenz: " 
         << long(dp2) - long(dp1);
}
}

liefert (Sun4)

Zeigerdifferenz: 1 Adressendifferenz: 8

Das Ergebnis der Pointer-Arithmetik ist undefiniert:


next up previous contents index
Next: Referenzen Up: Grundtypen und abgeleitete Typen Previous: Konstanten

Peter Pfahler, 1997