Compartir a través de


Tipos de puntero (Guía de programación de C#)

En un contexto no seguro, un tipo puede ser un tipo de puntero, un tipo de valor o un tipo de referencia. Una declaración de tipos de puntero toma una de las siguientes formas:

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

Cualquiera de los tipos siguientes puede ser un tipo de puntero:

Los tipos de puntero no heredan de object y no existe ninguna conversión entre tipos de puntero y object. Además, las conversiones boxing y unboxing no admiten punteros. Sin embargo, puede realizar la conversión entre diferentes tipos de puntero y entre tipos de puntero y tipos enteros.

Cuando declare varios punteros en la misma declaración, únicamente debe escribir el asterisco (*) con el tipo subyacente; no se usa como prefijo en cada nombre de puntero. Por ejemplo:

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

Un puntero no puede señalar a una referencia o a un struct que contenga referencias, porque una referencia object puede recolectarse como elemento no utilizado aunque haya un puntero que la señale. El recolector de elementos no utilizados no realiza un seguimiento de si algún tipo de puntero señala a un objeto.

El valor de la variable de puntero de tipo myType* es la dirección de una variable de tipo myType. A continuación se muestran ejemplos de declaraciones de tipos de puntero:

Ejemplo

Descripción

int* p

p es un puntero a un entero.

int** p

p es un puntero a un puntero a un entero.

int*[] p

p es una matriz unidimensional de punteros a enteros.

char* p

p es un puntero a un valor char.

void* p

p es un puntero a un tipo desconocido.

El operador de direccionamiento indirecto del puntero * puede usarse para obtener acceso al contenido de la ubicación señalada por la variable de puntero. Por ejemplo, consideremos la siguiente declaración:

int* myVariable;

La expresión *myVariable denota la variable int que se encuentra en la dirección contenida en myVariable.

Hay varios ejemplos de punteros en los temas fixed (Instrucción, Referencia de C#) y Conversiones de puntero (Guía de programación de C#). En el ejemplo siguiente se muestra la necesidad de la palabra clave unsafe y la instrucción fixed, además de cómo incrementar un puntero interior. Puede pegar este código en la función Main de una aplicación de consola para ejecutarla. (Recuerde habilitar el código no seguro en el Diseñador de proyectos; elija Proyecto y Propiedades en la barra de menús y, a continuación, seleccione Permitir código no seguro en la pestaña Compilar).

// 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

No se puede aplicar el operador de direccionamiento indirecto a un puntero de tipo void*. Sin embargo, es posible usar una conversión para convertir un puntero void en cualquier otro tipo de puntero y viceversa.

Un puntero puede ser null. La aplicación del operador de direccionamiento indirecto a un puntero NULL da como resultado un comportamiento definido por la implementación.

Tenga en cuenta que pasar punteros entre métodos puede provocar un comportamiento no definido. Un ejemplo es devolver un puntero a una variable local mediante un parámetro Out o Ref, o como resultado de la función. Si el puntero se estableció en un bloque fijo, es posible que la variable a la que señala ya no sea fija.

En la tabla siguiente se muestran los operadores e instrucciones que pueden funcionar en punteros en un contexto no seguro:

Operador/Instrucción

Uso

*

Realiza el direccionamiento indirecto del puntero.

->

Obtiene acceso a un miembro de un struct a través de un puntero.

[]

Indiza un puntero.

&

Obtiene la dirección de una variable.

++ y --

Incrementa y disminuye los punteros.

+ y -

Realiza aritmética con punteros.

==, !=, <, >, <= y >=

Compara los punteros.

stackalloc

Asigna memoria en la pila.

Instrucción fixed

Fija provisionalmente una variable para que pueda encontrarse su dirección.

Especificación del lenguaje C#

Para obtener más información, consulte la Especificación del lenguaje C#. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.

Vea también

Referencia

Código no seguro y punteros (Guía de programación de C#)

Conversiones de puntero (Guía de programación de C#)

Expresiones de puntero (Guía de programación de C#)

unsafe (Referencia de C#)

fixed (Instrucción, Referencia de C#)

stackalloc (Referencia de C#)

Conversión boxing y unboxing (Guía de programación de C#)

Conceptos

Guía de programación de C#

Otros recursos

Tipos (Referencia de C#)