---
title: "Pointer Types em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/pointer-types-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/pointer-types-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda os tipos de ponteiro em Zig: *T, [*]T, []T e suas variantes. Segurança de memória sem garbage collector. Guia completo pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# Pointer Types em Zig — O que é e Como Usar

Entenda os tipos de ponteiro em Zig: *T, [*]T, []T e suas variantes. Segurança de memória sem garbage collector. Guia completo pt-BR.


# 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

| Tipo | Nome | Descrição |
|------|------|-----------|
| `*T` | Single-item pointer | Aponta para exatamente um valor |
| `*const T` | Const pointer | Ponteiro somente leitura para um valor |
| `[*]T` | Many-item pointer | Aponta para vários itens (sem tamanho conhecido) |
| `[]T` | Slice | Ponteiro + comprimento (tamanho conhecido) |
| `[*:0]T` | Sentinel-terminated pointer | Muitos itens terminados por sentinela |
| `?*T` | Optional pointer | Pode ser nulo |

## Exemplo Prático

### Single-Item Pointer (*T)

```zig
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)

```zig
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)

```zig
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)
```

## Sentinel-Terminated Pointer ([*:0]T)

O tipo `[*:0]u8` é o equivalente de `char*` em C — um ponteiro para bytes terminados por zero (null-terminated string). Zig usa este tipo para interoperabilidade com APIs C. Na prática, ao chamar funções C que retornam `char*`, Zig representa o tipo como `[*:0]u8`. Use `std.mem.span(ptr)` para converter para `[]u8` de forma segura ao encontrar o terminador.

## Comparação com Ponteiros em C

| Recurso | C `T*` | Zig `*T` | Zig `[]T` | Zig `[*]T` |
|---------|---------|----------|-----------|------------|
| Tamanho conhecido | Não | 1 elemento | Sim (.len) | Não |
| Pode ser nulo | Sim | Não (`?*T`) | Não | Não |
| Aritmética | Sim | Não | Via slicing | Sim |
| Verificação bounds | Não | Não | Debug | Não |
| Null-terminated | Convencional | Não | Não | `[*:0]T` |

Zig separa o que C trata como um único conceito em tipos distintos, tornando a intenção do código explícita e verificável pelo compilador.

## Boas Práticas

- **Prefira `[]T` (slice) sobre `[*]T`**: Slices carregam o tamanho e permitem iteração segura com `for`. Use `[*]T` apenas para interop com C ou performance extrema onde o tamanho é gerenciado externamente.
- **Use `?*T` para representar nulidade**: Nunca use `0` ou `@intToPtr` como substituto de null. O tipo `?*T` comunica a intenção e força verificação explícita.
- **Converta `[*:0]u8` com `std.mem.span`**: Para trabalhar com strings vindas de APIs C, `std.mem.span(ptr)` converte para `[]u8` de forma segura ao encontrar o terminador.

## 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](/glossario/slice/) — Referência com tamanho conhecido
- [Sentinel](/glossario/sentinel/) — Ponteiros e slices terminados por sentinela
- [usize](/glossario/usize/) — Tipo usado para tamanho e indexação
- [Dangling Pointer](/glossario/dangling-pointer/) — Ponteiro para memória inválida
- [Stack vs Heap](/glossario/stack-vs-heap/) — Onde os dados apontados vivem

## Tutoriais Relacionados

- [Ponteiros em Zig](/tutoriais/ponteiros-zig/)
- [Gerenciamento de Memória em Zig](/tutoriais/gerenciamento-de-memoria-zig/)
- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
