Ziglings 笔记 17: 挑战 FizzBuzz

编程界的试金石

在学习了基本的控制流(Loop, If, Switch)之后,Ziglings 抛出了第二个综合测验:FizzBuzz

规则很简单:从 1 数到 16,如果是 3 的倍数打印 “Fizz”,如果是 5 的倍数打印 “Buzz”,如果是 3 和 5 的公倍数打印 “FizzBuzz”,否则打印数字本身。

挑战:逻辑的组合

这个练习考察的是如何将 while 循环、if 判断和算术运算结合起来。

解决方案

这是我的 Zig 实现:

const std = @import("std");

pub fn main() void {
    var i: u8 = 1;
    const stop_at: u8 = 16;

    // 使用带步进表达式的 while 循环,模拟 C 风格的 for 循环
    // 逻辑:当 i <= 16 时执行,每次结束后 i 加 1
    while (i <= stop_at) : (i += 1) {
        
        // 技巧:使用独立的 if 语句而不是 if-else
        // 这样当 i=15 时,会依次打印 "Fizz" 和 "Buzz" -> "FizzBuzz"
        if (i % 3 == 0) std.debug.print("Fizz", .{});
        if (i % 5 == 0) std.debug.print("Buzz", .{});
        
        // 如果既不是 3 的倍数也不是 5 的倍数,则打印数字
        // 注意 Zig 使用 'and' 而不是 '&&',使用 '!' 表示非
        if (!(i % 3 == 0) and !(i % 5 == 0)) {
            std.debug.print("{}", .{i});
        }
        
        std.debug.print(", ", .{});
    }
    std.debug.print("\n", .{});
}

核心知识点回顾

1. 循环的最佳实践

虽然 Zig 有 for 循环,但主要用于遍历数组。对于这种纯数字计数的场景,while (cond) : (step) 是最标准(Idiomatic)的写法。它清晰地分离了终止条件和状态更新。

2. 逻辑运算符的文字化

Zig 倾向于让代码更易读:

  • 使用 and 代替 &&
  • 使用 or 代替 || 这减少了符号的视觉干扰,让逻辑表达式读起来像英语句子。

3. 条件的堆叠

解决 FizzBuzz 有很多种写法。这里展示的方法利用了 std.debug.print 不会自动换行的特性,通过堆叠 if 语句,自然而然地拼接出了 “FizzBuzz”,避免了专门为 15 写一个 if (i % 15 == 0) 的判断,逻辑更加精简。


后续预告:顺利通过测验!接下来,我们将进入 Zig 最强大的特性之一:函数(Functions)。我们将学习如何定义函数、传递参数以及处理返回值。