Share via


Zeigertypen (C#-Programmierhandbuch)

In einem unsicheren Kontext kann ein Typ sowohl ein Zeigertyp als auch ein Werttyp oder Verweistyp sein. Eine Zeigertypdeklaration erfolgt in einer der folgenden Formen:

type* identifier;
void* identifier; //allowed but not recommended

Die folgenden Typen können Zeigertypen sein:

Zeigertypen erben nicht von object, und es ist keine Konvertierung zwischen Zeigertypen und object möglich. Weiterhin unterstützen Boxing und Unboxing keine Zeiger. Es ist jedoch möglich, Konvertierungen zwischen verschiedenen Zeigertypen sowie zwischen Zeigertypen und ganzzahligen Typen durchzuführen.

Wenn Sie mehrere Zeiger innerhalb ein- und derselben Deklaration deklarieren, wird das Sternchen (*) nur einmal mit dem zugrunde liegenden Typ notiert und nicht als Präfix für jeden Zeigernamen verwendet. Beispiel:

int* p1, p2, p3;   // Ok
int *p1, *p2, *p3;   // Invalid in C#

Ein Zeiger kann nicht auf einen Verweis oder eine Struktur verweisen, die Verweise enthält, da ein Objektverweis auch dann in die Garbage Collection aufgenommen werden kann, wenn ein Zeiger darauf verweist. In der Garbage Collection wird nicht nachgehalten, ob von einem der Zeigertypen auf ein Objekt verwiesen wird.

Der Wert der Zeigervariablen vom Typ myType* ist die Adresse einer Variablen vom Typ myType. Im Folgenden finden Sie Beispiele für Zeigertypdeklarationen:

Beispiel

Beschreibung

int* p

p ist ein Zeiger auf einen ganzzahligen Wert.

int** p

p ist ein Zeiger auf einen Zeiger auf einen ganzzahligen Wert.

int*[] p

p ist ein eindimensionales Array von Zeigern auf ganzzahlige Werte.

char* p

p ist ein Zeiger auf eine char-Variable.

void* p

p ist ein Zeiger auf einen unbekannten Typ.

Sie können den Zeigerdereferenzierungsoperator * verwenden, um auf den Inhalt an der Speicherstelle zuzugreifen, auf die die Zeigervariable zeigt. Betrachten Sie beispielsweise die folgende Deklaration:

int* myVariable;

Der Ausdruck *myVariable kennzeichnet die int-Variable, die sich an der in myVariable enthaltenen Adresse befindet.

Es gibt mehrere Beispiele von Zeigern in den Themen fixed-Anweisung (C#-Referenz) und Zeigerkonvertierungen (C#-Programmierhandbuch). Im folgenden Beispiel wird die Notwendigkeit für das unsafe-Schlüsselwort und die fixed-Anweisung sowie die Vorgehensweise zum Erhöhen eines inneren Zeigers veranschaulicht. Sie können diesen Code in die Hauptmethode einer Konsolenanwendung einfügen, um ihn auszuführen. (Denken Sie daran, unsicheren Code im Projekt-Designer zu aktivieren. Wählen Sie in der Menüleiste Projekt, Eigenschaften aus, und wählen Sie dann Unsicheren Code zulassen auf der Registerkarte Erstellen aus.)

// Normal pointer to an object.
int[] a = new int[5] {10, 20, 30, 40, 50};
// Must be in unsafe code to use interior pointers.
unsafe
{
    // Must pin object on heap so that it doesn't move while using interior pointers.
    fixed (int* p = &a[0])
    {
        // p is pinned as well as object, so create another pointer to show incrementing it.
        int* p2 = p;
        Console.WriteLine(*p2);
        // Incrementing p2 bumps the pointer by four bytes due to its type ...
        p2 += 1;
        Console.WriteLine(*p2);
        p2 += 1;
        Console.WriteLine(*p2);
        Console.WriteLine("--------");
        Console.WriteLine(*p);
        // Deferencing p and incrementing changes the value of a[0] ...
        *p += 1;
        Console.WriteLine(*p);
        *p += 1;
        Console.WriteLine(*p);
    }
}

Console.WriteLine("--------");
Console.WriteLine(a[0]);
Console.ReadLine();

// Output:
//10
//20
//30
//--------
//10
//11
//12
//--------
//12

Der Dereferenzierungsoperator kann nicht auf Zeiger vom Typ void* angewendet werden. Sie können jedoch eine Umwandlung verwenden, um einen void-Zeiger in einen anderen Zeigertyp und umgekehrt zu konvertieren.

Ein Zeiger kann den Wert null annehmen. Die Anwendung des Dereferenzierungsoperators auf einen NULL-Zeiger führt zu einem in der Implementierung definierten Verhalten.

Beachten Sie, dass die Übergabe von Zeigern zwischen Methoden zu nicht definiertem Verhalten führen kann. Dies betrifft zum Beispiel die Rückgabe eines Zeigers an eine lokale Variable als Out-Parameter, Ref-Parameter oder als Funktionsergebnis. Wenn der Zeiger in einem fixed-Block festgelegt wurde, ist die Variable, auf die der Zeiger verweist, möglicherweise nicht fixiert.

In der folgenden Tabelle werden die Operatoren und Anweisungen aufgelistet, die in einem unsicheren Kontext auf Zeiger angewendet werden können.

Operator/Anweisung

Verwendung

*

Führt eine Zeigerdereferenzierung aus.

->

Greift über einen Zeiger auf einen Member einer Struktur zu.

[]

Indiziert einen Zeiger.

&

Ruft die Adresse einer Variablen ab.

++ und --

Inkrementiert und dekrementiert Zeiger.

+ und -

Führt Zeigerarithmetik aus.

==, !=, <, >, <= und >=

Vergleicht Zeiger.

stackalloc

Belegt Speicher für den Stapel.

fixed-Anweisung

Fixiert eine Variable vorübergehend, damit ihre Adresse gefunden werden kann.

C#-Programmiersprachenspezifikation

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auch

Referenz

Unsicherer Code und Zeiger (C#-Programmierhandbuch)

Zeigerkonvertierungen (C#-Programmierhandbuch)

Zeigerausdrücke (C#-Programmierhandbuch)

unsafe (C#-Referenz)

fixed-Anweisung (C#-Referenz)

stackalloc (C#-Referenz)

Boxing und Unboxing (C#-Programmierhandbuch)

Konzepte

C#-Programmierhandbuch

Weitere Ressourcen

Typen (C#-Referenz)