Zig-Operatoren
Operatoren und Ausdrücke sind grundlegende Komponenten in Programmiersprachen, die verwendet werden, um verschiedene Operationen auszuführen.
In Zig können Operatoren in mehrere Kategorien unterteilt werden, darunter arithmetische Operatoren, relationale Operatoren, logische Operatoren, bitweise Operatoren, Zuweisungsoperatoren und andere Operatoren.
Im Folgenden finden Sie detaillierte Beschreibungen und Beispiele für jeden Typ von Operator.
Arithmetische Operatoren
| Operator | Beschreibung |
|---|---|
| + | Addition |
| - | Subtraktion |
| * | Multiplikation |
| / | Division |
| % | Rest (Modulo-Operation) |
Beispiel
pub fn main() void {
const a: i32 = 5;
const b: i32 = 3;
const add: i32 = a + b;
const subtract: i32 = a - b;
const multiply: i32 = a * b;
const divide: i32 = a / b;
const remainder: i32 = a % b;
std.debug.print("a + b = {}\n", .{add});
std.debug.print("a - b = {}\n", .{subtract});
std.debug.print("a * b = {}\n", .{multiply});
std.debug.print("a / b = {}\n", .{divide});
std.debug.print("a % b = {}\n", .{remainder});
}
Die kompilierte Ausgabe ist:
a + b = 8 a - b = 2 a * b = 15 a / b = 1 a % b = 2
Relationale Operatoren
| Operator | Beschreibung |
|---|---|
| == | Gleich |
| != | Ungleich |
| > | Größer als |
| < | Kleiner als |
| >= | Größer als oder gleich |
| <= | Kleiner als oder gleich |
Beispiel
pub fn main() void {
const a: i32 = 5;
const b: i32 = 3;
const equal: bool = a == b;
const not_equal: bool = a != b;
const greater: bool = a > b;
const less: bool = a < b;
const greater_equal: bool = a >= b;
const less_equal: bool = a <= b;
std.debug.print("a == b: {}\n", .{equal});
std.debug.print("a != b: {}\n", .{not_equal});
std.debug.print("a > b: {}\n", .{greater});
std.debug.print("a < b: {}\n", .{less});
std.debug.print("a >= b: {}\n", .{greater_equal});
std.debug.print("a <= b: {}\n", .{less_equal});
}
Die kompilierte Ausgabe ist:
a == b: false a != b: true a > b: true a < b: false a >= b: true a <= b: false
Logische Operatoren
| Operator | Beschreibung |
|---|---|
| und | Logisches AND |
| oder | Logisches OR |
| ! | Logisches NICHT |
Beispiel
pub fn main() void {
const a: bool = true;
const b: bool = false;
const and_result: bool = a and b;
const or_result: bool = a or b;
const not_result: bool = !a;
std.debug.print("a und b: {}\n", .{and_result}); // false
std.debug.print("a oder b: {}\n", .{or_result}); // true
std.debug.print("!a: {}\n", .{not_result}); // false
}
Die kompilierte Ausgabe ist:
a and b: false a or b: true !a: false
Bitweise Operatoren
| Operator | Beschreibung |
|---|---|
| & | Bitweises AND |
| | | Bitweises OR |
| ^ | Bitweises XOR |
| ~ | Bitweises NICHT |
| << | Linksverschiebung |
| >> | Rechtsverschiebung |
Beispiel
pub fn main() void {
const a: i32 = 5; // 0101
const b: i32 = 3; // 0011
const bit_and: i32 = a & b; // 0001
const bit_or: i32 = a | b; // 0111
const bit_xor: i32 = a ^ b; // 0110
const bit_not: i32 = ~a; // 11111111111111111111111111111010
const left_shift: i32 = a << 1; // 1010
const right_shift: i32 = a >> 1; // 0010
std.debug.print("a & b: {}\n", .{bit_and});
std.debug.print("a | b: {}\n", .{bit_or});
std.debug.print("a ^ b: {}\n", .{bit_xor});
std.debug.print("~a: {}\n", .{bit_not});
std.debug.print("a << 1: {}\n", .{left_shift});
std.debug.print("a >> 1: {}\n", .{right_shift});
}
Die kompilierte Ausgabe ist:
a & b: 1 a | b: 7 a ^ b: 6 ~a: -6 a << 1: 10 a >> 1: 2
Zuweisungsoperatoren
| Operator | Beschreibung |
|---|---|
| = | Zuweisung |
| += | Additionszuweisung |
| -= | Subtraktionszuweisung |
| *= | Multiplikationszuweisung |
| /= | Divisionszuweisung |
| %= | Restzuweisung |
| &= | Bitweise AND-Zuweisung |
| |= | Bitweise OR-Zuweisung |
| ^= | Bitweise XOR-Zuweisung |
| <<= | Linksverschiebungszuweisung |
| >>= | Rechtsverschiebungszuweisung |
Beispiel
pub fn main() void {
var a: i32 = 5;
const b: i32 = 3;
a += b; // entspricht a = a + b;
std.debug.print("a += b: {}\n", .{a});
a -= b; // entspricht a = a - b;
std.debug.print("a -= b: {}\n", .{a});
a *= b; // entspricht a = a * b;
std.debug.print("a *= b: {}\n", .{a});
a = @divTrunc(a, b); // entspricht a = a / b;
std.debug.print("a /= b: {}\n", .{a});
a = @mod(a, b); // entspricht a = a % b;
std.debug.print("a %= b: {}\n", .{a});
a &= b; // entspricht a = a & b;
std.debug.print("a &= b: {}\n", .{a});
a |= b; // entspricht a = a | b;
std.debug.print("a |= b: {}\n", .{a});
a ^= b; // entspricht a = a ^ b;
std.debug.print("a ^= b: {}\n", .{a});
a <<= 1; // entspricht a = a << 1;
std.debug.print("a <<= 1: {}\n", .{a});
a >>= 1; // entspricht a = a >> 1;
std.debug.print("a >>= 1: {}\n", .{a});
}
Die kompilierte Ausgabe ist:
a += b: 8 a -= b: 5 a *= b: 15 a /= b: 5 a %= b: 2 a &= b: 2 a |= b: 3 a ^= b: 0 a <<= 1: 0 a >>= 1: 0
Weitere Operatoren
| Operator | Beschreibung |
|---|---|
| ++ | Inkrement |
| -- | Dekrement |
Beispiel
pub fn main() void {
var a: i32 = 5;
a += 1; // Zig hat keinen ++-Operator, verwende stattdessen += 1
std.debug.print("a += 1: {}\n", .{a});
a -= 1; // Zig hat keinen --Operator, verwende stattdessen -= 1
std.debug.print("a -= 1: {}\n", .{a});
}
Die kompilierte Ausgabe ist:
a += 1: 6 a -= 1: 5
Operatorrangfolge
Das Folgende ist eine Liste der Operatorpriorität von Zig, angeordnet von der höchsten zur niedrigsten:
| Rangfolge | Operator | Beschreibung |
|---|---|---|
| 1 | [] | Indexoperation, Array- oder Zeigerzugriff |
| 1 | . | Memberzugriff |
| 2 | fn_call() | Funktionsaufruf |
| 2 | @builtin() | Aufruf einer eingebauten Funktion |
| 3 | ! | Fehlerfortpflanzung |
| 3 | ? | Entpacken optionaler Werte |
| 4 | * & | Zeigerdereferenzierung und Adressoperationen |
| 5 | + - | Unäres Plus und Minus |
| 6 | ~ | Bitweises NICHT |
| 7 | * / % | Multiplikation, Division, Rest |
| 8 | + - | Addition, Subtraktion |
| 9 | << >> | Bitweise Linksverschiebung, Rechtsverschiebung |
| 10 | & | Bitweises AND |
| 11 | ^ | Bitweises XOR |
| 12 | ` | ` |
| 13 | == != | Gleich, ungleich |
| 13 | < <= > >= | Kleiner als, kleiner oder gleich, größer als, größer oder gleich |
| 14 | and | Logisches AND |
| 15 | or | Logisches OR |
| 16 | orelse | Oder sonst einen anderen Wert zurückgeben |
| 17 | catch | Fehler abfangen |
| 18 | = | Zuweisung |
| 19 | -> | Funktionskörper einer Closure oder Typindikator für den Rückgabewert |
Notizen:
- Assoziativität: Normalerweise sind Zig-Operatoren linksassoziativ, aber je nach der spezifischen Funktion des Operators kann man die Dokumentation zu Rate ziehen.
- Hinweise: Die Operatoren in Zig sind einfach und klar gestaltet und vermeiden komplexe implizite Verhaltensweisen, die in vielen Sprachen vorkommen, wie etwa keine implizite Typkonvertierung.
Das folgende Beispiel zeigt, wie die Operatorpriorität die Auswertungsreihenfolge von Ausdrücken beeinflusst:
Beispiel
pub fn main() void {
const a: i32 = 5;
const b: i32 = 3;
const c: i32 = 2;
// Multiplikation hat eine höhere Priorität als Addition
const result1: i32 = a + b * c; // 5 + (3 * 2) = 11
std.debug.print("a + b * c = {}\n", .{result1});
// Verwenden Sie Klammern, um die Priorität zu ändern
const result2: i32 = (a + b) * c; // (5 + 3) * 2 = 16
std.debug.print("(a + b) * c = {}\n", .{result2});
// Vergleichsoperatoren haben eine höhere Priorität als logische Operatoren
const result3: bool = a > b and b > c; // (5 > 3) and (3 > 2) = true
std.debug.print("a > b and b > c = {}\n", .{result3});
// Das logische NICHT hat eine höhere Priorität als das logische UND
const result4: bool = !(a > b) and b > c; // !(5 > 3) and (3 > 2) = false
std.debug.print("!(a > b) and b > c = {}\n", .{result4});
}
Die kompilierte Ausgabe ist:
a + b * c = 11 (a + b) * c = 16 a > b and b > c = true !(a > b) and b > c = falseAndere Erweiterungen