Manipulation des tableaux avec GLib

Pour compiler un programme utilisant GLib, la commande suivante peut être employée : gcc -g -Wall -O0 programme.c -o programme pkg-config --libs --cflags glib-2.0``

Opérations fondamentales

L'exemple suivant illustre l'ajout et la suppression d'éléments dans un tableau GLib.

#include <glib.h>
#include <stdio.h>

int main(int argc, char** argv) {
    GArray* tableau = g_array_new(FALSE, FALSE, sizeof(char*));
    char* premier = "bonjour", *second = "comment", *troisieme = "allez";
    g_array_append_val(tableau, premier);
    g_array_append_val(tableau, second);
    g_array_append_val(tableau, troisieme);
    printf("Le tableau contient maintenant %d elements\n", tableau->len);
    printf("Le premier element est '%s'\n", g_array_index(tableau, char*, 0));
    printf("Le troisieme element est '%s'\n", g_array_index(tableau, char*, 2));
    g_array_remove_index(tableau, 1);
    printf("Le tableau contient maintenant %d elements\n", tableau->len);
    g_array_free(tableau, FALSE);
    return 0;
}

Résultat :


Le tableau contient maintenant 3 elements
Le premier element est 'bonjour'
Le troisieme element est 'allez'
Le tableau contient maintenant 2 elements

Variantes de création et destruction

Différentes méthodes existent pour instancier et libérer un GArray.

#include <glib.h>
#include <stdio.h>

int main(int argc, char** argv) {
    // Pré-allocation avec initialisation à zéro
    GArray* bloc = g_array_sized_new(TRUE, TRUE, sizeof(int), 16);
    printf("La longueur initiale est cachée, elle vaut %d\n", bloc->len);
    printf("Le troisieme element initialise est %d\n", g_array_index(bloc, int, 2));
    g_array_free(bloc, FALSE);

    // Création puis redimensionnement
    bloc = g_array_new(FALSE, FALSE, sizeof(int));
    g_array_set_size(bloc, 20);
    g_array_free(bloc, FALSE);

    // Avec une chaîne dupliquée
    bloc = g_array_new(FALSE, FALSE, sizeof(char*));
    char* texte = g_strdup("exemple");
    g_array_append_val(bloc, texte);
    g_array_free(bloc, TRUE);
    return 0;
}

Ajouts multiples

Au-delà de g_array_append_val, plusieurs fonctions permettent d'insérer des données.

#include <glib.h>
#include <stdio.h>

void afficher_tableau(GArray* t) {
    printf("Contenu : ");
    for (int i = 0; i < t->len; i++)
        printf("%d ", g_array_index(t, int, i));
    printf("\n");
}

int main(int argc, char** argv) {
    GArray* nombres = g_array_new(FALSE, FALSE, sizeof(int));
    int debut[2] = {10, 20};
    g_array_append_vals(nombres, debut, 2);
    afficher_tableau(nombres);

    int milieu[2] = {30, 40};
    g_array_prepend_vals(nombres, milieu, 2);
    afficher_tableau(nombres);

    int fin = 50;
    g_array_prepend_val(nombres, fin);
    afficher_tableau(nombres);
    g_array_free(nombres, FALSE);
    return 0;
}

Insertion à une position précise

Il est possible d'insérer un ou plusieurs éléments à n'importe quel index.

#include <glib.h>
#include <stdio.h>

void afficher(GArray* t) {
    printf("Tableau : ");
    for (int j = 0; j < t->len; j++)
        printf("%d ", g_array_index(t, int, j));
    printf("\n");
}

int main(int argc, char** argv) {
    GArray* sequence = g_array_new(FALSE, FALSE, sizeof(int));
    int init[2] = {5, 8};
    g_array_append_vals(sequence, init, 2);
    afficher(sequence);

    int valeur_unique = 6;
    g_array_insert_val(sequence, 1, valeur_unique);
    afficher(sequence);

    int bloc[2] = {7, 8};
    g_array_insert_vals(sequence, 2, bloc, 2);
    afficher(sequence);
    g_array_free(sequence, FALSE);
    return 0;
}

Suppression d'éléments

