Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Langue C

Maîtriser les membres de tableau flexibles dans les structures C pour la gestion dynamique des données

Les membres de tableau flexibles permettent de gérer des tableaux à l'intérieur de structures sans définir leur taille. Ces tableaux obtiennent leur taille à l'exécution. Une structure en C est un type de données défini par l'utilisateur où l'on regroupe plusieurs membres de différents types de données sous un même nom.

Voici la syntaxe pour déclarer une structure en C :

struct NomStructure {
    type_donnee membre1;
    type_donnee membre2;
    // ...
};

Chaque membre peut avoir un type de données différent.

Les membres de tableau flexibles étendent les structures en contenant un tableau de taille dynamique à la fin de leurs membres de taille fixe, le tout stocké dans un seul bloc de mémoire. Dans ce chapitre, nous verrons comment ils fonctionnent à l'intérieur des structures.

Membres de tableau flexibles dans une structure

Un membre de tableau flexible est un tableau à l'intérieur d'une structure sans taille fixe, et sa mémoire est allouée dynamiquement à l'exécution en utilisant malloc(), calloc() ou des fonctions similaires. Il est déclaré à l'aide de crochets vides [].

Le membre de tableau flexible doit être déclaré à la fin de la structure, et il doit y avoir au moins un autre membre avant de le déclarer.

Voici la syntaxe pour déclarer un membre de tableau flexible à l'intérieur d'une structure :

struct NomStructure {
    type_donnee membre1;
    type_donnee tableau_flexible[]; // membre de tableau flexible
};

Ici, type_donnee est le type de données du tableau, et tableau_flexible[] est le tableau flexible sans taille fixe.

Allocation de mémoire pour un membre de tableau flexible

Un membre de tableau flexible n'a pas de taille fixe, donc le compilateur n'alloue aucune mémoire pour lui à l'intérieur de la structure. L'opérateur sizeof ne calcule que la taille des membres fixes de la structure sans inclure le membre de tableau flexible. C'est pourquoi nous devons allouer la mémoire manuellement lors de la création de telles structures.

La mémoire totale requise est calculée comme suit :

Mémoire Totale = sizeof(structure) + (nombre d'éléments x sizeof(type d'élément))

Ici, sizeof(structure) donne la mémoire pour les membres fixes, et (nombre d'éléments x sizeof(type d'élément)) donne la mémoire pour le tableau flexible. En les additionnant, on obtient la mémoire totale à allouer.

Exemple 1 : Allocation de mémoire pour un membre de tableau flexible

Voici un exemple où nous définissons une structure avec un membre fixe et un tableau flexible, et allouons de la mémoire pour le tableau flexible.

#include <stdio.h>
#include <stdlib.h>
struct Exemple {
    int id;
    int arr[]; // membre de tableau flexible
};
int main() {
    int taille = 5;
    // Allouer de la mémoire pour la structure + tableau flexible
    struct Exemple *e = malloc(sizeof(struct Exemple) + taille * sizeof(int));
    if (e != NULL) {
        printf("Mémoire totale allouée : %zu octets\n", sizeof(struct Exemple) + taille * sizeof(int));
        free(e);
    }
    return 0;
}

Ici, sizeof(struct Exemple) donne 4 octets pour le membre id. Ensuite, nous calculons la mémoire pour le tableau flexible : 5 x sizeof(int) = 20 octets. La mémoire totale allouée est 4 + 20 = 24 octets. La sortie est :

Mémoire totale allouée : 24 octets

Exemple 2 : Accès à un tableau flexible dans une structure

Dans cet exemple, nous définissons une structure Étudiant avec un membre fixe (id) et un membre de tableau flexible (notes). Nous allouons de la mémoire dynamiquement pour le tableau flexible et accédons à ses éléments. Si nous accédons à des éléments au-delà de la taille allouée, cela provoquera un comportement indéfini, donc nous n'accédons qu'à notes[0] à notes[2].

#include <stdio.h>
#include <stdlib.h>
struct Etudiant {
    int id;
    int notes[]; // membre de tableau flexible
};
int main() {
    int matieres = 3;
    // Allouer de la mémoire pour la structure + tableau flexible
    struct Etudiant *s = malloc(sizeof(struct Etudiant) + matieres * sizeof(int));
    if (s != NULL) {
        s->id = 102;
        s->notes[0] = 80;
        s->notes[1] = 75;
        s->notes[2] = 88;
        printf("ID Étudiant : %d\n", s->id);
        printf("Notes : %d, %d, %d\n", s->notes[0], s->notes[1], s->notes[2]);
        printf("Mémoire totale allouée : %zu octets\n", sizeof(struct Etudiant) + matieres * sizeof(int));
        free(s);
    }
    return 0;
}

