Operadores relacionados con el puntero (referencia de C#)Pointer related operators (C# reference)

Puede usar los siguientes operadores para trabajar con punteros:You can use the following operators to work with pointers:

Para obtener información sobre los tipos de punteros, vea Tipos de puntero.For information about pointer types, see Pointer types.

Nota

Cualquier operación con punteros requiere un contexto unsafe.Any operation with pointers requires an unsafe context. El código que contiene bloques no seguros debe compilarse con la opción del compilador -unsafe.The code that contains unsafe blocks must be compiled with the -unsafe compiler option.

Operador Address-of &Address-of operator &

El operador unario & devuelve la dirección de su 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

El operando del operador & debe ser una variable fija.The operand of the & operator must be a fixed variable. Las variables fijas son las que residen en ubicaciones de almacenamiento que no se ven afectadas por el funcionamiento del recolector de elementos no utilizados.Fixed variables are variables that reside in storage locations that are unaffected by operation of the garbage collector. En el ejemplo anterior, la variable local number es una variable fija, ya que reside en la pila.In the preceding example, the local variable number is a fixed variable, because it resides on the stack. Las variables que residen en ubicaciones de almacenamiento que pueden verse afectadas por el recolector de elementos no utilizados (por ejemplo, reubicadas) se denominan variables móviles.Variables that reside in storage locations that can be affected by the garbage collector (for example, relocated) are called movable variables. Los campos de objeto y los elementos de matriz son ejemplos de variables móviles.Object fields and array elements are examples of movable variables. Puede obtener la dirección de una variable móvil si la "fija" o "ancla" con la instrucción fixed.You can get the address of a movable variable if you "fix", or "pin", it with the fixed statement. La dirección obtenida solo es válida mientras dure el bloque de instrucciones fixed.The obtained address is valid only for the duration of the fixed statement block. En el ejemplo siguiente se muestra cómo usar la instrucción fixed y el operador &:The following example shows how to use the 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.
    }
}

No se puede obtener la dirección de una constante o un valor.You can't get the address of a constant or a value.

Para obtener más información sobre las variables fijas y móviles, vea la sección Variables fijas y móviles de Especificación del lenguaje C#.For more information about fixed and movable variables, see the Fixed and moveable variables section of the C# language specification.

El operador binario & calcula el AND lógico de sus operandos booleanos o el AND lógico bit a bit de sus operandos enteros.The binary & operator computes the logical AND of its Boolean operands or the bitwise logical AND of its integral operands.

Operador de direccionamiento indirecto del puntero *Pointer indirection operator *

El operador unario de direccionamiento indirecto del puntero * obtiene la variable a la que apunta su operando.The unary pointer indirection operator * obtains the variable to which its operand points. También se conoce como operador de desreferencia.It's also known as the dereference operator. El operando del operador * debe ser un tipo de puntero.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

No se puede aplicar el operador * a una expresión de tipo void*.You cannot apply the * operator to an expression of type void*.

El operador binario * calcula la multiplicación de sus operandos numéricos.The binary * operator computes the product of its numeric operands.

Operador de acceso a miembros de puntero ->Pointer member access operator ->

El operador -> combina el direccionamiento indirecto del puntero y el acceso a miembros.The -> operator combines pointer indirection and member access. Es decir, si x es un puntero de tipo T* y y es un miembro accesible de T, una expresión con el formatoThat is, if x is a pointer of type T* and y is an accessible member of T, an expression of the form

x->y

es equivalente ais equivalent to

(*x).y

En el siguiente ejemplo se muestra el uso del 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)
    }
}

No se puede aplicar el operador -> a una expresión de tipo void*.You cannot apply the -> operator to an expression of type void*.

Operador de acceso de elemento de puntero []Pointer element access operator []

En el caso de una expresión p de un tipo de puntero, un acceso de elemento de puntero con el formato p[n] se evalúa como *(p + n), donde n debe ser de un tipo convertible de forma implícita en int, uint, long o 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 obtener información sobre el comportamiento del operador + con punteros, vea la sección Suma o resta de un valor entero en un puntero.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.

En el ejemplo siguiente se muestra cómo acceder a los elementos de matriz con un puntero y el 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

En el ejemplo se usa el operador stackalloc para asignar un bloque de memoria en la pila.The example uses the stackalloc operator to allocate a block of memory on the stack.

Nota

El operador de acceso de elemento de puntero no busca errores fuera de límites.The pointer element access operator doesn't check for out-of-bounds errors.

No puede usar [] para el acceso de elemento de puntero con una expresión de tipo void*.You cannot use [] for pointer element access with an expression of type void*.

También puede usar el operador [] para acceso de elemento de matriz o indizador.You also can use the [] operator for array element or indexer access.

Operadores aritméticos de punteroPointer arithmetic operators

