Zig Many-Item Pointers
A many-item pointer is a pointer that can index a run of values of one type, like the items of an array. It is written [*]i32 for i32 items, and it does not store a length.
One pointer indexes the whole array
Taking the address of an array gives a pointer that a [*]i32 can hold. Indexing it reads the array items in order.
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
var arr = [_]i32{ 10, 20, 30 };
const p: [*]i32 = &arr;
try out.print("{d} {d} {d}\n", .{ p[0], p[1], p[2] });
}
Writing through it changes the array
The pointer points at the array itself, not at a copy. Assigning p[1] replaces the second array item.
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
var arr = [_]i32{ 1, 2, 3 };
const p: [*]i32 = &arr;
p[1] = 99;
try out.print("{any}\n", .{arr});
}
Slicing a many-item pointer adds a length
The slice p[0..2] covers the first two items. Printing it shows both items, and its len is 2.
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
var arr = [_]i32{ 5, 6, 7, 8 };
const p: [*]i32 = &arr;
const first_two = p[0..2];
try out.print("{any}\n", .{first_two});
try out.print("len = {d}\n", .{first_two.len});
}
Example
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
var scores = [_]i32{ 70, 80, 90, 100 };
const p: [*]i32 = &scores;
p[2] = 95;
const middle = p[1..3];
try out.print("{any}\n", .{middle});
try out.print("{any}\n", .{scores});
}
Key points
- Type: [*]i32 is a many-item pointer to i32 values.
- Getting one: const p: [*]i32 = &arr; points p at the first item of arr.
- Indexing: p[0] reads the first item and p[1] reads the second.
- Writing: p[1] = 99 changes the array item, because p points at the array itself.
- No length: a many-item pointer does not know how many items follow the first.
- Slicing: p[0..2] makes a slice of the first two items, and the slice knows its length.
In this example, p points at the scores array and p[2] = 95 replaces the third score. The slice p[1..3] then covers the two middle items, 80 and the new 95. The last print shows the whole array with the change in place.
Note
a slice carries a length, while a many-item pointer does not.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
An array holds [_]i32{ 4, 8, 15 } and p is a many-item pointer to it. What does p[2] read?