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

OperatorBeschreibung
+Addition
-Subtraktion
*Multiplikation
/Division
%Rest (Modulo-Operation)

Beispiel

const std = @import("std");

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

OperatorBeschreibung
==Gleich
!=Ungleich
>Größer als
<Kleiner als
>=Größer als oder gleich
<=Kleiner als oder gleich

Beispiel

const std = @import("std");

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

OperatorBeschreibung
undLogisches AND
oderLogisches OR
!Logisches NICHT

Beispiel

const std = @import("std");

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

OperatorBeschreibung
&Bitweises AND
|Bitweises OR
^Bitweises XOR
~Bitweises NICHT
<<Linksverschiebung
>>Rechtsverschiebung

Beispiel

const std = @import("std");

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

OperatorBeschreibung
=Zuweisung
+=Additionszuweisung
-=Subtraktionszuweisung
*=Multiplikationszuweisung
/=Divisionszuweisung
%=Restzuweisung
&=Bitweise AND-Zuweisung
|=Bitweise OR-Zuweisung
^=Bitweise XOR-Zuweisung
<<=Linksverschiebungszuweisung
>>=Rechtsverschiebungszuweisung

Beispiel

const std = @import("std");

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

OperatorBeschreibung
++Inkrement
--Dekrement

Beispiel

const std = @import("std");

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:

RangfolgeOperatorBeschreibung
1[]Indexoperation, Array- oder Zeigerzugriff
1.Memberzugriff
2fn_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
14andLogisches AND
15orLogisches OR
16orelseOder sonst einen anderen Wert zurückgeben
17catchFehler 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

const std = @import("std");

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 = false
Andere Erweiterungen