# Exercises

### Exercises

This chapter introduced the basic forms of values and declarations: names, constants, variables, integer types, floating-point types, booleans, bytes, inferred types, and explicit casts.

The exercises below are small. Type them by hand. Compile them. Change them. Read the error messages.

1. Write a program that declares a constant named `answer` with value `42` and prints it.

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

pub fn main() void {
    const answer = 42;
    std.debug.print("{d}\n", .{answer});
}
```

2. Write a program that declares a mutable variable named `count`, increments it three times, and prints the result.

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

pub fn main() void {
    var count: i32 = 0;

    count += 1;
    count += 1;
    count += 1;

    std.debug.print("{d}\n", .{count});
}
```

3. Change the previous program so that `count` is declared with `const`. Compile it and read the error.

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

pub fn main() void {
    const count: i32 = 0;

    count += 1;

    std.debug.print("{d}\n", .{count});
}
```

The program is wrong because `count` cannot be assigned after initialization.

4. Declare three integer values: one `i32`, one `u32`, and one `usize`. Print all three.

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

pub fn main() void {
    const a: i32 = -10;
    const b: u32 = 20;
    const c: usize = 30;

    std.debug.print("{d} {d} {d}\n", .{ a, b, c });
}
```

5. Try to assign `256` to a `u8`.

```zig
pub fn main() void {
    const x: u8 = 256;
    _ = x;
}
```

This is an error because `u8` can hold only values from `0` to `255`.

6. Write the same integer in decimal, hexadecimal, binary, and octal.

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

pub fn main() void {
    const a = 255;
    const b = 0xff;
    const c = 0b1111_1111;
    const d = 0o377;

    std.debug.print("{d} {d} {d} {d}\n", .{ a, b, c, d });
}
```

7. Write a program that demonstrates wrapping addition on `u8`.

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

pub fn main() void {
    var x: u8 = 255;
    x +%= 1;

    std.debug.print("{d}\n", .{x});
}
```

The output is:

```text
0
```

8. Write a program that demonstrates saturating addition on `u8`.

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

pub fn main() void {
    var x: u8 = 255;
    x +|= 1;

    std.debug.print("{d}\n", .{x});
}
```

The output is:

```text
255
```

9. Declare two `f64` values and print their average.

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

pub fn main() void {
    const a: f64 = 10.0;
    const b: f64 = 20.0;

    const avg = (a + b) / 2.0;

    std.debug.print("{d}\n", .{avg});
}
```

10. Write a function that returns the average of two `f64` values.

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

fn average(a: f64, b: f64) f64 {
    return (a + b) / 2.0;
}

pub fn main() void {
    std.debug.print("{d}\n", .{average(10.0, 20.0)});
}
```

11. Write a function that tests whether an integer is positive.

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

fn isPositive(n: i32) bool {
    return n > 0;
}

pub fn main() void {
    std.debug.print("{}\n", .{isPositive(3)});
    std.debug.print("{}\n", .{isPositive(-3)});
}
```

12. Write a condition that checks whether a number is between `1` and `10`, inclusive.

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

pub fn main() void {
    const n = 7;

    if (n >= 1 and n <= 10) {
        std.debug.print("in range\n", .{});
    }
}
```

13. Declare a byte with value `'A'` and print it as both a character and a number.

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

pub fn main() void {
    const c: u8 = 'A';

    std.debug.print("{c}\n", .{c});
    std.debug.print("{d}\n", .{c});
}
```

14. Loop over the bytes of a string.

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

pub fn main() void {
    const s = "zig";

    for (s) |b| {
        std.debug.print("{c} {d}\n", .{ b, b });
    }
}
```

15. Check the byte length of a UTF-8 string.

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

pub fn main() void {
    const s = "é";

    std.debug.print("{d}\n", .{s.len});
}
```

The result is `2`, because the string contains two UTF-8 bytes.

16. Create an array whose length is inferred.

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

pub fn main() void {
    const data = [_]u8{ 1, 2, 3, 4 };

    std.debug.print("{d}\n", .{data.len});
}
```

The type of `data` is `[4]u8`.

17. Create a slice of constant bytes.

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

pub fn main() void {
    const name: []const u8 = "zig";

    std.debug.print("{s}\n", .{name});
}
```

18. Convert an `i32` to `f64`.

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

pub fn main() void {
    const n: i32 = 10;
    const x: f64 = @floatFromInt(n);

    std.debug.print("{d}\n", .{x});
}
```

19. Convert a `u32` to `u8`.

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

pub fn main() void {
    const big: u32 = 100;
    const small: u8 = @intCast(big);

    std.debug.print("{d}\n", .{small});
}
```

20. Write a function `square` that takes an `i32` and returns an `i32`.

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

fn square(n: i32) i32 {
    return n * n;
}

pub fn main() void {
    std.debug.print("{d}\n", .{square(12)});
}
```

These exercises are not puzzles. They are meant to build hand memory. Zig rewards precision, and precision begins with small declarations that say exactly what they mean.