Puede realizar las siguientes operaciones aritméticas con punteros:You can perform the following arithmetic operations with pointers:

  • Agregar o restar un valor entero en un punteroAdd or subtract an integral value to or from a pointer
  • Restar dos punterosSubtract two pointers
  • Incrementar o reducir un punteroIncrement or decrement a pointer

No es posible realizar esas operaciones con punteros de tipo void*.You cannot perform those operations with pointers of type void*.

Para obtener información sobre las operaciones aritméticas admitidas con tipos numéricos, vea Operadores aritméticos.For information about supported arithmetic operations with numeric types, see Arithmetic operators.

Suma o resta de un valor entero en un punteroAddition or subtraction of an integral value to or from a pointer

En el caso de un puntero p de tipo T* y una expresión n de un tipo convertible de forma implícita en int, uint, long o ulong, la suma y la resta se definen de este modo: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:

  • Ambas expresiones p + n y n + p generan un puntero de tipo T* que resulta de agregar n * sizeof(T) a la dirección proporcionada por 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.
  • La expresión p - n genera un puntero de tipo T* que resulta de restar n * sizeof(T) a la dirección proporcionada por p.The p - n expression produces a pointer of type T* that results from subtracting n * sizeof(T) from the address given by p.

El operador sizeof obtiene el tamaño de un tipo en bytes.The sizeof operator obtains the size of a type in bytes.

En el siguiente ejemplo se muestra el uso del operador + con un puntero: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

Resta de punteroPointer subtraction

En el caso de dos punteros p1 y p2 de tipo T*, la expresión p1 - p2 genera la diferencia entre las direcciones proporcionadas por p1 y p2 dividida 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). El tipo del resultado es long.The type of the result is long. Es decir, p1 - p2 se calcula como ((long)(p1) - (long)(p2)) / sizeof(T).That is, p1 - p2 is computed as ((long)(p1) - (long)(p2)) / sizeof(T).

El ejemplo siguiente muestra la resta de puntero: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
}

Incremento y decremento de punteroPointer increment and decrement

El operador de incremento ++ agrega 1 a su operando de puntero.The ++ increment operator adds 1 to its pointer operand. El operador de decremento -- resta 1 a su operando de puntero.The -- decrement operator subtracts 1 from its pointer operand.

Ambos operadores se admiten con dos formatos: postfijo (p++ y p--) y prefijo (++p y --p).Both operators are supported in two forms: postfix (p++ and p--) and prefix (++p and --p). El resultado de p++ y p-- es el valor de p antes de la operación.The result of p++ and p-- is the value of p before the operation. El resultado de ++p y --p es el valor de p después de la operación.The result of ++p and --p is the value of p after the operation.

El ejemplo siguiente muestra el comportamiento de los operadores de incremento postfijo y prefijo: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 comparación de punteroPointer comparison operators

Puede usar los operadores ==, !=, <, >, <= y >= para comparar los operandos de cualquier tipo de puntero, incluido void*.You can use the ==, !=, <, >, <=, and >= operators to compare operands of any pointer type, including void*. Esos operadores comparan las direcciones proporcionadas por los dos operandos como si fueran enteros sin signo.Those operators compare the addresses given by the two operands as if they were unsigned integers.

Para obtener información sobre el comportamiento de esos operadores para operandos de otros tipos, vea los artículos Operadores de igualdad y Operadores de comparación.For information about the behavior of those operators for operands of other types, see the Equality operators and Comparison operators articles.

Prioridad de operadoresOperator precedence

En la lista siguiente se ordenan los operadores relacionados con el puntero desde la prioridad más alta a la más baja:The following list orders pointer related operators starting from the highest precedence to the lowest:

  • Operadores de incremento x++ y decremento x-- postfijos y operadores -> y []Postfix increment x++ and decrement x-- operators and the -> and [] operators
  • Operadores de incremento ++x y decremento --x prefijos y operadores & y *Prefix increment ++x and decrement --x operators and the & and * operators
  • Operadores + y - de sumaAdditive + and - operators
  • Operadores de comparación <, >, <= y >=Comparison <, >, <=, and >= operators
  • Operadores de igualdad == y !=Equality == and != operators

Use paréntesis, (), para cambiar el orden de evaluación impuesto por la prioridad de los operadores.Use parentheses, (), to change the order of evaluation imposed by operator precedence.

Para obtener la lista completa de los operadores de C# ordenados por nivel de prioridad, vea Operadores de C#.For the complete list of C# operators ordered by precedence level, see C# operators.

Posibilidad de sobrecarga del operadorOperator overloadability

Un tipo definido por el usuario no puede sobrecargar los operadores relacionados con el puntero &, *, -> y [].A user-defined type cannot overload the pointer related operators &, *, ->, and [].

Especificación del lenguaje C#C# language specification

Para más información, vea las secciones siguientes de la Especificación del lenguaje C#:For more information, see the following sections of the C# language specification:

Vea tambiénSee also