Tableaux et tranches Zig

Dans le langage de programmation Zig, les tableaux et les tranches sont des structures fondamentales pour stocker et manipuler un ensemble de données de même type.

  • Tableau: Utilisé pour stocker un ensemble de données de taille fixe de même type, la taille étant spécifiée au moment de la définition et stockée sur la pile.
  • Tranche: Utilisée pour référencer une partie d'un tableau ou d'une autre région de mémoire contiguë. Sa taille peut être ajustée dynamiquement, ce qui la rend plus flexible, et elle fait généralement référence à la mémoire du tas.

Tableau :

  • Un tableau est une séquence de longueur fixe dont la taille est déterminée au moment de la compilation.
  • Le type d'un tableau est[T], oùTest le type des éléments du tableau.
  • La mémoire des tableaux est contiguë, ce qui leur donne un avantage en termes de performance, en particulier lors du traitement de grandes quantités de données.

Tranche :

  • Une tranche est une séquence de taille dynamique qui permet de modifier sa taille au moment de l'exécution.
  • Le type d'une tranche est[]T, oùTest le type des éléments de la tranche.
  • Une tranche est en fait une référence à un tableau ; elle contient un pointeur vers le tableau et la longueur de la tranche.
  • Les tranches peuvent gérer les données de manière plus flexible car elles peuvent être facilement partagées et transmises entre les tableaux.

Tableau

Les tableaux ont une taille fixe, sont stockés sur la pile, et les types des éléments doivent être identiques.

Vous pouvez utiliser la[]syntaxe pour définir un tableau et spécifier sa taille.

Le type d'un tableau est défini comme[T; N], où T est le type des éléments du tableau et N est la longueur du tableau.

Les éléments d'un tableau sont accessibles par indice, l'indexation commençant à00.

Syntaxe

const arrayName: [size]ElementType = [size]ElementType{element1, element2, ...};

