Pointer Types em Zig — O que é e Como Usar

Pointer Types em Zig — O que é e Como Usar

Definição

Pointer types (tipos de ponteiro) em Zig são referências a endereços de memória. Diferente de C, onde existe apenas um tipo de ponteiro (T*), Zig distingue entre vários tipos de ponteiro com semânticas diferentes. Essa distinção permite ao compilador verificar a segurança do acesso à memória e otimizar o código gerado.

Cada tipo de ponteiro carrega informações sobre: quantos elementos aponta, se é mutável ou const, qual o alinhamento, e se pode ser nulo.

Por que Pointer Types Importam

  1. Segurança: O sistema de tipos impede usos incorretos de ponteiros em tempo de compilação.
  2. Clareza: O tipo declara exatamente a intenção — um item, vários itens ou um slice com tamanho.
  3. Interop com C: Tipos específicos mapeiam diretamente para ponteiros C.
  4. Otimização: O compilador usa as informações de tipo para gerar código mais eficiente.

Tipos de Ponteiro

TipoNomeDescrição
*TSingle-item pointerAponta para exatamente um valor
*const TConst pointerPonteiro somente leitura para um valor
[*]TMany-item pointerAponta para vários itens (sem tamanho conhecido)
[]TSlicePonteiro + comprimento (tamanho conhecido)
[*:0]TSentinel-terminated pointerMuitos itens terminados por sentinela
?*TOptional pointerPode ser nulo

Exemplo Prático

Single-Item Pointer (*T)

const std = @import("std");

fn incrementar(ptr: *u32) void {
    ptr.* += 1;
}

pub fn main() void {
    var valor: u32 = 10;
    incrementar(&valor);
    std.debug.print("Valor: {}\n", .{valor}); // 11

    // Ponteiro const — somente leitura
    const constante: u32 = 42;
    const ptr: *const u32 = &constante;
    std.debug.print("Lido: {}\n", .{ptr.*}); // 42
}

Many-Item Pointer ([*]T) e Slice ([]T)

const std = @import("std");

pub fn main() void {
    var array = [_]u32{ 10, 20, 30, 40, 50 };

    // Slice: ponteiro + tamanho
    const slice: []u32 = array[1..4]; // [20, 30, 40]
    std.debug.print("Slice len: {}\n", .{slice.len}); // 3

    // Many-item pointer: sem tamanho
    const many: [*]u32 = &array;
    std.debug.print("many[2] = {}\n", .{many[2]}); // 30

    // Converter many-pointer para slice
    const slice2: []u32 = many[0..5];
    std.debug.print("Slice2 len: {}\n", .{slice2.len}); // 5
}

Ponteiros Opcionais (?*T)

const std = @import("std");

const Node = struct {
    valor: i32,
    proximo: ?*Node, // Pode ser nulo
};

fn somar_lista(inicio: ?*Node) i32 {
    var soma: i32 = 0;
    var atual = inicio;
    while (atual) |node| {
        soma += node.valor;
        atual = node.proximo;
    }
    return soma;
}

pub fn main() void {
    var c = Node{ .valor = 3, .proximo = null };
    var b = Node{ .valor = 2, .proximo = &c };
    var a = Node{ .valor = 1, .proximo = &b };

    const total = somar_lista(&a);
    std.debug.print("Soma: {}\n", .{total}); // 6
}

Coerções de Ponteiro

*[N]T  -->  []T         (array pointer para slice)
*[N]T  -->  [*]T        (array pointer para many-pointer)
*T     -->  *const T    (mutável para const)
[]T    -->  []const T   (slice mutável para const)

Armadilhas Comuns

  • Dangling pointer: Retornar ponteiro para variável local causa undefined behavior. Use alocação no heap ou retorne por valor.
  • Confundir *T com []T: *T aponta para um item; []T é um slice com tamanho. Usar o tipo errado causa erros de compilação.
  • Many-pointer sem limites: [*]T não tem .len. Não é possível iterar com for sem primeiro convertê-lo para slice.
  • Ponteiro nulo: *T nunca pode ser nulo. Use ?*T se precisar representar nulidade.
  • Alinhamento: Ponteiros carregam informação de alinhamento. Casts entre tipos com alinhamentos diferentes exigem @alignCast.

Termos Relacionados

  • Slice — Referência com tamanho conhecido
  • Sentinel — Ponteiros e slices terminados por sentinela
  • usize — Tipo usado para tamanho e indexação
  • Dangling Pointer — Ponteiro para memória inválida
  • Stack vs Heap — Onde os dados apontados vivem

Tutoriais Relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.