Exercice langage C corrigé les suites

 Exercice 1 :

#include 

int nombre, somme, x;
float moyenne; 

main() {
    nombre = 0;
    somme = 0;

    printf("? ");
    scanf("%d", &x);
    while (x >= 0) {
        nombre = nombre + 1;
        somme = somme + x;

        printf("? ");
        scanf("%d", &x);
    }

    if (nombre > 0) {
       moyenne = (float) somme / nombre; 
       printf("la moyenne est : %f\n", moyenne);
    }
    else
       printf("pour calculer une moyenne il faut au moins un nombre!\n");
}

[1] Il ne faut pas se faire avoir par l’énoncé de l’exercice ! Ce n’est pas parce que le sujet parle d’une suite (x0, x1, x2, …) qu’il faut nécessairement introduire un tableau X et parler de X[0]X[1]X[2], etc. En effet, compte tenu du travail à faire, les valeurs x0, x1, x2, etc. n’ont pas besoin d’exister simultanément et une unique variable simple, appelée ci-dessus x, suffit à les représenter à tour de rôle.

[2] Ce programme est un avatar du problème « traiter une suite de données sans savoir à l’avance combien il y en a ». Sa résolution à l’aide d’une boucle while a été commentée à l’occasion de l’exercice 1.

[3] Les nombres à traiter étant garantis positifs ou nuls, nous n’avons pas eu de mal à déterminer une valeur « intruse » pour indiquer la fin des données. Mais il ne faut pas croire qu’il en sera toujours ainsi ; souvent toutes les données possibles sont valides et on a du mal à trouver comment indiquer la fin de la suite (le moment venu on verra comment mettre à profit des talents cachés de la fonction scanf).

Ce programme illustre un point important mentionné à l’exercice 1 : la marque de fin des données est une donnée invalide qu’il ne faut pas traiter comme les autres. Ici, ce serait une erreur grave que de faire intervenir le nombre négatif de la fin dans le calcul de la moyenne!

[4] Notez enfin un piège subtil qui vous est tendu ici. Les nombres lus étant des entiers, nous avons déclaré de type int les variables x et somme. Tout est fait pour vous pousser à écrire

moyenne = somme / nombre; Attention, erreur !

C’est une erreur, car somme et nombre étant tous deux entiers, la division faite est le quotient par défaut : ce n’est pas ce qu’il faut pour la moyenne (le fait que le membre gauche de l’affectation, moyenne, soit une variable de type float ne rattrape rien, au moment de l’affectation les décimales sont déjà perdues).

Exercice 2 :

Contrairement à l’exercice précédent, il nous faut ici mémoriser tous les termes de la suite pour pouvoir les afficher à l’envers, d’où la nécessité de déclarer un tableau. Deux points importants dans ce genre de situations :

  • estimer correctement une taille maximum bien adaptée aux jeux de données envisagés,
  • vérifier l’absence de débordement au fur et à mesure que le tableau se remplit.
LIRE AUSSI :  Liste exercices en langage C++ 

Ici, la taille maximum nous est explicitement suggérée par l’énoncé, qui indique qu’il n’y aura pas plus de 100 nombres.

Exercice 3 :

[1] Pour commencer il nous faut écarter les solutions inutilement onéreuses, voire ridicules. Chef d’œuvre : lire toutes les données en comptant le nombre d’apparitions de la valeur 0, puis redemander à l’utilisateur de refrapper les données afin de compter le nombre de 1, puis les demander à nouveau pour compter les 2, et ainsi de suite (notre programme sera à la poubelle bien avant le 21ème tour!).

[2] Raffinement de la même idée : lire les données en les mémorisant dans un tableau comme à l’exercice précédent, ensuite parcourir ce tableau 21 fois : une fois pour compter le nombre de valeurs égales à 0, une autre pour compter le nombre de 1, encore une pour compter les 2, etc. Ce programme fonctionnerait correctement et, en principe, suffisamment vite du point de vue de l’utilisateur. Mais le tableau des données peut être de taille importante et il est probablement bien peu efficace de le parcourir 21 fois. De plus, comment déclarer ce tableau alors qu’on n’a aucune indication quant à sa taille ?

[3] Voici un programme qui traite les nombres donnés au vol, c’est-à-dire au moment où ils sont lus, sans avoir besoin d’y revenir dessus. Pour cela il nous faut un tableau de 21 compteurs, pour compter séparément le nombre de fois que se sont produits chacun des 21 événements possibles : x = 0, x = 1, x = 2, etc.

Étant donnée une valeur x, une manière de savoir quel compteur doit être incrémenté est une cascade de if :

if (x == 0)
    compteur[0]++;
else if (x == 1)
    compteur[1]++;
else if (x == 2)
    compteur[2]++; 
...
etc. Or, il y a une simplification évidente

 compteur[x]++;
d'où notre programme :

 #include 

int compteur[21], x, i;

main() {
    for (i = 0; i <= 20; i++)
        compteur[i] = 0;

    printf("? ");
    scanf("%d", &x);
    while (0 <= x && x <= 20) {
        compteur[x]++;

        printf("? ");
        scanf("%d", &x);
    }

    for (i = 0; i <= 20; i++)
        if (compteur[i] > 0)
            printf("nombre de %d : %d\n", i, compteur[i]);
}

Télécharger aussi :

Laisser un commentaire

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