ざっくり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