Langage C/C++

Exercices corrigés en langage C : Les structures

Les structures en langage C sont une manière essentielle de regrouper différentes variables sous un même type de données. Elles permettent de modéliser des données complexes de manière plus intuitive et structurée. Cet article présente quelques exercices corrigés pour comprendre et maîtriser les structures en C.

Exercice 1 : Définition et utilisation de structures de base

Énoncé

Définissez une structure Personne contenant les champs suivants : nom, âge, et taille. Créez une variable de type Personne, assignez des valeurs à ses champs, et affichez-les.

Solution

#include <stdio.h>
#include <string.h>

// Définition de la structure Personne
struct Personne {
    char nom[50];
    int age;
    float taille;
};

int main() {
    // Déclaration d'une variable de type Personne
    struct Personne p1;

    // Assignation des valeurs aux champs de la structure
    strcpy(p1.nom, "Alice");
    p1.age = 30;
    p1.taille = 1.75;

    // Affichage des valeurs
    printf("Nom : %s\n", p1.nom);
    printf("Âge : %d\n", p1.age);
    printf("Taille : %.2f m\n", p1.taille);

    return 0;
}
Exercice 2 : Structure imbriquée

Énoncé

Définissez une structure Date contenant les champs jour, mois, et année. Ensuite, définissez une structure Employe contenant un champ nom et un champ date_naissance de type Date. Créez une variable de type Employe, assignez des valeurs à ses champs, et affichez-les.

Solution

#include <stdio.h>
#include <string.h>

// Définition de la structure Date
struct Date {
    int jour;
    int mois;
    int annee;
};

// Définition de la structure Employe
struct Employe {
    char nom[50];
    struct Date date_naissance;
};

int main() {
    // Déclaration d'une variable de type Employe
    struct Employe emp1;

    // Assignation des valeurs aux champs de la structure Employe
    strcpy(emp1.nom, "Bob");
    emp1.date_naissance.jour = 15;
    emp1.date_naissance.mois = 8;
    emp1.date_naissance.annee = 1990;

    // Affichage des valeurs
    printf("Nom : %s\n", emp1.nom);
    printf("Date de naissance : %02d/%02d/%d\n",
           emp1.date_naissance.jour,
           emp1.date_naissance.mois,
           emp1.date_naissance.annee);

    return 0;
}
Exercice 3 : Tableau de structures

Énoncé

Définissez une structure Livre contenant les champs titre, auteur, et année de publication. Créez un tableau de 3 livres, assignez des valeurs à chaque livre, et affichez-les.

Solution

#include <stdio.h>
#include <string.h>

// Définition de la structure Livre
struct Livre {
    char titre[100];
    char auteur[50];
    int annee_publication;
};

int main() {
    // Déclaration d'un tableau de 3 livres
    struct Livre bibliotheque[3];

    // Assignation des valeurs au premier livre
    strcpy(bibliotheque[0].titre, "Le Petit Prince");
    strcpy(bibliotheque[0].auteur, "Antoine de Saint-Exupéry");
    bibliotheque[0].annee_publication = 1943;

    // Assignation des valeurs au deuxième livre
    strcpy(bibliotheque[1].titre, "1984");
    strcpy(bibliotheque[1].auteur, "George Orwell");
    bibliotheque[1].annee_publication = 1949;

    // Assignation des valeurs au troisième livre
    strcpy(bibliotheque[2].titre, "Le Seigneur des Anneaux");
    strcpy(bibliotheque[2].auteur, "J.R.R. Tolkien");
    bibliotheque[2].annee_publication = 1954;

    // Affichage des valeurs
    for (int i = 0; i < 3; i++) {
        printf("Livre %d :\n", i + 1);
        printf("  Titre : %s\n", bibliotheque[i].titre);
        printf("  Auteur : %s\n", bibliotheque[i].auteur);
        printf("  Année de publication : %d\n\n", bibliotheque[i].annee_publication);
    }

    return 0;
}
Exercice 4 : Structure avec pointeurs

Énoncé

Définissez une structure Etudiant contenant les champs nom, âge, et une liste de notes (tableau de flottants). Allouez dynamiquement de la mémoire pour les notes et affichez les informations de l’étudiant.

Solution

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Définition de la structure Etudiant
struct Etudiant {
    char nom[50];
    int age;
    float *notes;
    int nombre_notes;
};