Description du paramètre :

  • arrayName: Le nom du tableau.
  • size: La taille du tableau (nombre d'éléments), qui est une constante à la compilation.
  • ElementType: Le type des éléments du tableau.
  • element1, element2, ...: Les éléments du tableau.

Un tableau est un bloc de mémoire contigu de taille fixe dont la taille est déterminée à la compilation :

var myArray: [10]u8 = [10]u8{0} ** 10; // 定义并初始化一个大小为 10 的 u8 类型数组

Exemple

const std = @import("std");

pub fn main() void {
    // Définir un tableau contenant 5 éléments de type i32
    const arr: [5]i32 = [5]i32{1, 2, 3, 4, 5};

    // Accéder aux éléments du tableau par indice
    std.debug.print("Premier élément : {}\n", .{arr[0]});
    std.debug.print("Troisième élément : {}\n", .{arr[2]});

    // La taille du tableau est fixe
    const size: usize = arr.len;
    std.debug.print("Taille du tableau : {}\n", .{size});
}

La sortie de compilation est :

First element: 1
Third element: 3
Array size: 5

Itération sur un tableau

Vous pouvez utiliser une boucleforpour parcourir les éléments d'un tableau.

Exemple

const std = @import("std");

pub fn main() void {
    const arr: [5]i32 = [5]i32{ 1, 2, 3, 4, 5 };

    var index: usize = 0;

    // Parcourir le tableau
    for (arr) |item| {
        std.debug.print("Index : {}, Élément : {}\n", .{ index, item });
        index += 1;
    }
}

La sortie de compilation est :

Index: 0, Item: 1
Index: 1, Item: 2
Index: 2, Item: 3
Index: 3, Item: 4
Index: 4, Item: 5

Tranche

Une slice est une référence à une portion d'un tableau ou d'une autre région de mémoire contiguë.

Une slice peut ajuster dynamiquement sa taille et est plus flexible qu'un tableau, mais ses éléments sont stockés sur le tas.

Définition et initialisation

Une slice est une référence à une portion d'un tableau ou d'une autre région de mémoire contiguë.

Une slice est dynamique et peut changer de taille ; elle est souvent utilisée pour représenter une portion d'un tableau ou un bloc de mémoire alloué dynamiquement.

Syntaxe

const sliceName: []ElementType = array[start..end];

Description du paramètre :

  • sliceName: Le nom de la slice.
  • ElementType: Le type des éléments de la tranche.
  • array[start..end]: Dearrayextraire une sous-tranche,startetendest l'indice.

Une tranche peut être créée à partir d'un sous-ensemble d'un tableau, ou elle peut être créée à partir d'un pointeur et d'une longueur :

var myArray: [10]u8 = ...; // 假设已经初始化
var mySlice = myArray[2..7]; // 创建一个切片,包含索引2到6的元素

// 或者使用指针和长度
var mySlicePtr = myArray[2..]; // 创建一个切片,从索引2开始到数组末尾

Les tranches fournissent des méthodes intégrées pour manipuler les tranches, par exemple :

  • len: Obtient la longueur de la tranche.
  • ptr: Obtient le pointeur de la tranche.
  • capacity: Obtient la capacité de la tranche, c'est-à-dire la longueur maximale de la partie du tableau qu'elle peut référencer.

Exemple

const std = @import("std");

pub fn main() void {
    var arr: [5]i32 = [5]i32{ 1, 2, 3, 4, 5 };

    // Créer une tranche à partir d'un tableau
    const slice: []i32 = arr[1..4];

    // Accéder aux éléments d'une tranche par indice
    std.debug.print("Premier élément de la tranche : {}\n", .{slice[0]});
    std.debug.print("Deuxième élément de la tranche : {}\n", .{slice[1]});

    // La longueur de la tranche
    const length: usize = slice.len;
    std.debug.print("Longueur de la tranche : {}\n", .{length});
}

La sortie de compilation est :

First element of slice: 2
Second element of slice: 3
Slice length: 3

Itération sur une tranche

Comme pour les tableaux, vous pouvez utiliser une boucleforpour parcourir la tranche.

Exemple

const std = @import("std");

pub fn main() void {
    var arr: [5]i32 = [5]i32{ 1, 2, 3, 4, 5 };
    const slice: []i32 = arr[1..4];
    var index: usize = 1;

    // Parcourir la tranche
    for (slice) |item| {
        std.debug.print("Index : {}, Élément : {}\n", .{ index, item });
        index += 1;
    }
}

La sortie de compilation est :

Index: 1, Item: 2
Index: 2, Item: 3
Index: 3, Item: 4

Différences entre les tableaux et les tranches

  • Taille: La taille d'un tableau est fixe et déterminée lors de la définition ; la taille d'une tranche peut être ajustée dynamiquement.
  • Emplacement de stockage: Les tableaux sont généralement stockés sur la pile, tandis que la mémoire référencée par un slice peut se trouver sur le tas.
  • Flexibilité: Les slices sont plus flexibles et peuvent référencer une partie d'un tableau ou une mémoire allouée dynamiquement.
FonctionnalitéTableauTranche
SizeFixe, déterminé à la compilationDynamique, la taille peut être modifiée
Type d'élémentIdentiqueIdentique
Emplacement mémoireGénéralement sur la pile (variables locales)La mémoire référencée peut être sur le tas ou sur la pile
AccessPar indexPar les indices de début et de fin du slice
CréationDéfinition directeCréé à partir d'un tableau ou d'un autre slice

Dans l'exemple suivant, la fonction printArray prend un tableau de taille fixe comme paramètre, tandis que la fonction printSlice prend un slice comme paramètre. Grâce à ces fonctions, vous pouvez voir les différences entre les tableaux et les slices en matière de passage et d'utilisation.

Exemple

const std = @import("std");

fn printArray(arr: [5]i32) void {
    for (arr) |item| {
        std.debug.print("Array item: {}\n", .{item});
    }
}

fn printSlice(slice: []const i32) void {
    for (slice) |item| {
        std.debug.print("Slice item: {}\n", .{item});
    }
}

pub fn main() void {
    const arr: [5]i32 = [5]i32{ 1, 2, 3, 4, 5 };
    const slice: []const i32 = arr[1..4];

    printArray(arr);
    printSlice(slice);
}

La sortie de compilation est :

Array item: 1
Array item: 2
Array item: 3
Array item: 4
Array item: 5
Slice item: 2
Slice item: 3
Slice item: 4
Autres extensions