Operatory powiązane z wskaźnikiem (C# odwołanie)Pointer related operators (C# reference)

Można użyć następujących operatorów do pracy ze wskaźnikami:You can use the following operators to work with pointers:

Aby uzyskać informacje na temat typów wskaźnikowych, zobacz typy wskaźnika.For information about pointer types, see Pointer types.

Uwaga

Wszystkie operacje ze wskaźnikami wymagają niebezpiecznego kontekstu.Any operation with pointers requires an unsafe context. Kod, który zawiera niebezpieczne bloki, musi być skompilowany przy użyciu opcji kompilatora -unsafe .The code that contains unsafe blocks must be compiled with the -unsafe compiler option.

& operatora adresuAddress-of operator &

Jednoargumentowy operator & zwraca adres tego operandu:The unary & operator returns the address of its operand:

unsafe
{
    int number = 27;
    int* pointerToNumber = &number;

    Console.WriteLine($"Value of the variable: {number}");
    Console.WriteLine($"Address of the variable: {(long)pointerToNumber:X}");
}
// Output is similar to:
// Value of the variable: 27
// Address of the variable: 6C1457DBD4

Argument operacji operatora & musi być zmienną stałą.The operand of the & operator must be a fixed variable. Zmienne stałe są zmiennymi, które znajdują się w lokalizacjach magazynu, które nie mają wpływ na działanie modułu wyrzucania elementów bezużytecznych.Fixed variables are variables that reside in storage locations that are unaffected by operation of the garbage collector. W poprzednim przykładzie zmienna lokalna number to stała zmienna, ponieważ znajduje się ona na stosie.In the preceding example, the local variable number is a fixed variable, because it resides on the stack. Zmienne, które znajdują się w lokalizacjach magazynu, na które może mieć wpływ Moduł wyrzucania elementów bezużytecznych (na przykład rezlokalizowane), są nazywane zmiennymi zmiennych.Variables that reside in storage locations that can be affected by the garbage collector (for example, relocated) are called movable variables. Pola obiektów i elementy tablicy to przykłady ruchomych zmiennych.Object fields and array elements are examples of movable variables. Adres ruchomej zmiennej można pobrać, jeśli "Napraw" lub "PIN", za pomocą instrukcjifixed.You can get the address of a movable variable if you "fix", or "pin", it with a fixed statement. Uzyskany adres jest prawidłowy tylko wewnątrz bloku instrukcji fixed.The obtained address is valid only inside the block of a fixed statement. Poniższy przykład pokazuje, jak używać instrukcji fixed i operatora &:The following example shows how to use a fixed statement and the & operator:

unsafe
{
    byte[] bytes = { 1, 2, 3 };
    fixed (byte* pointerToFirst = &bytes[0])
    {
        // The address stored in pointerToFirst 
        // is valid only inside this fixed statement block.
    }
}

Nie można uzyskać adresu stałej ani wartości.You can't get the address of a constant or a value.

Aby uzyskać więcej informacji na temat zmiennych stałych i przenośnych, zobacz sekcję zmienne stałe i ruchome C# specyfikacji języka.For more information about fixed and movable variables, see the Fixed and moveable variables section of the C# language specification.

Operator & binarny oblicza wartość logiczną i jej operandy logiczne oraz koniunkcję bitową i jej całkowite argumenty operacji.The binary & operator computes the logical AND of its Boolean operands or the bitwise logical AND of its integral operands.

Operator pośredni wskaźnika *Pointer indirection operator *

Operator jednoargumentowy pośredni wskaźnika, * uzyskuje zmienną, do której wskazuje operand.The unary pointer indirection operator * obtains the variable to which its operand points. Jest on również znany jako operator dereferencji.It's also known as the dereference operator. Argument operacji operatora * musi być typu wskaźnika.The operand of the * operator must be of a pointer type.

unsafe
{
    char letter = 'A';
    char* pointerToLetter = &letter;
    Console.WriteLine($"Value of the `letter` variable: {letter}");
    Console.WriteLine($"Address of the `letter` variable: {(long)pointerToLetter:X}");

    *pointerToLetter = 'Z';
    Console.WriteLine($"Value of the `letter` variable after update: {letter}");
}
// Output is similar to:
// Value of the `letter` variable: A
// Address of the `letter` variable: DCB977DDF4
// Value of the `letter` variable after update: Z

Nie można zastosować operatora * do wyrażenia typu void*.You cannot apply the * operator to an expression of type void*.

Operator * binarny oblicza iloczyn swoich argumentów liczbowych.The binary * operator computes the product of its numeric operands.

Operator dostępu do elementów członkowskich wskaźnika — >Pointer member access operator ->

Operator -> łączy pośredni wskaźnik i dostęp do elementów członkowskich.The -> operator combines pointer indirection and member access. Oznacza to, że jeśli x jest wskaźnikiem typu T*, a y jest dostępną składową typu T, wyrażenie formularzaThat is, if x is a pointer of type T* and y is an accessible member of type T, an expression of the form

x->y

jest równoważnyis equivalent to

(*x).y

Poniższy przykład ilustruje użycie operatora ->:The following example demonstrates the usage of the -> operator:

public struct Coords
{
    public int X;
    public int Y;
    public override string ToString() => $"({X}, {Y})";
}

public class PointerMemberAccessExample
{
    public static unsafe void Main()
    {
        Coords coords;
        Coords* p = &coords;
        p->X = 3;
        p->Y = 4;
        Console.WriteLine(p->ToString());  // output: (3, 4)
    }
}

Nie można zastosować operatora -> do wyrażenia typu void*.You cannot apply the -> operator to an expression of type void*.

Operator dostępu do elementów wskaźnika []Pointer element access operator []

Dla wyrażenia p typu wskaźnika, dostęp elementu wskaźnika do formularza p[n] jest oceniane jako *(p + n), gdzie n musi być typem niejawnie konwertowanym na int, uint, longlub ulong.For an expression p of a pointer type, a pointer element access of the form p[n] is evaluated as *(p + n), where n must be of a type implicitly convertible to int, uint, long, or ulong. Aby uzyskać informacje o zachowaniu operatora + ze wskaźnikami, zobacz Dodawanie lub odejmowanie wartości całkowitej do lub z sekcji wskaźnika .For information about the behavior of the + operator with pointers, see the Addition or subtraction of an integral value to or from a pointer section.

W poniższym przykładzie pokazano, jak uzyskać dostęp do elementów tablicy za pomocą wskaźnika i operatora []:The following example demonstrates how to access array elements with a pointer and the [] operator:

unsafe
{
    char* pointerToChars = stackalloc char[123];

    for (int i = 65; i < 123; i++)
    {
        pointerToChars[i] = (char)i;
    }

    Console.Write("Uppercase letters: ");
    for (int i = 65; i < 91; i++)
    {
        Console.Write(pointerToChars[i]);
    }
}
// Output:
// Uppercase letters: ABCDEFGHIJKLMNOPQRSTUVWXYZ

W przykładzie używa operatorastackalloc , aby przydzielić blok pamięci na stosie.The example uses the stackalloc operator to allocate a block of memory on the stack.

Uwaga

Operator dostępu do elementów wskaźnika nie sprawdza występowania błędów poza granicami.The pointer element access operator doesn't check for out-of-bounds errors.

Nie można użyć [] do uzyskiwania dostępu do elementu wskaźnika przy użyciu wyrażenia typu void*.You cannot use [] for pointer element access with an expression of type void*.

Można również użyć operatora [] dla elementu tablicy lub dostępu indeksatora.You also can use the [] operator for array element or indexer access.

Operatory arytmetyczne wskaźnikaPointer arithmetic operators

Za pomocą wskaźników można wykonywać następujące operacje arytmetyczne:You can perform the following arithmetic operations with pointers:

  • Dodaj lub Odejmij wartość całkowitą do lub ze wskaźnikaAdd or subtract an integral value to or from a pointer
  • Odejmij dwa wskaźnikiSubtract two pointers
  • Zwiększ lub Zmniejsz wskaźnikIncrement or decrement a pointer

Nie można wykonać tych operacji ze wskaźnikami typu void*.You cannot perform those operations with pointers of type void*.

Aby uzyskać informacje o obsługiwanych operacjach arytmetycznych o typach liczbowych, zobacz Operatory arytmetyczne.For information about supported arithmetic operations with numeric types, see Arithmetic operators.

Dodanie lub odjęcie wartości całkowitej do lub ze wskaźnikaAddition or subtraction of an integral value to or from a pointer

Dla wskaźnika p typu T* i n wyrażenia typu niejawnie przekonwertowany na int, uint, longlub ulong, Dodawanie i odejmowanie są zdefiniowane w następujący sposób:For a pointer p of type T* and an expression n of a type implicitly convertible to int, uint, long, or ulong, addition and subtraction are defined as follows:

  • Wyrażenia p + n i n + p tworzą wskaźnik typu T*, który powoduje dodanie n * sizeof(T) do adresu podanego przez p.Both p + n and n + p expressions produce a pointer of type T* that results from adding n * sizeof(T) to the address given by p.
  • Wyrażenie p - n generuje wskaźnik typu T*, który wynika z odejmowania n * sizeof(T) od adresu podanych przez p.The p - n expression produces a pointer of type T* that results from subtracting n * sizeof(T) from the address given by p.

Operatorsizeof uzyskuje rozmiar typu w bajtach.The sizeof operator obtains the size of a type in bytes.

Poniższy przykład ilustruje użycie operatora + ze wskaźnikiem:The following example demonstrates the usage of the + operator with a pointer:

unsafe
{
    const int Count = 3;
    int[] numbers = new int[Count] { 10, 20, 30 };
    fixed (int* pointerToFirst = &numbers[0])
    {
        int* pointerToLast = pointerToFirst + (Count - 1);

        Console.WriteLine($"Value {*pointerToFirst} at address {(long)pointerToFirst}");
        Console.WriteLine($"Value {*pointerToLast} at address {(long)pointerToLast}");
    }
}
// Output is similar to:
// Value 10 at address 1818345918136
// Value 30 at address 1818345918144

Odejmowanie wskaźnikaPointer subtraction

W przypadku dwóch wskaźników p1 i p2 typu T*wyrażenie p1 - p2 powoduje różnicę między adresami podaną przez p1 i p2 podzieloną przez sizeof(T).For two pointers p1 and p2 of type T*, the expression p1 - p2 produces the difference between the addresses given by p1 and p2 divided by sizeof(T). Typ wyniku jest long.The type of the result is long. Oznacza to, że p1 - p2 jest obliczana jako ((long)(p1) - (long)(p2)) / sizeof(T).That is, p1 - p2 is computed as ((long)(p1) - (long)(p2)) / sizeof(T).

Poniższy przykład ilustruje odejmowanie wskaźnika:The following example demonstrates the pointer subtraction:

unsafe
{
    int* numbers = stackalloc int[] { 0, 1, 2, 3, 4, 5 };
    int* p1 = &numbers[1];
    int* p2 = &numbers[5];
    Console.WriteLine(p2 - p1);  // output: 4
}

Zwiększenie i zmniejszenie wskaźnikaPointer increment and decrement

Operator przyrostu ++ dodaje 1 do jego operandu wskaźnika.The ++ increment operator adds 1 to its pointer operand. Operator zmniejszania -- odejmuje 1 od jego operandu wskaźnika.The -- decrement operator subtracts 1 from its pointer operand.

Oba operatory są obsługiwane w dwóch formach: przyrostki (p++ i p--) oraz prefiks (++p i --p).Both operators are supported in two forms: postfix (p++ and p--) and prefix (++p and --p). Wynik p++ i p-- jest wartością p przed operacją.The result of p++ and p-- is the value of p before the operation. Wynik ++p i --p jest wartością p po operacji.The result of ++p and --p is the value of p after the operation.

W poniższym przykładzie przedstawiono zachowanie operatorów przyrostu przyrostkowego i powiększania:The following example demonstrates the behavior of both postfix and prefix increment operators:

unsafe
{
    int* numbers = stackalloc int[] { 0, 1, 2 };
    int* p1 = &numbers[0];
    int* p2 = p1;
    Console.WriteLine($"Before operation: p1 - {(long)p1}, p2 - {(long)p2}");
    Console.WriteLine($"Postfix increment of p1: {(long)(p1++)}");
    Console.WriteLine($"Prefix increment of p2: {(long)(++p2)}");
    Console.WriteLine($"After operation: p1 - {(long)p1}, p2 - {(long)p2}");
}
// Output is similar to
// Before operation: p1 - 816489946512, p2 - 816489946512
// Postfix increment of p1: 816489946512
// Prefix increment of p2: 816489946516
// After operation: p1 - 816489946516, p2 - 816489946516

Operatory porównania wskaźnikaPointer comparison operators

Operatory ==, !=, <, >, <=i >= służą do porównywania operandów dowolnego typu wskaźnika, w tym void*.You can use the ==, !=, <, >, <=, and >= operators to compare operands of any pointer type, including void*. Te operatory porównują adresy podane przez dwa operandy, tak jakby były to liczby całkowite bez znaku.Those operators compare the addresses given by the two operands as if they were unsigned integers.

Aby uzyskać informacje o zachowaniu tych operatorów dla operandów innych typów, zobacz artykuły Operatory równości i Operatory porównania .For information about the behavior of those operators for operands of other types, see the Equality operators and Comparison operators articles.

Pierwszeństwo operatorówOperator precedence

Poniższa lista kolejności pokrewnych operatorów, rozpoczynając od najwyższego priorytetu do najniższego:The following list orders pointer related operators starting from the highest precedence to the lowest:

  • Przyrosty przyrostkowe x++ i zmniejszają operatory x-- i operatory -> i []Postfix increment x++ and decrement x-- operators and the -> and [] operators
  • ++x przyrostu prefiksu i zmniejszaj operatory --x i operatory & i *Prefix increment ++x and decrement --x operators and the & and * operators
  • Addytywne + i operatory -Additive + and - operators
  • Porównanie <, >, <=i operatory >=Comparison <, >, <=, and >= operators
  • Operatory równości == i !=Equality == and != operators

Użyj nawiasów (), aby zmienić kolejność oceny nałożona przez pierwszeństwo operatorów.Use parentheses, (), to change the order of evaluation imposed by operator precedence.

Aby uzyskać pełną listę C# operatorów uporządkowanych według poziomu pierwszeństwa, zobacz sekcję pierwszeństwo operatorów w artykule C# Operators .For the complete list of C# operators ordered by precedence level, see the Operator precedence section of the C# operators article.

Przeciążanie operatoraOperator overloadability

Typ zdefiniowany przez użytkownika nie może przeciążać operatorów powiązanych ze wskaźnikami &, *, ->i [].A user-defined type cannot overload the pointer related operators &, *, ->, and [].

specyfikacja języka C#C# language specification

Aby uzyskać więcej informacji, zobacz następujące sekcje C# specyfikacji języka:For more information, see the following sections of the C# language specification:

Zobacz takżeSee also