Typy wskaźników (Przewodnik programowania w języku C#)
W kontekście słowa kluczowego „unsafe” typ może być typem wskaźnika, typem wartości lub typem referencyjnym.Deklaracja typu wskaźnika ma jedną z następujących form:
type* identifier;
void* identifier; //allowed but not recommended
Dowolny z następujących typów może być typem wskaźnika:
sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal lub bool.
Dowolny typ enum.
Dowolny typ wskaźnika.
Dowolny typ struktury zdefiniowany przez użytkownika, który zawiera tylko pola niezarządzanych typów.
Typy wskaźnika nie dziedziczą z obiektu i nie występują konwersje między typami wskaźnika a typami object.Ponadto wskaźniki nie są obsługiwane w przypadku opakowywania i rozpakowywania.Można jednak wykonywać konwersje między różnymi typami wskaźnika oraz między typami wskaźnika a typami całkowitymi.
W przypadku deklarowania wielu wskaźników w jednej deklaracji gwiazdka (*) jest pisana razem tylko z typem podstawowym; nie jest używana jako prefiks każdej nazwy wskaźnika.Na przykład:
int* p1, p2, p3; // Ok
int *p1, *p2, *p3; // Invalid in C#
Wskaźnik nie może wskazywać odwołania ani struktury zawierającej odwołania, ponieważ odwołanie do obiektu może zostać usunięte nawet wtedy, gdy jest wskazywane przez wskaźnik.Moduł odśmiecania pamięci nie sprawdza, czy obiekt jest wskazywany przez jakiś wskaźnik.
Wartość zmiennej składnika typu myType* to adres zmiennej typu myType.Poniżej przedstawiono przykłady deklaracji typów wskaźnika:
Przykład |
Opis |
---|---|
int* p |
p to wskaźnik do liczby całkowitej. |
int** p |
p to wskaźnik do wskaźnika do liczby rzeczywistej. |
int*[] p |
p to jednowymiarowa tablica wskaźników do liczb całkowitych. |
char* p |
p to wskaźnik do znaku. |
void* p |
p to wskaźnik do nieznanego typu. |
Operatora pośredniego wskaźnika * można użyć w celu uzyskania dostępu do zawartości znajdującej się w lokalizacji wskazywanej przez zmienną wskaźnikową.Na przykład przeanalizujmy następującą deklarację:
int* myVariable;
Wyrażenie *myVariable wskazuje zmienną typu int znajdującą się pod adresem zawartym w zmiennej myVariable.
Kilka przykładów wskaźników można znaleźć w tematach fixed — Instrukcja (odwołanie w C#) i Konwersje wskaźników (Przewodnik programowania w języku C#). W poniższym przykładzie pokazano, że jest potrzebne słowo kluczowe unsafe oraz instrukcja fixed, a także jak zwiększyć wartość wskaźnika wewnętrznego. Ten kod można wkleić do funkcji Main aplikacji konsoli, aby go uruchomić. (Należy pamiętać, aby w Projektancie projektu włączyć możliwość używania w kodzie słowa kluczowego „unsafe”: na pasku menu wybierz polecenia Projekt, Właściwości, a następnie wybierz opcję Zezwalaj na używanie słowa kluczowego „unsafe” na karcie Kompilacja).
// 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
Operatora pośredniego nie można zastosować do wskaźnika typu void*.Można jednak użyć rzutowania, aby przekonwertować wskaźnik typu void na wskaźnik dowolnego innego typu i odwrotnie.
Wskaźnik może mieć wartość null.Zastosowanie operatora pośredniego do wskaźnika o wartości null powoduje użycie zachowania zdefiniowanego w implementacji.
Należy pamiętać, że przekazywanie wskaźników między metodami może spowodować niezdefiniowane zachowanie.W przykładach wskaźnik do zmiennej lokalnej jest zwracany za pośrednictwem parametru Out lub Ref lub jako wynik funkcji.Jeśli wskaźnik został ustawiony w stałym bloku, wskazywana przez niego zmienna może już nie być stała.
W poniższej tabeli wymieniono operatory i instrukcje, które mogą wykonywać operacje na wskaźnikach w kontekście słowa kluczowego „unsafe”:
Operator/instrukcja |
Zastosowanie |
---|---|
* |
Wykonuje operację wskaźnika pośredniego. |
-> |
Uzyskuje dostęp do elementu członkowskiego struktury za pomocą wskaźnika. |
[] |
Indeksuje wskaźnik. |
& |
Uzyskuje adres zmiennej. |
++ oraz -- |
Zwiększa i zmniejsza wartość wskaźnika. |
+ oraz - |
Wykonuje operacje arytmetyczne na wskaźniku. |
==, !=, <, >, <= oraz >= |
Porównuje wskaźniki. |
stackalloc |
Przydziela pamięć na stosie. |
Instrukcja fixed |
Tymczasowo ustala zmienną, dzięki czemu można znaleźć ten adres. |
Specyfikacja języka C#
Aby uzyskać więcej informacji, zobacz Specyfikacja języka C#. Specyfikacja języka jest ostatecznym źródłem informacji o składni i użyciu języka C#.
Zobacz też
Informacje
Niebezpieczny kod i wskaźniki (Przewodnik programowania w języku C#)
Konwersje wskaźników (Przewodnik programowania w języku C#)
Wyrażenia wskaźników (Przewodnik programowania w języku C#)
fixed — Instrukcja (odwołanie w C#)
Konwersja boxing i konwersja unboxing (Przewodnik programowania w języku C#)
Koncepcje
Przewodnik programowania w języku C#