Ziglings 笔记 59: 字符与进制的变身
它是字符,也是数字
在完成了复杂的图算法测验后,Ziglings 的第 59 个练习带我们回归基础,通过 051_values.zig(注:练习编号可能因版本而异)来探讨 数值 (Values) 的本质。
在高级语言中,Char 和 Integer 往往是泾渭分明的类型。但在 Zig 这样的系统语言中,它们之间的界限消失了。字符只是数字的另一种表现形式。
挑战:手动转码
我们需要构造字符串 “Zig”,但不能直接使用字符字面量,而是要分别使用八进制、二进制和十六进制来表示它们。
我们需要查阅 ASCII 表:
'Z'= 90'i'= 105'g'= 103
解决方案
这是转换后的代码:
const print = @import("std").debug.print;
pub fn main() void {
const zig = [_]u8{
// 1. 'Z' (90) 转八进制
// 90 / 8 = 11 ... 2
// 11 / 8 = 1 ... 3
// 1 / 8 = 0 ... 1
// 结果: 132
0o132,
// 2. 'i' (105) 转二进制
// 105 = 64 + 32 + 8 + 1
// 结果: 01101001
0b01101001,
// 3. 'g' (103) 转十六进制
// 103 / 16 = 6 ... 7
// 结果: 67
0x67,
};
// 打印结果:Zig is cool.
print("{s} is cool.\n", .{zig});
}
核心知识点总结
1. 进制前缀
Zig 的进制表示法非常标准且易记:
0x: Hexadecimal (16进制)0o: Octal (8进制)0b: Binary (2进制)
2. 这里的 u8 是什么?
代码中定义的是 [_]u8。
虽然我们塞进去的是 0o132 这样看起来很奇怪的数字,但只要它的值在 0-255 之间,它就是一个合法的 u8。
当我们用 {s} 格式化打印这个数组时,Zig 会把这串数字解释为 ASCII 字符并打印出来。
3. 下划线分隔符
虽然在这个练习里没用上,但 Zig 允许 const mask = 0b1111_0000_1010_0011; 这样的写法。在定义位掩码或大数值时,这对可读性的提升是巨大的。
后续预告:我们已经了解了数值。但是,如果我有一个 u8,想把它赋值给 u16 怎么办?或者反过来?下一篇我们将探讨 Zig 中极其严格的类型转换规则 (Type Coercion)。