Tipos de ponteiro (Guia de Programação em C#)
Em um contexto inseguro, um tipo pode ser de ponteiro, valor ou referência. Uma declaração de tipo de ponteiro usa uma das seguintes formas:
type* identifier;
void* identifier; //allowed but not recommended
Alguns dos seguintes tipos podem ser um tipo de ponteiro:
sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal ou bool.
Qualquer tipo enum.
Qualquer tipo de ponteiro.
Qualquer struct definido pelo usuário que contenha somente campos de tipos não gerenciados.
Os tipos de ponteiro não são herdados de objeto e não há nenhuma conversão entre tipos de ponteiro e object. Além disso, as conversões boxing e unboxing não oferecem suporte a ponteiros. No entanto, você pode converter entre diferentes tipos de ponteiro e tipos de ponteiro e tipos integrais.
Quando você designa vários ponteiros na mesma declaração, o asterisco (*) é escrito junto apenas com o tipo subjacente; ele não é usado como um prefixo para cada nome de ponteiro. Por exemplo:
int* p1, p2, p3; // Ok
int *p1, *p2, *p3; // Invalid in C#
Um ponteiro não pode apontar para uma referência ou um struct que contenha referências, pois uma referência de objeto pode ser coletada ao lixo mesmo se um ponteiro estiver apontando para ela. O coletor de lixo não acompanha se um objeto está sendo apontado por qualquer tipo de ponteiro.
O valor da variável de ponteiro do tipo myType* é o endereço de uma variável do tipo myType. Estes são exemplos de declarações de tipos de ponteiro:
Exemplo |
Descrição |
---|---|
int* p |
p é um ponteiro para um inteiro. |
int** p |
p é um ponteiro para um ponteiro para um inteiro. |
int*[] p |
p é uma matriz unidimensional de ponteiros para inteiros. |
char* p |
p é um ponteiro para um caractere. |
void* p |
p é um ponteiro para um tipo desconhecido. |
O operador de indireção de ponteiro * pode ser usado para acessar o conteúdo no local apontado pela variável de ponteiro. Por exemplo, considere a seguinte declaração:
int* myVariable;
A expressão *myVariable denota a variável int encontrada no endereço contido em myVariable.
Há vários exemplos de ponteiros nos tópicos Instrução fixed (Referência de C#) e Conversões de ponteiro (Guia de Programação em C#). O exemplo a seguir mostra a necessidade da palavra-chave unsafe e a instrução fixed e como incrementar um ponteiro interior. Você pode colar esse código na função principal de um aplicativo de console para executá-lo. (Lembre-se de habilitar código inseguro no Designer de Projeto; escolha Projeto, Propriedades na barra de menus e selecione Permitir código não seguro na guia Compilação .)
// 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
Você não pode aplicar o operador de indireção para um ponteiro do tipo void*. No entanto, você pode usar uma conversão para converter um ponteiro nulo em qualquer outro tipo de ponteiro e vice-versa.
Um ponteiro pode ser null. Aplicar o operador de indireção a um ponteiro nulo causa um comportamento definido por implementação.
Lembre-se de que transmitir ponteiros entre métodos pode causar comportamento indefinido. Exemplos estão retornando um ponteiro para uma variável local através de um parâmetro Out ou Ref ou como o resultado da função. Se o ponteiro foi definido em um bloco fixo, a variável à qual ele aponta não pode mais ser corrigida.
A tabela a seguir lista os operadores e as instruções que podem operar em ponteiros em um contexto inseguro:
Operador/Instrução |
Uso |
---|---|
* |
Executa indireção de ponteiro. |
-> |
Acessa um membro de um struct através de um ponteiro. |
[] |
Indexa um ponteiro. |
& |
Obtém o endereço de uma variável. |
++ e -- |
Incrementa e decrementa ponteiros. |
+ e - |
Executa aritmética de ponteiros. |
==, !=, <, >, <= e >= |
Compara ponteiros. |
stackalloc |
Aloca memória na pilha. |
Instrução fixed |
Corrige temporariamente uma variável para que seu endereço possa ser encontrado. |
Especificação da Linguagem C#
Para obter mais informações, consulte a Especificação da linguagem C#. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.
Consulte também
Referência
Código não seguro e ponteiros (Guia de Programação em C#)
Conversões de ponteiro (Guia de Programação em C#)
Expressões de ponteiro (Guia de Programação em C#)
Instrução fixed (Referência de C#)
Conversões boxing e unboxing (Guia de Programação em C#)