# Arrays, Slices and Strings — Zig

Source: https://www.geekswithgeeks.com/en/zig/c-arrays

> Use fixed arrays, slices and byte strings safely.

## Arrays know their length; slices carry it

An **array** `[N]T` has a compile-time-known length that is part of its type: `[3]u32`. Literals can infer the length with `[_]u32{ 1, 2, 3 }`, and `**` repeats (`[_]u8{0} ** 16`). Arrays are **values**: assigning one copies it. A **slice** `[]T` (or `[]const T`) is a **pointer plus a length**, created by slicing (`array[1..3]`, `array[2..]`) or from allocations; indexing is **bounds-checked** in safe modes, so out-of-range access panics instead of corrupting memory. **Strings are just bytes**: `[]const u8`, conventionally UTF-8, with no separate string type. String literals are **null-terminated** arrays (`*const [N:0]u8`) that coerce to `[]const u8`; the `:0` is a **sentinel**, useful for C interop (`[:0]const u8`). The **`std.mem`** module provides the operations: `std.mem.eql(u8, a, b)` to compare (never `==` on slices), `indexOf`, `startsWith`, `splitScalar`, `tokenizeScalar`, `trim` and `concat`; `std.fmt.parseInt` parses numbers and `std.unicode` handles code points. Multi-line string literals use `\\` at the start of each line.

## Slices and string handling

Bounds-checked slicing, std.mem helpers and parsing.

```zig
const std = @import("std");

pub fn main() !void {
    var scores = [_]u32{ 72, 91, 58, 84, 66 };
    const top_three: []u32 = scores[0..3];          // pointer + length into the array
    top_three[0] = 75;                              // modifies scores[0]

    var sum: u32 = 0;
    for (scores) |s| sum += s;
    std.debug.print("sum={d} slice len={d} first={d}\n", .{ sum, top_three.len, scores[0] });

    const line = "  o-17, Pune , 120000  ";
    var fields = std.mem.splitScalar(u8, std.mem.trim(u8, line, " "), ',');
    const order_id = std.mem.trim(u8, fields.next().?, " ");
    const city = std.mem.trim(u8, fields.next().?, " ");
    const total = try std.fmt.parseInt(u64, std.mem.trim(u8, fields.next().?, " "), 10);

    std.debug.print("{s} | {s} | {d}\n", .{ order_id, city, total });
    std.debug.print("is Pune? {}\n", .{std.mem.eql(u8, city, "Pune")});   // compare contents, not pointers
    std.debug.print("starts with o-? {}\n", .{std.mem.startsWith(u8, order_id, "o-")});

    const greeting =
        \\Dear customer,
        \\Your order has shipped.
    ;
    std.debug.print("{s}\n", .{greeting});
    // scores[7] would panic: index out of bounds (in Debug and ReleaseSafe)
}
```

## A window onto a shelf

An array is the whole shelf of fixed size. A slice is a window you hold up to part of the shelf: it knows where it starts and how wide it is, and in safe builds the window refuses to look past the shelf's edge.

**Quiz:** How should you compare the contents of two strings in Zig?

- [ ] With ==
- [x] With std.mem.eql(u8, a, b)
- [ ] With strcmp
- [ ] They cannot be compared

*Answer:* With std.mem.eql(u8, a, b). Slices are pointer and length; std.mem.eql compares their bytes.
