Operadores relacionados a ponteiro (referência do C#)Pointer related operators (C# reference)

Você pode usar os operadores a seguir para trabalhar com ponteiros:You can use the following operators to work with pointers:

Para obter informações sobre tipos de ponteiros, veja Tipos de ponteiro.For information about pointer types, see Pointer types.

Observação

Qualquer operação com ponteiros exige um contexto unsafe.Any operation with pointers requires an unsafe context. O código que contém blocos não seguros deve ser compilado com a -unsafe opção do compilador.The code that contains unsafe blocks must be compiled with the -unsafe compiler option.

Operador de endereço&Address-of operator &

O operador unário & retorna o endereço de seu operando: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

O operando do operador & deve ser uma variável fixa.The operand of the & operator must be a fixed variable. Variáveis fixas são variáveis que residem em locais de armazenamento não afetados pela operação do coletor de lixo.Fixed variables are variables that reside in storage locations that are unaffected by operation of the garbage collector. No exemplo anterior, a variável local number é uma variável fixa, pois reside na pilha.In the preceding example, the local variable number is a fixed variable, because it resides on the stack. Variáveis que residem em locais de armazenamento que podem ser afetados pelo coletor de lixo (por exemplo, realocado) são chamadas de variáveis móveis.Variables that reside in storage locations that can be affected by the garbage collector (for example, relocated) are called movable variables. Campos de objeto e elementos de matriz são exemplos de variáveis móveis.Object fields and array elements are examples of movable variables. Você pode obter o endereço de uma variável móvel se você "corrigir" ou "fixar", com uma fixed instrução.You can get the address of a movable variable if you "fix", or "pin", it with a fixed statement. O endereço obtido é válido somente dentro do bloco de uma fixed instrução.The obtained address is valid only inside the block of a fixed statement. O exemplo a seguir mostra como usar uma fixed instrução e o & operador: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.
    }
}

Não é possível obter o endereço de uma constante nem de um valor.You can't get the address of a constant or a value.

Para obter mais informações sobre variáveis fixas e móveis, veja a seção Variáveis fixas e móveis da Especificação de linguagem C#.For more information about fixed and movable variables, see the Fixed and moveable variables section of the C# language specification.

O operador binário & computa o AND lógico de seus operandos Boolianos ou o AND lógico bit a bit de seus operandos integrais.The binary & operator computes the logical AND of its Boolean operands or the bitwise logical AND of its integral operands.

Operador de indireção de ponteiro*Pointer indirection operator *

O operador unário de indireção de ponteiro * obtém a variável para a qual o operando aponta.The unary pointer indirection operator * obtains the variable to which its operand points. Também é conhecido como o operador de desreferenciar.It's also known as the dereference operator. O operando do operador * deve ser de um tipo de ponteiro.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

Não é possível aplicar o operador * a uma expressão do tipo void*.You cannot apply the * operator to an expression of type void*.

O operador binário * computa o produto de seus operandos numéricos.The binary * operator computes the product of its numeric operands.

Operador de acesso a membro do ponteiro ->Pointer member access operator ->

O operador -> combina indireção do ponteiro e acesso de membro.The -> operator combines pointer indirection and member access. Ou seja, se x for um ponteiro do tipo T* e y for um membro acessível do tipo T , uma expressão do formulárioThat 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

é equivalente ais equivalent to

(*x).y

O exemplo a seguir demonstra o uso do operador ->: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)
    }
}

Não é possível aplicar o operador -> a uma expressão do tipo void*.You cannot apply the -> operator to an expression of type void*.

Operador de acesso a elemento do ponteiro []Pointer element access operator []

Para uma expressão p de um tipo de ponteiro, um acesso de elemento de ponteiro da forma p[n] é avaliado como *(p + n), em que n deve ser do tipo implicitamente conversível em int, uint, long ou 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. Para obter informações sobre o comportamento do operador + com ponteiros, veja a seção Adição ou subtração de um valor integral para ou de um ponteiro.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.

O exemplo a seguir demonstra como acessar elementos da matriz com um ponteiro e o operador []: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

No exemplo anterior, uma stackalloc expressão aloca um bloco de memória na pilha.In the preceding example, a stackalloc expression allocates a block of memory on the stack.

Observação

O operador de acesso de elemento de ponteiro não verifica se há erros fora dos limites.The pointer element access operator doesn't check for out-of-bounds errors.

Não é possível usar [] para acesso de elemento de ponteiro com uma expressão do tipo void*.You cannot use [] for pointer element access with an expression of type void*.

Você também pode usar o [] operador para acesso de elemento de matriz ou indexador.You can also use the [] operator for array element or indexer access.

Operadores aritméticos de ponteiroPointer arithmetic operators

Você pode executar as seguintes operações aritméticas com ponteiros:You can perform the following arithmetic operations with pointers:

  • Adicionar ou subtrair um valor integral de ou para um ponteiroAdd or subtract an integral value to or from a pointer
  • Subtrair dois ponteirosSubtract two pointers
  • Incrementar ou decrementar um ponteiroIncrement or decrement a pointer

