Array Estático em Zig — Implementação Completa

Array Estático em Zig — Implementação Completa

O array estático é a estrutura de dados mais fundamental: uma sequência contígua de elementos com tamanho definido em tempo de compilação. Em Zig, arrays estáticos são cidadãos de primeira classe com excelente suporte da linguagem.

Conceito

Um array estático armazena N elementos do mesmo tipo em posições contíguas de memória. O tamanho é imutável após a criação.

Visualização

Array: [5]i32 = {10, 20, 30, 40, 50}

Memória:
  Índice:   0     1     2     3     4
          +-----+-----+-----+-----+-----+
  Valor:  | 10  | 20  | 30  | 40  | 50  |
          +-----+-----+-----+-----+-----+
  Endereço: 0x00  0x04  0x08  0x0C  0x10

Acesso direto: arr[2] = 30  → O(1)

Slice (referência a subseção):
  arr[1..4] → {20, 30, 40}  (não copia!)

Implementação em Zig

const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    // ==================== Criação ====================

    // Array com valores explícitos
    const numeros = [5]i32{ 10, 20, 30, 40, 50 };

    // Array com inferência de tamanho
    const letras = [_]u8{ 'Z', 'i', 'g' };

    // Array inicializado com valor padrão
    var zeros: [10]i32 = .{0} ** 10;

    // Array inicializado com sentinela
    const preenchido: [5]u8 = .{0xFF} ** 5;

    // Array em comptime
    const quadrados = comptime blk: {
        var arr: [10]i32 = undefined;
        for (0..10) |i| {
            arr[i] = @intCast(i * i);
        }
        break :blk arr;
    };

    // ==================== Acesso ====================

    try stdout.print("numeros[2] = {d}\n", .{numeros[2]});
    try stdout.print("letras = {s}\n", .{&letras});
    try stdout.print("quadrados = ", .{});
    for (quadrados) |q| try stdout.print("{d} ", .{q});
    try stdout.print("\n", .{});

    // ==================== Slicing ====================

    const slice = numeros[1..4]; // {20, 30, 40}
    try stdout.print("numeros[1..4] = ", .{});
    for (slice) |s| try stdout.print("{d} ", .{s});
    try stdout.print("\n", .{});

    // ==================== Iteração ====================

    // Com valor
    for (numeros) |n| {
        _ = n;
    }

    // Com índice
    for (numeros, 0..) |n, i| {
        try stdout.print("numeros[{d}] = {d}\n", .{ i, n });
    }

    // ==================== Modificação ====================

    zeros[3] = 42;
    try stdout.print("zeros[3] = {d}\n", .{zeros[3]});

    // ==================== Comparação ====================

    const a = [_]i32{ 1, 2, 3 };
    const b = [_]i32{ 1, 2, 3 };
    const c = [_]i32{ 1, 2, 4 };
    try stdout.print("a == b? {}\n", .{std.mem.eql(i32, &a, &b)});
    try stdout.print("a == c? {}\n", .{std.mem.eql(i32, &a, &c)});

    // ==================== Funções com arrays ====================

    const soma = somarArray(&numeros);
    try stdout.print("Soma: {d}\n", .{soma});

    const encontrado = buscarLinear(&numeros, 30);
    try stdout.print("30 no índice: {?d}\n", .{encontrado});

    _ = preenchido;
}

/// Soma todos os elementos.
fn somarArray(arr: []const i32) i64 {
    var soma: i64 = 0;
    for (arr) |n| soma += n;
    return soma;
}

/// Busca linear retornando o índice.
fn buscarLinear(arr: []const i32, alvo: i32) ?usize {
    for (arr, 0..) |n, i| {
        if (n == alvo) return i;
    }
    return null;
}

/// Array genérico em comptime com transformação.
fn mapear(comptime T: type, comptime n: usize, arr: [n]T, comptime f: fn (T) T) [n]T {
    var resultado: [n]T = undefined;
    for (arr, 0..) |val, i| {
        resultado[i] = f(val);
    }
    return resultado;
}

Análise de Complexidade

OperaçãoTempoEspaço
Acesso por índiceO(1)-
BuscaO(n)O(1)
ModificaçãoO(1)-
IteraçãoO(n)O(1)
SliceO(1)O(1) — referência

Características em Zig

  • Tamanho em comptime: o compilador conhece o tamanho
  • Sem overhead: nenhum custo extra comparado a C
  • Bounds checking: verificação de limites em modo debug
  • Coerção para slice: arrays se convertem automaticamente em slices

Quando Usar

  • Tamanho conhecido em tempo de compilação
  • Dados que não mudam de tamanho
  • Buffers de tamanho fixo (parsing, I/O)
  • Tabelas de lookup pré-computadas

Recursos Relacionados

Continue aprendendo Zig

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