ざっくりZig - 繰り返し (while, break, continue)
繰り返しというのは、何度も同じ処理を行うということです。とはいえ、毎回全く同じ処理を行うのではなく、1回ごとに変数の値を変えながら処理を行うことが多いです。その方法として、ここではwhileを紹介します。
また、繰り返し処理を途中で中断するbreakや、中断しつつ次の繰り返しを行うcontinueも一緒に紹介します。
whileによる繰り返し
whileは条件式の結果がtrueとなる間は{...}内の処理を繰り返し行うことを表します。
while (条件式) {
    // 繰り返し行う処理
}
1.は変数iの値が5より小さい間(i < 5)はiの値を表示するという処理をwhileで行います。これは繰り返し処理としてはもっとも基本的なものです。
ポイントは{...}の中でiの値がどのように変化していくかです。この処理の場合、{...}の処理が1回行われるごとにiの値は0~4まで1ずつ増加していきます。これは{...}の処理が5回行われたことを意味します。その結果、iは最初に0が代入されていましたが、繰り返しが終了した後のiの値は5になっています。
const std = @import("std");
pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    var i: u8 = 0;
    // 繰り返し処理を行う前のiの値
    try stdout.print("before: i = {}\n\n", .{i});
    // whileによる繰り返し処理
    while (i < 5) {
        try stdout.print("while: i = {}\n", .{i});
        i += 1; // iの値を1増やす
    }
    // 繰り返し処理を行った後のiの値
    try stdout.print("\nafter: i = {}\n", .{i});
}
// 結果
before: i = 0
while: i = 0
while: i = 1
while: i = 2
while: i = 3
while: i = 4
after: i = 5
2.はbreakによりiが1より大きくなった時(2になった時)に繰り返しを中断します。これにより{...}の部分が実行されるのはiの値が0, 1, 2の時までとなります。iの値を1増やす前にbreakが実行されていますので、処理が中断された後もiの値は2のままです。
const std = @import("std");
pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    var i: u8 = 0;
    // 繰り返し処理を行う前のiの値
    try stdout.print("before: i = {}\n\n", .{i});
    // whileによる繰り返し処理
    while (i < 5) {
        try stdout.print("while: i = {}\n", .{i});
        if (i > 1) break; // iの値が1を超えたら中断
        i += 1; // iの値を1増やす
    }
    // 繰り返し処理を行った後のiの値
    try stdout.print("\nafter: i = {}\n", .{i});
}
//結果
before: i = 0
while: i = 0
while: i = 1
while: i = 2    // この後breakにより繰り返しを中断
after: i = 2
3.はiの値が1のとき、その値を3増やして次の繰り返しを行います。continueにより処理を途中で切り上げていますので、その下の i += 1 は実行していません。
const std = @import("std");
pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    var i: u8 = 0;
    // 繰り返し処理を行う前のiの値
    try stdout.print("before: i = {}\n\n", .{i});
    // whileによる繰り返し処理
    while (i < 5) {
        try stdout.print("while: i = {}\n", .{i});
        if (i == 1) {
            i += 3;
            continue; // iの値を3増やして次の繰り返し
        }
        i += 1; // iの値を1増やす (i == 1のときは実行しない)
    }
    // 繰り返し処理を行った後のiの値
    try stdout.print("\nafter: i = {}\n", .{i});
}
// 結果
before: i = 0
while: i = 0
while: i = 1    // このあと i += 3 を実行
while: i = 4
after: i = 5
4.はi += 1の部分を条件の次に: (i += 1)のように書いています。この部分は繰り返し処理の最後に実行されます。結果は1.と同じです。
const std = @import("std");
pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    var i: u8 = 0;
    // 繰り返し処理を行う前のiの値
    try stdout.print("before: i = {}\n\n", .{i});
    // whileによる繰り返し処理
    while (i < 5) : (i += 1) {
        try stdout.print("while: i = {}\n", .{i});
    }
    // 繰り返し処理を行った後のiの値
    try stdout.print("\nafter: i = {}\n", .{i});
}
// 結果
// 1.と同じ
ただ注意したいのは、continueで次の繰り返しを行う際にもこの部分が実行されることです。そのため: (...)で変数の値を変更しているときは、その値がどのように変化するかを確認するようにしましょう。
なお、: (...)では5.のように{...}で囲まれた複数の処理を実行することもできます。
const std = @import("std");
pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    var i: u8 = 0;
    var j: u8 = 1;
    // 繰り返し処理を行う前のiの値
    try stdout.print("before: i = {}\n\n", .{i});
    // whileによる繰り返し処理
    while (i < 5) : ({
        i += 1;
        j += 2;
        try stdout.print("count:  i, j = {}, {}\n", .{ i, j });
    }) {
        try stdout.print("while: i, j = {}, {}\n", .{ i, j });
        if (i == 1) {
            i += 3;
            continue; // iの値を3増やして次の繰り返し
        }
    }
    // 繰り返し処理を行った後のiの値
    try stdout.print("\nafter: i = {}\n", .{i});
}
// 結果
before: i = 0
while: i, j = 0, 1
count: i, j = 1, 3
while: i, j = 1, 3
count: i, j = 5, 5  // continueの後にも実行されている
after: i = 5
まとめ
- 
whileは条件式の結果が
trueの間は{...}の処理を繰り返し実行する - breakにより繰り返し処理を中断したり、continueにより処理を途中で切り上げて次の繰り返しを行うこともできる
 - 条件式の次に
: (i += 1)のような処理を書くこともできる。ただし、continueで次の繰り返し処理を行う際にも実行されるため、変数の値がどう変化するか確認する必要がある - 
: (...)の部分は{...}で囲まれた複数の処理を実行することもできる 
繰り返しの応用 (for, while, else, break, continue, オプション, ラベル) >
< 判断と振り分け (if, switch)
ざっくりZig 一覧
Discussion