Você não pode executar essas operações com ponteiros do tipo void*.You cannot perform those operations with pointers of type void*.

Para obter informações sobre operações aritméticas com suporte com tipos numéricos, veja Operadores aritméticos.For information about supported arithmetic operations with numeric types, see Arithmetic operators.

Adição ou subtração de um valor integral a ou de um ponteiroAddition or subtraction of an integral value to or from a pointer

Para um ponteiro p do tipo T* e uma expressão n de um tipo implicitamente conversível em int, uint, long ou ulong, adição e subtração são definidas da seguinte maneira: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:

  • As expressões p + n e n + p produzem um ponteiro do tipo T* que resulta da adição de n * sizeof(T) ao endereço fornecido pelo 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.
  • A expressão p - n produz um ponteiro do tipo T* que resulta da subtração de n * sizeof(T) ao endereço fornecido pelo p.The p - n expression produces a pointer of type T* that results from subtracting n * sizeof(T) from the address given by p.

O sizeof operador Obtém o tamanho de um tipo em bytes.The sizeof operator obtains the size of a type in bytes.

O exemplo a seguir demonstra o uso do operador + com um ponteiro: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

Subtração de ponteiroPointer subtraction

Para dois ponteiros p1 e p2 do tipo T*, a expressão p1 - p2 produz a diferença entre os endereços dados por p1 e p2 divididos por 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). O tipo de resultado é long.The type of the result is long. Ou seja, p1 - p2 é computado como ((long)(p1) - (long)(p2)) / sizeof(T).That is, p1 - p2 is computed as ((long)(p1) - (long)(p2)) / sizeof(T).

O exemplo a seguir demonstra a subtração de ponteiro: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
}

Incrementar e decrementar ponteirosPointer increment and decrement

O operador de incremento ++adiciona 1 ao operando do ponteiro.The ++ increment operator adds 1 to its pointer operand. O operador de decremento --subtrai 1 do operando do ponteiro.The -- decrement operator subtracts 1 from its pointer operand.

Os dois operadores têm suporte em duas formas: sufixo (p++ e p--) e prefixo (++p e --p).Both operators are supported in two forms: postfix (p++ and p--) and prefix (++p and --p). O resultado de p++ e p-- é o valor de p antes da operação.The result of p++ and p-- is the value of p before the operation. O resultado de ++p e --p é o valor de p depois da operação.The result of ++p and --p is the value of p after the operation.

O exemplo a seguir demonstra o comportamento dos operadores de incremento de sufixo e prefixo: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

Operadores de comparação de ponteiroPointer comparison operators

Você pode usar os operadores ==, !=, <, >, <= e >= para comparar os operandos de qualquer tipo de ponteiro, incluindo void*.You can use the ==, !=, <, >, <=, and >= operators to compare operands of any pointer type, including void*. Esses operadores comparam os endereços fornecidos pelos dois operandos como se fossem inteiros sem sinal.Those operators compare the addresses given by the two operands as if they were unsigned integers.

Para obter informações sobre o comportamento desses operadores para operandos de outros tipos, veja os artigos Operadores de igualdade e Operadores de comparação.For information about the behavior of those operators for operands of other types, see the Equality operators and Comparison operators articles.

Precedência do operadorOperator precedence

A lista a seguir ordena operadores relacionados a ponteiro começando da precedência mais alta até a mais baixa:The following list orders pointer related operators starting from the highest precedence to the lowest:

  • Operadores de incremento x++ e decremento x-- sufixados e os operadores -> e []Postfix increment x++ and decrement x-- operators and the -> and [] operators
  • Operadores de incremento ++x e decremento --x prefixados e os operadores & e *Prefix increment ++x and decrement --x operators and the & and * operators
  • Operadores de adição + e -Additive + and - operators
  • Operadores de comparação <, >, <= e >=Comparison <, >, <=, and >= operators
  • Operadores de igualdade == e !=Equality == and != operators

Use parênteses, (), para alterar a ordem de avaliação imposta pela precedência do operador.Use parentheses, (), to change the order of evaluation imposed by operator precedence.

Para obter a lista completa de operadores C# ordenados por nível de precedência, consulte a seção precedência de operador do artigo sobre operadores do c# .For the complete list of C# operators ordered by precedence level, see the Operator precedence section of the C# operators article.

Capacidade de sobrecarga do operadorOperator overloadability

Um tipo definido pelo usuário não pode sobrecarregar operadores relacionados a ponteiro &, *, -> e [].A user-defined type cannot overload the pointer related operators &, *, ->, and [].

especificação da linguagem C#C# language specification

Para obter mais informações, confira as seguintes seções da especificação da linguagem C#:For more information, see the following sections of the C# language specification:

Consulte tambémSee also