int main() {
    // Déclaration d'une variable de type Etudiant
    struct Etudiant etu;

    // Assignation des valeurs aux champs de la structure
    strcpy(etu.nom, "Claire");
    etu.age = 20;
    etu.nombre_notes = 3;

    // Allocation dynamique de mémoire pour les notes
    etu.notes = (float *)malloc(etu.nombre_notes * sizeof(float));
    if (etu.notes == NULL) {
        printf("Erreur d'allocation de mémoire.\n");
        return 1;
    }

    // Assignation des valeurs aux notes
    etu.notes[0] = 15.5;
    etu.notes[1] = 17.0;
    etu.notes[2] = 18.5;

    // Affichage des valeurs
    printf("Nom : %s\n", etu.nom);
    printf("Âge : %d\n", etu.age);
    printf("Notes : ");
    for (int i = 0; i < etu.nombre_notes; i++) {
        printf("%.2f ", etu.notes[i]);
    }
    printf("\n");

    // Libération de la mémoire allouée
    free(etu.notes);

    return 0;
}

Synthèse 1

Ces exercices illustrent comment les structures peuvent être utilisées en C pour organiser et manipuler des données de manière efficace. La compréhension et la pratique de ces concepts sont essentielles pour développer des programmes complexes et bien structurés. Les structures permettent de regrouper des informations variées sous un même type, facilitant ainsi leur gestion et leur utilisation dans des programmes plus larges.

Les structures en C sont extrêmement utiles pour diverses applications réelles. Voici quelques cas d’applications typiques où les structures jouent un rôle crucial :

1. Gestion des bases de données

Cas d’application : Système de gestion de bibliothèque

Un système de gestion de bibliothèque peut utiliser des structures pour représenter des livres, des membres et des transactions d’emprunt.

#include <stdio.h>
#include <string.h>

#define MAX_LIVRES 100
#define MAX_MEMBRES 50

// Structure pour représenter un livre
struct Livre {
    char titre[100];
    char auteur[50];
    int annee;
    int disponible; // 1 pour disponible, 0 pour emprunté
};

// Structure pour représenter un membre de la bibliothèque
struct Membre {
    char nom[50];
    int id;
};

// Structure pour représenter une transaction d'emprunt
struct Emprunt {
    int id_membre;
    char titre_livre[100];
    char date_emprunt[11]; // Format YYYY-MM-DD
    char date_retour[11];  // Format YYYY-MM-DD
};

struct Livre bibliotheque[MAX_LIVRES];
struct Membre membres[MAX_MEMBRES];
struct Emprunt emprunts[MAX_LIVRES];

int nombre_livres = 0;
int nombre_membres = 0;
int nombre_emprunts = 0;

// Fonctions pour ajouter des livres, des membres, enregistrer des emprunts, etc.

void ajouterLivre(char* titre, char* auteur, int annee) {
    strcpy(bibliotheque[nombre_livres].titre, titre);
    strcpy(bibliotheque[nombre_livres].auteur, auteur);
    bibliotheque[nombre_livres].annee = annee;
    bibliotheque[nombre_livres].disponible = 1;
    nombre_livres++;
}

void ajouterMembre(char* nom, int id) {
    strcpy(membres[nombre_membres].nom, nom);
    membres[nombre_membres].id = id;
    nombre_membres++;
}

void enregistrerEmprunt(int id_membre, char* titre_livre, char* date_emprunt, char* date_retour) {
    strcpy(emprunts[nombre_emprunts].titre_livre, titre_livre);
    emprunts[nombre_emprunts].id_membre = id_membre;
    strcpy(emprunts[nombre_emprunts].date_emprunt, date_emprunt);
    strcpy(emprunts[nombre_emprunts].date_retour, date_retour);
    nombre_emprunts++;

    // Marquer le livre comme emprunté
    for (int i = 0; i < nombre_livres; i++) {
        if (strcmp(bibliotheque[i].titre, titre_livre) == 0) {
            bibliotheque[i].disponible = 0;
            break;
        }
    }
}

