const und var
const ist unveränderlich, var veränderlich. Der Compiler meldet ungenutzte Variablen und Variablen, die var sein könnten, aber nie verändert werden, als Fehler.
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
const name = "Mia"; // Typ wird erschlossen
var punkte: i32 = 10; // Typ ausdrücklich
punkte += 5;
const alter: u8 = 17;
var undefiniert: i32 = undefined; // bewusst unbelegt
undefiniert = 7;
try out.print("{s} {d} {d} {d}\n", .{ name, punkte, alter, undefiniert });
const a = 7;
const b = 2;
try out.print("{d} {d} {d} {d}\n", .{ a + b, a - b, a * b, @divTrunc(a, b) });
try out.print("{d} {d} {d}\n", .{ a % b, @mod(-7, 3), @rem(-7, 3) });
try out.print("{d:.3} {d}\n", .{ @as(f64, a) / b, std.math.pow(i32, 2, 10) });
}Mia 15 17 7 9 5 14 3 1 2 -1 3.500 1024
Zahlentypen
| Typ | Beschreibung |
|---|---|
i8 i16 i32 i64 i128 | vorzeichenbehaftete Ganzzahlen |
u8 u16 u32 u64 usize | vorzeichenlose Ganzzahlen (usize = Zeigergröße, für Indizes) |
beliebig: u3, i7, u24 | Zig kennt jede Bitbreite |
f16 f32 f64 f128 | Gleitkomma |
bool, void, noreturn | Wahrheitswert, "nichts", "kehrt nie zurück" |
comptime_int, comptime_float | Literale zur Übersetzungszeit mit beliebiger Größe |
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
const klein: u8 = 255;
const mittel: i32 = -300;
const gross: u64 = 1 << 40;
try out.print("{d} {d} {d}\n", .{ klein, mittel, gross });
try out.print("{d} {d} {d}\n", .{ std.math.maxInt(i32), std.math.minInt(i8), std.math.maxInt(u16) });
// Umwandlungen sind explizit
const x: i32 = 1000;
const als_u8: u8 = @intCast(@mod(x, 256));
const als_f: f64 = @floatFromInt(x);
const zurueck: i32 = @intFromFloat(3.99);
try out.print("{d} {d:.1} {d}\n", .{ als_u8, als_f, zurueck });
try out.print("{d} {d}\n", .{ @as(u16, 40000) +% 40000, @as(i8, 127) +% 1 }); // +% : Überlauf umbrechen
// Überlaufprüfung
const ergebnis = @addWithOverflow(@as(u8, 250), 10);
try out.print("{d} Überlauf={d}\n", .{ ergebnis[0], ergebnis[1] });
// Bit-Operationen
try out.print("{b} {b} {b} {b} {d} {d}\n", .{ 0b1100 & 0b1010, 0b1100 | 0b1010, 0b1100 ^ 0b1010, ~@as(u4, 0b1100), 1 << 5, 256 >> 2 });
try out.print("{d} {d}\n", .{ @clz(@as(u8, 1)), @popCount(@as(u8, 0b10110)) });
}255 -300 1099511627776 2147483647 -128 65535 232 1000.0 3 14464 -128 4 Überlauf=1 1000 1110 110 11 32 64 7 3
Optionale Werte
Statt null-Zeigern gibt es optionale Typen ?T:
const std = @import("std");
fn finde(liste: []const i32, ziel: i32) ?usize {
for (liste, 0..) |wert, i| {
if (wert == ziel) return i;
}
return null;
}
pub fn main() !void {
const out = std.io.getStdOut().writer();
const zahlen = [_]i32{ 5, 8, 13, 21 };
const treffer = finde(&zahlen, 13);
const keiner = finde(&zahlen, 99);
try out.print("{any} {any}\n", .{ treffer, keiner });
if (treffer) |idx| {
try out.print("gefunden an Index {d}\n", .{idx});
} else {
try out.print("nicht gefunden\n", .{});
}
try out.print("{d} {d}\n", .{ keiner orelse 0, treffer.? }); // orelse: Standardwert, .?: auspacken
}2 null gefunden an Index 2 0 2
Verzweigungen und Schleifen
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
const punkte: u8 = 78;
if (punkte >= 90) {
try out.print("sehr gut\n", .{});
} else if (punkte >= 75) {
try out.print("gut\n", .{});
} else {
try out.print("weiter üben\n", .{});
}
const status = if (punkte >= 50) "bestanden" else "durchgefallen"; // if als Ausdruck
try out.print("{s}\n", .{status});
const tag: u8 = 3;
const name = switch (tag) {
1 => "Montag",
2, 3, 4 => "Mitte der Woche",
5...7 => "Ende der Woche",
else => "unbekannt",
};
try out.print("{s}\n", .{name});
var i: u32 = 0;
while (i < 3) : (i += 1) { // Fortsetzungsausdruck nach dem Doppelpunkt
try out.print("i={d} ", .{i});
}
try out.print("\n", .{});
for (0..4) |k| try out.print("{d} ", .{k}); // Bereich
try out.print("\n", .{});
const namen = [_][]const u8{ "Mia", "Tom", "Zoe" };
for (namen, 0..) |n, idx| try out.print("{d}:{s} ", .{ idx, n });
try out.print("\n", .{});
outer: for (0..3) |a| {
for (0..3) |b| {
if (b == 2) continue :outer;
if (a == 2) break :outer;
try out.print("{d}{d} ", .{ a, b });
}
}
try out.print("\n", .{});
var n: u32 = 1;
const ergebnis = while (true) { // while mit Wert über break
n *= 2;
if (n > 100) break n;
};
try out.print("{d}\n", .{ergebnis});
}gut bestanden Mitte der Woche i=0 i=1 i=2 0 1 2 3 0:Mia 1:Tom 2:Zoe 00 01 10 11 128
Merke
const(unveränderlich) undvar; ungenutzte Variablen sind Fehler- Ganzzahltypen mit beliebiger Bitbreite (
u8,i32,u3); keine impliziten verlustbehafteten Umwandlungen - Umwandlung:
@intCast,@floatFromInt,@intFromFloat; Überlauf:+%,@addWithOverflow - Optionale Typen
?Tmitorelse,if (x) |wert|statt Null-Zeigern if,switchundwhilemit Wert;for (liste, 0..) |x, i|
Aufgabe
Schreibe FizzBuzz für 1 bis 30 mit switch oder if.