Trois méthodes sont offertes pour retirer des éléments.

#include <glib.h>
#include <stdio.h>

void afficher_contenu(GArray* t) {
    printf("Contenu : ");
    for (int k = 0; k < t->len; k++)
        printf("%d ", g_array_index(t, int, k));
    printf("\n");
}

int main(int argc, char** argv) {
    GArray* ensemble = g_array_new(FALSE, FALSE, sizeof(int));
    int donnees[6] = {1, 2, 3, 4, 5, 6};
    g_array_append_vals(ensemble, donnees, 6);
    afficher_contenu(ensemble);

    g_array_remove_index(ensemble, 0);
    afficher_contenu(ensemble);

    g_array_remove_range(ensemble, 0, 2);
    afficher_contenu(ensemble);

    g_array_remove_index_fast(ensemble, 0);
    afficher_contenu(ensemble);
    g_array_free(ensemble, FALSE);
    return 0;
}

Note : g_array_remove_index_fast ne garantit pas le maintien de l'ordre initial.

Tri du tableau

Le tri s'effectue via une fonction de comparaison GCompareFunc.

#include <glib.h>
#include <stdio.h>

void afficher_liste(GArray* t) {
    printf("Liste : ");
    for (int m = 0; m < t->len; m++)
        printf("%d ", g_array_index(t, int, m));
    printf("\n");
}

gpointer comparer(gconstpointer a, gconstpointer b) {
    const int* x = a;
    const int* y = b;
    return GINT_TO_POINTER(*x - *y);
}

int main(int argc, char** argv) {
    GArray* liste = g_array_new(FALSE, FALSE, sizeof(int));
    int elements[6] = {3, 1, 4, 1, 5, 9};
    g_array_append_vals(liste, elements, 6);
    afficher_liste(liste);

    g_array_sort(liste, comparer);
    afficher_liste(liste);
    g_array_free(liste, FALSE);
    return 0;
}

GPtrArray pour les pointeurs

Un GPtrArray simplifie la gestion de tableaux de pointeurs.

#include <glib.h>
#include <stdio.h>

int main(int argc, char** argv) {
    GPtrArray* liste_pointeurs = g_ptr_array_new();
    g_ptr_array_add(liste_pointeurs, g_strdup("Premier "));
    g_ptr_array_add(liste_pointeurs, g_strdup("Deuxieme "));
    g_ptr_array_add(liste_pointeurs, g_strdup("Troisieme "));
    g_ptr_array_add(liste_pointeurs, g_strdup("Quatrieme "));

    printf("Contenu initial :\n");
    for (int n = 0; n < liste_pointeurs->len; n++)
        printf("%s", (char*)g_ptr_array_index(liste_pointeurs, n));
    printf("\n");

    g_ptr_array_remove_index(liste_pointeurs, 1);
    printf("Apres suppression d'un element :\n");
    for (int p = 0; p < liste_pointeurs->len; p++)
        printf("%s", (char*)g_ptr_array_index(liste_pointeurs, p));
    printf("\n");

    g_ptr_array_free(liste_pointeurs, TRUE);
    return 0;
}

GByteArray pour les octets

Ce type spécifique est conçu pour les données binaires.

#include <glib.h>
#include <stdio.h>

int main(int argc, char** argv) {
    GByteArray* octets = g_byte_array_new();
    guint8 val = 0xFF;
    g_byte_array_append(octets, &val, sizeof(val));
    printf("Premier octet (decimal) : %d\n", octets->data[0]);

    val = 0x00;
    g_byte_array_prepend(octets, &val, sizeof(val));
    printf("Apres ajout au debut, premier octet : %d\n", octets->data[0]);

    g_byte_array_remove_index(octets, 0);
    printf("Apres retrait, premier octet retourne a %d\n", octets->data[0]);

    val = 0xAA;
    g_byte_array_append(octets, &val, sizeof(val));
    printf("Longueur finale du tableau d'octets : %d\n", octets->len);

    g_byte_array_free(octets, TRUE);
    return 0;
}

Étiquettes: GLib GArray GPtrArray GByteArray programmation C

Publié le 12 juin à 19h27