# `while` Loops

### `while` Loops

A `while` loop repeats while a condition is true.

```zig
var i: usize = 0;

while (i < 5) {
    std.debug.print("{d}\n", .{i});
    i += 1;
}
```

The output is:

```text
0
1
2
3
4
```

The condition must be a boolean. Zig does not treat integers as true or false.

This is correct:

```zig
while (i != 0) {
    i -= 1;
}
```

This is wrong:

```zig
while (i) {
    i -= 1;
}
```

The compiler rejects it because `i` is an integer, not a boolean.

A `while` loop may have a continue expression. It runs after each iteration, just before the next condition check.

```zig
var i: usize = 0;

while (i < 5) : (i += 1) {
    std.debug.print("{d}\n", .{i});
}
```

This prints the same numbers as before.

The continue expression is useful when the loop has one regular step.

```zig
var n: usize = 10;

while (n > 0) : (n -= 1) {
    std.debug.print("{d}\n", .{n});
}
```

The condition is checked before the body runs. If it is false at the start, the body does not run.

```zig
var i: usize = 10;

while (i < 5) {
    std.debug.print("never printed\n", .{});
}
```

A `while` loop can be infinite.

```zig
while (true) {
    // repeat forever
}
```

Use `break` to leave a loop.

```zig
var i: usize = 0;

while (true) {
    if (i == 5) break;
    std.debug.print("{d}\n", .{i});
    i += 1;
}
```

Use `continue` to skip to the next iteration.

```zig
var i: usize = 0;

while (i < 10) : (i += 1) {
    if (i % 2 == 0) continue;
    std.debug.print("{d}\n", .{i});
}
```

This prints only odd numbers.

`while` can also be an expression. A loop expression may have an `else` branch. The `else` branch runs when the loop ends normally, not when it ends by `break`.

```zig
var i: usize = 0;

while (i < 3) : (i += 1) {
    std.debug.print("{d}\n", .{i});
} else {
    std.debug.print("done\n", .{});
}
```

The output is:

```text
0
1
2
done
```

If the loop breaks, the `else` branch does not run.

```zig
var i: usize = 0;

while (i < 3) : (i += 1) {
    if (i == 1) break;
    std.debug.print("{d}\n", .{i});
} else {
    std.debug.print("done\n", .{});
}
```

The output is:

```text
0
```

The word `done` is not printed.

A `while` loop can produce a value by breaking with a value.

```zig
var i: usize = 0;

const answer = while (i < 10) : (i += 1) {
    if (i == 7) break i;
} else 0;
```

Here `answer` is `7`.

The `else` value is used if the loop finishes without `break`.

This is useful for searches.

```zig
const data = [_]u8{ 3, 8, 13, 21, 34 };

var i: usize = 0;
const found = while (i < data.len) : (i += 1) {
    if (data[i] == 21) break i;
} else null;
```

The value of `found` is the index of the first match, or `null` if no match is found. Its type is `?usize`.

`while` also has special support for optionals.

```zig
var maybe: ?usize = 3;

while (maybe) |value| {
    std.debug.print("{d}\n", .{value});

    if (value == 0) {
        maybe = null;
    } else {
        maybe = value - 1;
    }
}
```

The loop continues while `maybe` contains a value. Inside the body, the value is captured as `value`.

This prints:

```text
3
2
1
0
```

After `maybe` becomes `null`, the loop stops.

This form is common when repeatedly asking for the next item from an operation that may stop.

```zig
while (next()) |item| {
    use(item);
}
```

A loop should keep its moving parts visible. Put the condition near the top. Put the regular update in the continue expression when there is one. Use `break` for the exceptional exit, not for the ordinary shape of the loop.

Exercise 3-13. Write a `while` loop that prints the numbers from `1` to `10`.

Exercise 3-14. Write a loop that prints only even numbers below `20`.

Exercise 3-15. Write a search loop that finds the first zero in an array.

Exercise 3-16. Change the search loop so it returns `null` when no zero is present.

