# Exercises

### Exercises

These exercises close the chapter on structs, enums, and unions. They are meant to make the data model concrete.

#### Exercise 7-29

Define a struct named `Point` with two fields:

```zig
x: i32
y: i32
```

Create a value with `x = 3` and `y = 4`, then print both fields.

#### Exercise 7-30

Add a method named `move` to `Point`.

It should take a pointer to `Point` and two numbers, `dx` and `dy`. It should add `dx` to `x` and `dy` to `y`.

Expected use:

```zig
var p = Point{
    .x = 3,
    .y = 4,
};

p.move(10, -2);
```

After the call, `p.x` should be `13` and `p.y` should be `2`.

#### Exercise 7-31

Define a struct named `Rectangle`.

```zig
const Rectangle = struct {
    width: u32,
    height: u32,

    // add area here
};
```

Add a method named `area` that returns `width * height`.

#### Exercise 7-32

Define an enum named `Direction`.

It should have four values:

```zig
north
south
east
west
```

Write a function:

```zig
fn isVertical(d: Direction) bool
```

It should return `true` for `north` and `south`, and `false` for `east` and `west`.

#### Exercise 7-33

Define an enum named `LogLevel`.

```zig
const LogLevel = enum {
    debug,
    info,
    warn,
    err,
};
```

Write a function:

```zig
fn levelName(level: LogLevel) []const u8
```

It should return `"debug"`, `"info"`, `"warn"`, or `"err"`.

Use a `switch`.

#### Exercise 7-34

Define a tagged union named `Value`.

It should have these variants:

```zig
integer: i64
boolean: bool
text: []const u8
```

Create one value of each variant.

Write a function:

```zig
fn printValue(value: Value) void
```

It should switch on the value and print the payload.

#### Exercise 7-35

Define a tagged union named `Shape`.

It should have two variants:

```zig
circle: Circle
rectangle: Rectangle
```

where:

```zig
const Circle = struct {
    radius: f64,
};

const Rectangle = struct {
    width: f64,
    height: f64,
};
```

Write a function:

```zig
fn area(shape: Shape) f64
```

For a circle, return `3.141592653589793 * radius * radius`.

For a rectangle, return `width * height`.

#### Exercise 7-36

Define a packed struct named `Permissions`.

It should contain three boolean fields:

```zig
read: bool
write: bool
execute: bool
```

Create this value:

```zig
const p = Permissions{
    .read = true,
    .write = false,
    .execute = true,
};
```

Print each field.

#### Exercise 7-37

Define a packed struct named `ByteParts`.

It should contain:

```zig
low: u4
high: u4
```

Convert a `u8` value to `ByteParts` with `@bitCast`, then print `low` and `high`.

Example input:

```zig
const raw: u8 = 0xab;
```

#### Exercise 7-38

Use `@sizeOf` and `@alignOf` on these types:

```zig
u8
u16
u32
u64
```

Print the result for each type.

Then define this struct:

```zig
const Example = struct {
    a: u8,
    b: u32,
};
```

Print its size and alignment.

#### Exercise 7-39

Change the order of the fields:

```zig
const Example = struct {
    b: u32,
    a: u8,
};
```

Print its size and alignment again. Compare the result.

#### Exercise 7-40

Write three versions of a small data type:

```zig
const Normal = struct {
    a: u8,
    b: u32,
};

const External = extern struct {
    a: u8,
    b: u32,
};

const Packed = packed struct {
    a: u8,
    b: u32,
};
```

Print the size and alignment of each.

Explain in a comment when each form should be used.