int main() {
    ajouterLivre("Le Petit Prince", "Antoine de Saint-Exupéry", 1943);
    ajouterMembre("Alice", 1);
    enregistrerEmprunt(1, "Le Petit Prince", "2024-07-01", "2024-07-15");

    // Affichage des informations
    printf("Livres dans la bibliothèque:\n");
    for (int i = 0; i < nombre_livres; i++) {
        printf("%s par %s (%d) - %s\n",
            bibliotheque[i].titre,
            bibliotheque[i].auteur,
            bibliotheque[i].annee,
            bibliotheque[i].disponible ? "Disponible" : "Emprunté");
    }

    printf("\nMembres de la bibliothèque:\n");
    for (int i = 0; i < nombre_membres; i++) {
        printf("ID: %d, Nom: %s\n", membres[i].id, membres[i].nom);
    }

    printf("\nEmprunts enregistrés:\n");
    for (int i = 0; i < nombre_emprunts; i++) {
        printf("Membre ID: %d, Livre: %s, Emprunté le: %s, Retour prévu le: %s\n",
            emprunts[i].id_membre,
            emprunts[i].titre_livre,
            emprunts[i].date_emprunt,
            emprunts[i].date_retour);
    }

    return 0;
}
2. Simulation et modélisation

Cas d’application : Simulation d’un système de gestion des stocks

Une entreprise peut utiliser des structures pour modéliser les articles en stock, les commandes et les clients.

#include <stdio.h>
#include <string.h>

#define MAX_ARTICLES 100
#define MAX_COMMANDES 50

// Structure pour représenter un article en stock
struct Article {
    char nom[50];
    int quantite;
    float prix;
};

// Structure pour représenter une commande
struct Commande {
    int id_client;
    char nom_article[50];
    int quantite_commande;
    char date_commande[11]; // Format YYYY-MM-DD
};

struct Article stock[MAX_ARTICLES];
struct Commande commandes[MAX_COMMANDES];

int nombre_articles = 0;
int nombre_commandes = 0;

void ajouterArticle(char* nom, int quantite, float prix) {
    strcpy(stock[nombre_articles].nom, nom);
    stock[nombre_articles].quantite = quantite;
    stock[nombre_articles].prix = prix;
    nombre_articles++;
}

void enregistrerCommande(int id_client, char* nom_article, int quantite_commande, char* date_commande) {
    strcpy(commandes[nombre_commandes].nom_article, nom_article);
    commandes[nombre_commandes].id_client = id_client;
    commandes[nombre_commandes].quantite_commande = quantite_commande;
    strcpy(commandes[nombre_commandes].date_commande, date_commande);
    nombre_commandes++;

    // Mettre à jour le stock
    for (int i = 0; i < nombre_articles; i++) {
        if (strcmp(stock[i].nom, nom_article) == 0) {
            stock[i].quantite -= quantite_commande;
            break;
        }
    }
}

int main() {
    ajouterArticle("Ordinateur", 50, 799.99);
    ajouterArticle("Clavier", 200, 19.99);
    ajouterArticle("Souris", 150, 9.99);

    enregistrerCommande(1, "Ordinateur", 1, "2024-07-01");
    enregistrerCommande(2, "Clavier", 2, "2024-07-02");

    // Affichage des informations
    printf("Articles en stock:\n");
    for (int i = 0; i < nombre_articles; i++) {
        printf("Nom: %s, Quantité: %d, Prix: %.2f\n",
            stock[i].nom, stock[i].quantite, stock[i].prix);
    }

    printf("\nCommandes enregistrées:\n");
    for (int i = 0; i < nombre_commandes; i++) {
        printf("Client ID: %d, Article: %s, Quantité: %d, Date: %s\n",
            commandes[i].id_client,
            commandes[i].nom_article,
            commandes[i].quantite_commande,
            commandes[i].date_commande);
    }

    return 0;
}
3. Traitement d’images

Cas d’application : Manipulation d’images en niveaux de gris

Un programme peut utiliser des structures pour représenter les pixels d’une image et effectuer des opérations telles que l’inversion des couleurs ou le lissage.

#include <stdio.h>
#include <stdlib.h>

// Structure pour représenter un pixel en niveaux de gris
struct Pixel {
    unsigned char niveau_gris;
};

// Structure pour représenter une image en niveaux de gris
struct Image {
    int largeur;
    int hauteur;
    struct Pixel* pixels;
};

// Fonction pour créer une image
struct Image creerImage(int largeur, int hauteur) {
    struct Image img;
    img.largeur = largeur;
    img.hauteur = hauteur;
    img.pixels = (struct Pixel*)malloc(largeur * hauteur * sizeof(struct Pixel));
    return img;
}

