From fd2cec02afa61fe3c3fd9a7f34569bb236dc7a57 Mon Sep 17 00:00:00 2001
From: Dave Gauer <dave@ratfactor.com>
Date: Sat, 6 Mar 2021 21:31:02 -0500
Subject: [PATCH] add ex54 multipointers (for real)

---
 build.zig                      |  4 +++
 exercises/54_multipointers.zig | 53 ++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)
 create mode 100644 exercises/54_multipointers.zig

diff --git a/build.zig b/build.zig
index 8e8a45b..789024b 100644
--- a/build.zig
+++ b/build.zig
@@ -276,6 +276,10 @@ const exercises = [_]Exercise{
         .main_file = "53_slices2.zig",
         .output = "'all your base are belong to us.' 'for great justice.'",
     },
+    .{
+        .main_file = "54_multipointers.zig",
+        .output = "Memory is a resource.",
+    },
 };
 
 /// Check the zig version to make sure it can compile the examples properly.
diff --git a/exercises/54_multipointers.zig b/exercises/54_multipointers.zig
new file mode 100644
index 0000000..b6fb1f7
--- /dev/null
+++ b/exercises/54_multipointers.zig
@@ -0,0 +1,53 @@
+//
+// You can also make pointers to multiple items without using a slice.
+//
+//     var foo: [4]u8 = [4]u8{ 1, 2, 3, 4 };
+//     var foo_slice: []u8 = foo[0..];
+//     var foo_ptr: [*]u8 = &foo;
+//
+// The difference between foo_slice and foo_ptr is that the slice has
+// a known length. The pointer doesn't. It is up to YOU to keep track
+// of the number of u8s foo_ptr points to!
+//
+const std = @import("std");
+
+pub fn main() void {
+    // Take a good look at the type of the zen12 string:
+    const zen12: *const [21]u8 = "Memory is a resource.";
+    // It would also have been valid to coerce this to a slice:
+    //
+    //     const zen12: []const u8 = "...";
+    //
+    // Now let's turn this into a "multi pointer":
+    const zen_multiptr: [*]const u8 = zen12;
+
+    // It's okay to access zen_multiptr just like an array or slice as
+    // long as you keep track of the length yourself!
+    //
+    // A "string" in Zig is a pointer to an array of const u8 values
+    // or a slice of const u8 values, into one, as we saw above). So,
+    // we could treat a "multi pointer" of const u8 a string as long
+    // as we can CONVERT IT TO A SLICE. (Hint: we do know the length!)
+    //
+    // Please fix this line so the print below statement can print it:
+    const zen12_string: []const u8 = zen_multiptr;
+
+    // Here's the moment of truth!
+    std.debug.print("{s}\n", .{zen12_string});
+}
+//
+// Are all of these pointer types starting to get confusing?
+//
+//     FREE ZIG POINTER CHEATSHEET! (Using u8 as the example type.)
+//   +---------------+----------------------------------------------+
+//   |  u8           |  one u8                                      |
+//   |  *u8          |  pointer to one u8                           |
+//   |  [2]u8        |  two u8s                                     |
+//   |  [*]u8        |  pointer to unknown number of u8s            |
+//   |  [2]const u8  |  two immutable u8s                           |
+//   |  [*]const u8  |  pointer to unknown number of immutable u8s  |
+//   |  *[2]u8       |  pointer to an array of 2 u8s                |
+//   |  *const [2]u8 |  pointer to an immutable array of 2 u8s      |
+//   |  []u8         |  slice of u8s                                |
+//   |  []const u8   |  slice of immutable u8s                      |
+//   +---------------+----------------------------------------------+