This chapter introduced the basic forms of values and declarations: names, constants, variables, integer types, floating-point types, booleans, bytes, inferred types, and...
This chapter introduced the basic forms of values and declarations: names, constants, variables, integer types, floating-point types, booleans, bytes, inferred types, and explicit casts.
The exercises below are small. Type them by hand. Compile them. Change them. Read the error messages.
- Write a program that declares a constant named
answerwith value42and prints it.
const std = @import("std");
pub fn main() void {
const answer = 42;
std.debug.print("{d}\n", .{answer});
}- Write a program that declares a mutable variable named
count, increments it three times, and prints the result.
const std = @import("std");
pub fn main() void {
var count: i32 = 0;
count += 1;
count += 1;
count += 1;
std.debug.print("{d}\n", .{count});
}- Change the previous program so that
countis declared withconst. Compile it and read the error.
const std = @import("std");
pub fn main() void {
const count: i32 = 0;
count += 1;
std.debug.print("{d}\n", .{count});
}The program is wrong because count cannot be assigned after initialization.
- Declare three integer values: one
i32, oneu32, and oneusize. Print all three.
const std = @import("std");
pub fn main() void {
const a: i32 = -10;
const b: u32 = 20;
const c: usize = 30;
std.debug.print("{d} {d} {d}\n", .{ a, b, c });
}- Try to assign
256to au8.
pub fn main() void {
const x: u8 = 256;
_ = x;
}This is an error because u8 can hold only values from 0 to 255.
- Write the same integer in decimal, hexadecimal, binary, and octal.
const std = @import("std");
pub fn main() void {
const a = 255;
const b = 0xff;
const c = 0b1111_1111;
const d = 0o377;
std.debug.print("{d} {d} {d} {d}\n", .{ a, b, c, d });
}- Write a program that demonstrates wrapping addition on
u8.
const std = @import("std");
pub fn main() void {
var x: u8 = 255;
x +%= 1;
std.debug.print("{d}\n", .{x});
}The output is:
0- Write a program that demonstrates saturating addition on
u8.
const std = @import("std");
pub fn main() void {
var x: u8 = 255;
x +|= 1;
std.debug.print("{d}\n", .{x});
}The output is:
255- Declare two
f64values and print their average.
const std = @import("std");
pub fn main() void {
const a: f64 = 10.0;
const b: f64 = 20.0;
const avg = (a + b) / 2.0;
std.debug.print("{d}\n", .{avg});
}- Write a function that returns the average of two
f64values.
const std = @import("std");
fn average(a: f64, b: f64) f64 {
return (a + b) / 2.0;
}
pub fn main() void {
std.debug.print("{d}\n", .{average(10.0, 20.0)});
}- Write a function that tests whether an integer is positive.
const std = @import("std");
fn isPositive(n: i32) bool {
return n > 0;
}
pub fn main() void {
std.debug.print("{}\n", .{isPositive(3)});
std.debug.print("{}\n", .{isPositive(-3)});
}- Write a condition that checks whether a number is between
1and10, inclusive.
const std = @import("std");
pub fn main() void {
const n = 7;
if (n >= 1 and n <= 10) {
std.debug.print("in range\n", .{});
}
}- Declare a byte with value
'A'and print it as both a character and a number.
const std = @import("std");
pub fn main() void {
const c: u8 = 'A';
std.debug.print("{c}\n", .{c});
std.debug.print("{d}\n", .{c});
}- Loop over the bytes of a string.
const std = @import("std");
pub fn main() void {
const s = "zig";
for (s) |b| {
std.debug.print("{c} {d}\n", .{ b, b });
}
}- Check the byte length of a UTF-8 string.
const std = @import("std");
pub fn main() void {
const s = "é";
std.debug.print("{d}\n", .{s.len});
}The result is 2, because the string contains two UTF-8 bytes.
- Create an array whose length is inferred.
const std = @import("std");
pub fn main() void {
const data = [_]u8{ 1, 2, 3, 4 };
std.debug.print("{d}\n", .{data.len});
}The type of data is [4]u8.
- Create a slice of constant bytes.
const std = @import("std");
pub fn main() void {
const name: []const u8 = "zig";
std.debug.print("{s}\n", .{name});
}- Convert an
i32tof64.
const std = @import("std");
pub fn main() void {
const n: i32 = 10;
const x: f64 = @floatFromInt(n);
std.debug.print("{d}\n", .{x});
}- Convert a
u32tou8.
const std = @import("std");
pub fn main() void {
const big: u32 = 100;
const small: u8 = @intCast(big);
std.debug.print("{d}\n", .{small});
}- Write a function
squarethat takes ani32and returns ani32.
const std = @import("std");
fn square(n: i32) i32 {
return n * n;
}
pub fn main() void {
std.debug.print("{d}\n", .{square(12)});
}These exercises are not puzzles. They are meant to build hand memory. Zig rewards precision, and precision begins with small declarations that say exactly what they mean.