Voici la sortie du programme ci-dessus :

ID Étudiant : 102
Notes : 80, 75, 88
Mémoire totale allouée : 16 octets

Redimensionnement dynamique des membres de tableau flexibles

Les tableaux flexibles peuvent être redimensionnés en utilisant la fonction realloc(). Cette fonction agrandit soit le bloc de mémoire existant, soit alloue un nouveau bloc et copie automatiquement les données existantes.

Pour redimensionner un tableau flexible, on appelle la fonction realloc() avec la nouvelle taille totale de mémoire en utilisant la formule :

sizeof(structure) + (nouveau_nombre_elements x sizeof(type_element))

Note : Stockez toujours le résultat de realloc() dans un pointeur temporaire. Si elle échoue, votre pointeur original reste intact. Mettez également à jour le compteur de taille après le redimensionnement et initialisez uniquement les éléments nouvellement ajoutés.

Exemple 3 : Redimensionnement dynamique des membres de tableau flexibles

Dans cet exemple, nous créons une structure Étudiant pour contenir 3 notes initialement. Plus tard, nous redimensionnons le tableau flexible pour contenir 6 notes en utilisant realloc(). Les notes déjà stockées restent inchangées, donc nous n'avons pas besoin de les copier manuellement.

#include <stdio.h>
#include <stdlib.h>
struct Etudiant {
    int id;
    int count; // Ce champ aide à suivre la taille actuelle du tableau
    int notes[]; // Membre de tableau flexible
};
int main() {
    // Étape 1 : Allocation initiale pour 3 notes
    int elements_initiaux = 3;
    struct Etudiant *s = malloc(sizeof(struct Etudiant) + elements_initiaux * sizeof(int));
    if (s != NULL) {
        s->id = 101;
        s->count = elements_initiaux; // Stocker la taille actuelle du tableau
        // Afficher les tailles initiales
        printf("Taille de la structure : %zu octets\n", sizeof(struct Etudiant));
        // Sortie : 8 octets (id + count)
        printf("Éléments initiaux du tableau : %d\n", s->count);
        // Sortie : 3
        printf("Mémoire totale initiale : %zu octets\n", sizeof(struct Etudiant) + elements_initiaux * sizeof(int));
        // Sortie : 20 octets
        // Étape 2 : Redimensionner pour contenir 6 notes
        int nouveaux_elements = 6;
        struct Etudiant *temp = realloc(s, sizeof(struct Etudiant) + nouveaux_elements * sizeof(int));
        if (temp != NULL) {
            s = temp;
            s->count = nouveaux_elements; // Mettre à jour le suivi de la taille du tableau
            // Afficher les nouvelles tailles
            printf("\nAprès redimensionnement :\n");
            printf("Taille de la structure : %zu octets\n", sizeof(struct Etudiant));
            // Toujours 8 octets
            printf("Nouveaux éléments du tableau : %d\n", s->count);
            // Sortie : 6
            printf("Nouvelle mémoire totale : %zu octets\n", sizeof(struct Etudiant) + nouveaux_elements * sizeof(int));
            // Sortie : 32 octets
        }
        free(s);
    }
    return 0;
}

Voici la sortie montrant la taille de la structure et la mémoire totale pour le tableau flexible initial et redimensionné.

Taille de la structure : 8 octets
Éléments initiaux du tableau : 3
Mémoire totale initiale : 20 octets
Après redimensionnement :
Taille de la structure : 8 octets
Nouveaux éléments du tableau : 6
Nouvelle mémoire totale : 32 octets

Dans ce chapitre, nous avons appris les membres de tableau flexibles dans les structures C. Ils sont déclarés à la fin d'une structure et gèrent des données de longueur variable, économisent de la mémoire et s'adaptent facilement à différentes tailles de données. Nous avons également vu comment les allouer, y accéder et les redimensionner.

Langue C

  1. Maîtriser l'héritage en C++ : Construire des classes puissantes avec du code réutilisable
  2. Maîtriser l'abstraction de données en C++ : Simplifier la conception par séparation interface-implémentation
  3. Maîtriser les opérateurs d'incrémentation et décrémentation en C : Usage & meilleures pratiques
  4. Comprendre la structure d'un programme C : Guide pour débutants
  5. Appel par référence en C++ : Utilisation des pointeurs - Exemples pratiques
  6. Classes et objets en C++ : Guide pratique avec exemples de code
  7. Comprendre les Interfaces C# : Définition, Exemple et Utilisation Pratique
  8. Maîtriser les classes C# : blueprint pour la programmation orientée objet
  9. Comprendre les modificateurs de type de données en C++