// Fonction pour libérer la mémoire de l'image
void libererImage(struct Image img) {
    free(img.pixels);
}

// Fonction pour inverser les couleurs de l'image
void inverserCouleurs(struct Image img) {
    for (int i = 0; i < img.largeur * img.hauteur; i++) {
        img.pixels[i].niveau_gris = 255 - img.pixels[i].niveau_gris;
    }
}

// Fonction pour afficher l'image (pour des raisons de simplicité, on affiche les niveaux de gris)
void afficherImage(struct Image img) {
    for (int i = 0; i < img.hauteur; i++) {
        for (int j = 0; j < img.largeur; j++) {
            printf("%3d ", img.pixels[i * img.largeur + j].niveau_gris);
        }
        printf("\n");
    }
}

int main() {
    int largeur = 5;
    int hauteur = 5;
    struct Image img = creerImage(largeur, hauteur);

    // Initialisation de l'image avec des valeurs de niveaux de gris
    for (int i = 0; i < largeur * hauteur

; i++) {
        img.pixels[i].niveau_gris = i * 10;
    }

    printf("Image originale:\n");
    afficherImage(img);

    inverserCouleurs(img);

    printf("\nImage avec couleurs inversées:\n");
    afficherImage(img);

    libererImage(img);

    return 0;
}
4. Gestion des étudiants

Cas d’application : Système de gestion des informations des étudiants

Un programme peut utiliser des structures pour stocker et gérer les informations des étudiants, y compris leurs notes, et calculer des statistiques comme la moyenne des notes.

#include <stdio.h>
#include <string.h>

#define MAX_ETUDIANTS 100
#define MAX_NOTES 10

// Structure pour représenter un étudiant
struct Etudiant {
    char nom[50];
    int id;
    float notes[MAX_NOTES];
    int nombre_notes;
};

// Tableau pour stocker les étudiants
struct Etudiant etudiants[MAX_ETUDIANTS];
int nombre_etudiants = 0;

// Fonction pour ajouter un étudiant
void ajouterEtudiant(char* nom, int id, float* notes, int nombre_notes) {
    struct Etudiant etu;
    strcpy(etu.nom, nom);
    etu.id = id;
    etu.nombre_notes = nombre_notes;
    for (int i = 0; i < nombre_notes; i++) {
        etu.notes[i] = notes[i];
    }
    etudiants[nombre_etudiants++] = etu;
}

// Fonction pour calculer la moyenne des notes d'un étudiant
float calculerMoyenne(float* notes, int nombre_notes) {
    float somme = 0.0;
    for (int i = 0; i < nombre_notes; i++) {
        somme += notes[i];
    }
    return somme / nombre_notes;
}

// Fonction pour afficher les informations des étudiants
void afficherEtudiants() {
    for (int i = 0; i < nombre_etudiants; i++) {
        printf("Nom: %s, ID: %d, Moyenne: %.2f\n",
            etudiants[i].nom, etudiants[i].id, calculerMoyenne(etudiants[i].notes, etudiants[i].nombre_notes));
    }
}

int main() {
    float notes1[] = {85.0, 90.0, 78.0};
    float notes2[] = {88.0, 92.0, 79.0};

    ajouterEtudiant("Alice", 1, notes1, 3);
    ajouterEtudiant("Bob", 2, notes2, 3);

    afficherEtudiants();

    return 0;
}

Conclusion

Les structures en C sont essentielles pour organiser et manipuler des données complexes dans diverses applications réelles. Que ce soit pour la gestion de bases de données, la simulation de systèmes, le traitement d’images ou la gestion d’informations des étudiants, les structures permettent de créer des programmes robustes et bien organisés. En pratiquant ces cas d’applications, vous pourrez mieux comprendre comment utiliser les structures pour résoudre des problèmes concrets.

Autres articles

Guide : Implémenter get_iemedans des fichiers avec...
La fonction get_iemepermet de récupérer le i-ème élément d'un fichier...
Read more
Guide : Implémenter un Fichier en Tableau...
Les fichiers en tableaux circulaires (ou files d'attente circulaires )...
Read more
Guide : Fichiers en Tableaux Circulaires en...
Les tableaux circulaires (ou buffers circulaires) sont des structures de...
Read more

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *