Apprendre à programmer

Série d’Exercices Corrigés : Manipulation de Tableaux et Chaînes de Caractères

Pourquoi maîtriser les tableaux et les chaînes de caractères en programmation ?

La manipulation des tableaux et des chaînes de caractères constitue une étape fondamentale dans l’apprentissage de l’algorithmique et du développement informatique. Ces structures de données permettent de stocker, organiser et transformer des informations utilisées dans presque toutes les applications numériques.

Les exercices corrigés proposés permettent de comprendre progressivement :

  • la déclaration et l’initialisation des tableaux ;
  • le parcours des éléments avec des boucles ;
  • la recherche d’une valeur dans un tableau ;
  • le tri et le classement des données ;
  • la modification et la concaténation des chaînes de caractères ;
  • la résolution de problèmes algorithmiques courants.

Cette série d’exercices se concentre sur la manipulation de tableaux et de chaînes de caractères en C, avec des situations pratiques et des solutions détaillées.


Exercice 1 : Trouver le Maximum d’un Tableau

Énoncé :

Écrivez une fonction qui prend un tableau d’entiers et sa taille, et retourne le maximum des valeurs.

Solution :

#include <stdio.h>

int findMax(int arr[], int size) {
    int max = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}

int main() {
    int arr[] = {10, 20, 5, 8, 50};
    int size = sizeof(arr) / sizeof(arr[0]);
    printf("Le maximum est : %d\n", findMax(arr, size));
    return 0;
}

Points Clés :

  • Utilisez une boucle pour parcourir le tableau.
  • Maintenez une variable max pour stocker la valeur maximale.

Exercice 2 : Réverser un Tableau

Énoncé :

Créez une fonction qui inverse les éléments d’un tableau.

Solution :

#include <stdio.h>

void reverseArray(int arr[], int size) {
    for (int i = 0; i < size / 2; i++) {
        int temp = arr[i];
        arr[i] = arr[size - i - 1];
        arr[size - i - 1] = temp;
    }
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int size = sizeof(arr) / sizeof(arr[0]);

    reverseArray(arr, size);

    printf("Tableau inversé : ");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}

Points Clés :

  • Échangez les éléments symétriques en utilisant un index i et son opposé size - i - 1.

Exercice 3 : Compter les Voyelles dans une Chaîne

Énoncé :

Écrivez une fonction qui compte le nombre de voyelles dans une chaîne de caractères.

Solution :

#include <stdio.h>
#include <ctype.h>

int countVowels(const char *str) {
    int count = 0;
    while (*str) {
        char ch = tolower(*str);
        if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
            count++;
        }
        str++;
    }
    return count;
}

int main() {
    char str[] = "Langage C et Manipulation des Chaines";
    printf("Nombre de voyelles : %d\n", countVowels(str));
    return 0;
}

Points Clés :

  • Parcourez la chaîne caractère par caractère.
  • Utilisez tolower pour gérer les majuscules/minuscules.

Exercice 4 : Supprimer les Espaces d’une Chaîne

Énoncé :

Implémentez une fonction qui supprime tous les espaces d’une chaîne de caractères.

Solution :

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

void removeSpaces(char *str) {
    char *dst = str;
    while (*str) {
        if (*str != ' ') {
            *dst++ = *str;
        }
        str++;
    }
    *dst = '\0';
}

int main() {
    char str[] = "Apprendre le C est amusant";
    removeSpaces(str);
    printf("Sans espaces : %s\n", str);
    return 0;
}

Points Clés :

  • Utilisez un second pointeur pour construire la chaîne sans espaces.
  • Terminez la chaîne avec '\0'.

Exercice 5 : Concaténer Deux Chaînes

Énoncé :

Créez une fonction qui concatène deux chaînes sans utiliser strcat.

Solution :

#include <stdio.h>

void concatenate(char *dest, const char *src) {
    while (*dest) {
        dest++;
    }
    while (*src) {
        *dest++ = *src++;
    }
    *dest = '\0';
}

int main() {
    char str1[50] = "Bonjour, ";
    char str2[] = "comment ça va ?";
    concatenate(str1, str2);
    printf("Chaîne concaténée : %s\n", str1);
    return 0;
}

Points Clés :

  • Parcourez dest jusqu’à la fin ('\0').
  • Copiez les caractères de src dans dest.

Exercice 6 : Comparer Deux Chaînes

Énoncé :

Implémentez une fonction pour comparer deux chaînes sans utiliser strcmp.

Solution :

#include <stdio.h>

int compareStrings(const char *str1, const char *str2) {
    while (*str1 && (*str1 == *str2)) {
        str1++;
        str2++;
    }
    return *(unsigned char *)str1 - *(unsigned char *)str2;
}

int main() {
    char str1[] = "Bonjour";
    char str2[] = "Bonsoire";
    int result = compareStrings(str1, str2);

    if (result == 0) {
        printf("Les chaînes sont identiques\n");
    } else if (result < 0) {
        printf("str1 est inférieur à str2\n");
    } else {
        printf("str1 est supérieur à str2\n");
    }
    return 0;
}

Points Clés :

  • Comparez les caractères un par un.
  • Retournez la différence des caractères dès qu’un désaccord est trouvé.

Exercice 7 : Trouver un Mot dans une Chaîne

Énoncé :

Écrivez une fonction qui vérifie si un mot donné est présent dans une chaîne de caractères.

Solution :

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

int findWord(const char *str, const char *word) {
    const char *p = strstr(str, word);
    return (p != NULL);
}

int main() {
    char str[] = "C est un langage de programmation.";
    char word[] = "langage";
    if (findWord(str, word)) {
        printf("Le mot '%s' est présent dans la chaîne.\n", word);
    } else {
        printf("Le mot '%s' n'est pas trouvé.\n", word);
    }
    return 0;
}

Points Clés :

  • Utilisez strstr pour trouver une sous-chaîne dans une chaîne.
  • Retournez un indicateur de présence.

Exercice 8 : Trier un Tableau de Chaînes

Énoncé :

Créez une fonction qui trie un tableau de chaînes par ordre alphabétique.

Solution :

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

void sortStrings(char arr[][50], int n) {
    char temp[50];
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (strcmp(arr[i], arr[j]) > 0) {
                strcpy(temp, arr[i]);
                strcpy(arr[i], arr[j]);
                strcpy(arr[j], temp);
            }
        }
    }
}

int main() {
    char arr[5][50] = {"Pomme", "Orange", "Banane", "Abricot", "Cerise"};
    int n = 5;

    sortStrings(arr, n);

    printf("Tableau trié :\n");
    for (int i = 0; i < n; i++) {
        printf("%s\n", arr[i]);
    }

    return 0;
}

Points Clés :

  • Utilisez strcmp pour comparer les chaînes.
  • Permutez les chaînes en cas de désordre.

Exercice Pratique : Gestion d’une Liste de Produits avec Pointeurs


Énoncé :

Créez un programme en C qui permet de gérer une liste de produits. Chaque produit contient les informations suivantes :

  • Nom : Chaîne de caractères.
  • Prix : Nombre décimal.
  • Quantité en stock : Entier.

Le programme doit permettre les opérations suivantes :

  1. Ajouter un produit.
  2. Afficher tous les produits.
  3. Modifier les informations d’un produit.
  4. Calculer la valeur totale en stock (prix × quantité pour chaque produit).

Utilisez des pointeurs pour gérer la liste dynamiquement.


Solution :

Voici une solution complète avec des explications :

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

// Structure pour représenter un produit
typedef struct {
    char name[50];
    float price;
    int quantity;
} Product;

// Prototypes des fonctions
void addProduct(Product **products, int *count);
void displayProducts(Product *products, int count);
void modifyProduct(Product *products, int count);
float calculateTotalValue(Product *products, int count);

int main() {
    Product *products = NULL; // Pointeur vers un tableau dynamique de produits
    int count = 0; // Nombre de produits

    int choice;

    do {
        printf("\n--- Gestion des Produits ---\n");
        printf("1. Ajouter un produit\n");
        printf("2. Afficher tous les produits\n");
        printf("3. Modifier un produit\n");
        printf("4. Calculer la valeur totale en stock\n");
        printf("5. Quitter\n");
        printf("Votre choix : ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                addProduct(&products, &count);
                break;
            case 2:
                displayProducts(products, count);
                break;
            case 3:
                modifyProduct(products, count);
                break;
            case 4: {
                float totalValue = calculateTotalValue(products, count);
                printf("Valeur totale en stock : %.2f\n", totalValue);
                break;
            }
            case 5:
                printf("Au revoir !\n");
                break;
            default:
                printf("Choix invalide. Veuillez réessayer.\n");
        }
    } while (choice != 5);

    // Libérer la mémoire allouée
    free(products);

    return 0;
}

// Fonction pour ajouter un produit
void addProduct(Product **products, int *count) {
    *products = realloc(*products, (*count + 1) * sizeof(Product));
    if (*products == NULL) {
        printf("Erreur d'allocation mémoire.\n");
        exit(1);
    }

    Product *newProduct = &(*products)[*count];

    printf("Nom du produit : ");
    scanf("%s", newProduct->name);
    printf("Prix du produit : ");
    scanf("%f", &newProduct->price);
    printf("Quantité en stock : ");
    scanf("%d", &newProduct->quantity);

    (*count)++;
}

// Fonction pour afficher tous les produits
void displayProducts(Product *products, int count) {
    if (count == 0) {
        printf("Aucun produit disponible.\n");
        return;
    }

    printf("\n--- Liste des Produits ---\n");
    for (int i = 0; i < count; i++) {
        printf("Produit %d : %s | Prix : %.2f | Quantité : %d\n",
               i + 1, products[i].name, products[i].price, products[i].quantity);
    }
}

// Fonction pour modifier un produit
void modifyProduct(Product *products, int count) {
    if (count == 0) {
        printf("Aucun produit disponible.\n");
        return;
    }

    int index;
    printf("Entrez le numéro du produit à modifier (1-%d) : ", count);
    scanf("%d", &index);

    if (index < 1 || index > count) {
        printf("Numéro invalide.\n");
        return;
    }

    Product *product = &products[index - 1];

    printf("Modifier le nom (actuel : %s) : ", product->name);
    scanf("%s", product->name);
    printf("Modifier le prix (actuel : %.2f) : ", product->price);
    scanf("%f", &product->price);
    printf("Modifier la quantité (actuelle : %d) : ", product->quantity);
    scanf("%d", &product->quantity);
}

// Fonction pour calculer la valeur totale en stock
float calculateTotalValue(Product *products, int count) {
    float total = 0;
    for (int i = 0; i < count; i++) {
        total += products[i].price * products[i].quantity;
    }
    return total;
}

Explications :

  1. Gestion dynamique avec realloc :
    • La liste des produits est étendue dynamiquement chaque fois qu’un nouveau produit est ajouté.
  2. Pointeurs pour gérer la liste :
    • Le double pointeur Product **products permet de modifier directement le tableau de produits dans la mémoire.
  3. Manipulation directe des structures :
    • Les produits sont manipulés via des pointeurs pour optimiser la gestion en mémoire.
  4. Réallocation et Libération :
    • La mémoire allouée est libérée à la fin pour éviter les fuites.

Exemple d’Exécution :

Entrées :

  1. Ajouter un produit : Nom = « Laptop », Prix = 1200.50, Quantité = 5.
  2. Ajouter un produit : Nom = « Mouse », Prix = 25.99, Quantité = 15.
  3. Afficher les produits.
  4. Modifier le produit 2 (Nom = « Keyboard », Prix = 30.99, Quantité = 10).
  5. Calculer la valeur totale en stock.
  6. Quitter.

Sorties :

Produit 1 : Laptop | Prix : 1200.50 | Quantité : 5
Produit 2 : Keyboard | Prix : 30.99 | Quantité : 10
Valeur totale en stock : 6075.95

Points Clés à Retenir :

  1. Réallocation Dynamique :
    • realloc permet de redimensionner le tableau lorsque de nouveaux produits sont ajoutés.
  2. Utilisation des Pointeurs :
    • Les structures sont manipulées par leur adresse pour éviter des copies inutiles.
  3. Libération de la Mémoire :
    • free(products) est utilisé pour éviter les fuites mémoire.

Cet exercice met en pratique l’utilisation des pointeurs dans un contexte réaliste, tout en renforçant des concepts comme la gestion dynamique de mémoire et la manipulation des structures.

Exercice corrigé : Calculer la somme et la moyenne d’un tableau

Énoncé

Écrire un algorithme permettant de calculer la somme et la moyenne des valeurs contenues dans un tableau de nombres.

Données utilisées

Indice01234
Valeur12815105

Schéma de résolution

⬇️ Début
⬇️
📌 Initialiser Somme = 0
⬇️
🔁 Parcourir chaque élément du tableau
⬇️
➕ Ajouter la valeur à Somme
⬇️
📊 Calculer Moyenne = Somme / Nombre d’éléments
⬇️
✅ Afficher résultat
⬇️
🏁 Fin

Correction algorithmique

Début

Somme ← 0

Pour i allant de 0 à n-1 faire

    Somme ← Somme + Tableau[i]

Fin Pour

Moyenne ← Somme / n

Afficher Somme
Afficher Moyenne

Fin

Série d’exercices corrigés multiniveau en algorithmique et programmation

Cette série d’exercices corrigés accompagne la progression en programmation, depuis les premiers raisonnements algorithmiques jusqu’aux problématiques plus complexes liées aux tableaux, chaînes, fonctions, structures de données et optimisation des programmes.

Chaque exercice comprend :

  • un énoncé clair ;
  • les données utilisées ;
  • un schéma de résolution ;
  • la correction algorithmique ;
  • les compétences développées.

Niveau débutant : Exercices corrigés d’algorithmique fondamentale

Exercice 1 : Calculer une remise commerciale

Un produit coûte 250 €. Si le client bénéficie d’une remise de 10 %, calculer le prix final.

Schéma de résolution

Prix initial
⬇️
Calcul remise = Prix × 10%
⬇️
Prix final = Prix – Remise
⬇️
Afficher résultat

Correction

Début

Prix ← 250

Remise ← Prix × 0.10

Final ← Prix - Remise

Afficher Final

Fin

Compétences :

  • variables ;
  • calculs simples ;
  • opérations mathématiques.

Exercice corrigé : Afficher les nombres de 1 à 10

Énoncé

Créer un algorithme affichant automatiquement les nombres compris entre 1 et 10.

Schéma

Initialiser compteur = 1⬇️Tester compteur ≤ 10 ?⬇️Afficher compteur⬇️Ajouter 1⬇️Retour au test

Correction

Début

Pour i allant de 1 à 10

Afficher i

Fin Pour

Fin

Niveau intermédiaire : Exercices corrigés sur les tableaux

Exercice : Trouver le maximum d’un tableau

Soit le tableau :

Indice0123
Valeur1472511

Schéma

Premier élément = Maximum⬇️Comparer avec élément suivant⬇️Si supérieur → remplacer Maximum⬇️Continuer jusqu’à la fin⬇️Afficher Maximum

Correction

Début

Max ← Tableau[0]

Pour i de 1 à n-1

Si Tableau[i] > Max

Alors Max ← Tableau[i]

Fin Si

Fin Pour

Afficher Max

Fin

Les pointeurs deviennent plus faciles à comprendre lorsqu’ils sont étudiés à partir de cas concrets. Le parcours d’un tableau, le passage d’une adresse à une fonction et la création d’un tableau dynamique permettent de visualiser leur rôle en mémoire. Consultez ce guide consacré aux tableaux et pointeurs en C pour travailler ces notions avec des programmes complets.

Niveau avancé : Exercice corrigé d’algorithme de tri

Énoncé

Trier un tableau de nombres dans l’ordre croissant.

Exemple

Avant : [9,3,7,1]

Après : [1,3,7,9]

Schéma du tri

Comparer deux valeurs⬇️Valeur gauche > valeur droite ?⬇️Échanger les positions⬇️Répéter jusqu’à obtenir un tableau trié

Correction simplifiée

Début

Pour i de 0 à n-1

Pour j de i+1 à n

Si T[i] > T[j]

Echanger T[i] et T[j]

Fin Si

Fin Pour

Fin Pour

Fin
NiveauNotions abordéesExercices proposés
DébutantVariables, conditions, bouclesCalculs, conversions, affichages
IntermédiaireTableaux, fonctions, chaînesRecherche, moyenne, statistiques
AvancéAlgorithmes complexesTri, récursivité, optimisation
ExpertStructures de donnéesListes, arbres, graphes

Quels exercices faire pour apprendre l’algorithmique ?

Les exercices les plus efficaces commencent par les variables et conditions, puis progressent vers les tableaux, chaînes de caractères, fonctions et algorithmes de tri.

Existe-t-il des exercices corrigés de programmation par niveau ?

Oui. Une progression efficace propose des exercices débutants, intermédiaires et avancés avec corrections détaillées et schémas de résolution.

Comment progresser rapidement en programmation ?

La pratique régulière d’exercices corrigés permet de développer la logique, la capacité d’analyse et la maîtrise des structures fondamentales.

error: Content is protected !!