Langage C / TP 2: Expressions et Iterations

1. Structures conditionnelles

Cette section illustre l'utilisation des structures conditionnelles du langage C.

1.1. Conditions simples

Exercice C1.

Ecrire un programme un programme tp2-exC01.c qui demande à l'utilisateur de saisir un nombre n et qui affiche "Le nombre <n> est pair." si n est pair et "Le nombre <n> est impair." si n est impair.

Exemple d'exécution:

Saisir un nombre: 2
Le nombre 2 est pair.

Saisir un nombre: 5
Le nombre 5 est impair.

Saisir un nombre: 0
Le nombre 0 est pair.

int main()
{
    int n;
    printf("Saisir un nombre: ");

    scanf("%d", &n);
    
    if (n % 2 == 0)
        printf("Le nombre %d est pair.", n);
    else
        printf("Le nombre %d est impair.", n);

    return 0;
}

 

Exercice C2.

Ecrire un programme un programme tp2-exC02.c qui demande à l'utilisateur de saisir un nombre entier et qui affiche "V" si le nombre est différent de 0 et "F" sinon.
Contrainte:
Interdiction d'utiliser un if.

#include<stdio.h>

int main(void){

    unsigned char a;
    
    scanf("%hhu", &a);
    
    printf("Valeur de verite: %c", a?'V':'F');

}

1.2. Tarification d'un musée

Il y a dans une certaine ville un musée permettant de voir des oeuvres incroyables. Les prix des billets sont les suivants:

Critère Prix
moins de 6 ans Gratuit
6-17 ans 8€
18-25 ans 10€
26-64 ans 15€
65 ans et plus 11€

 Certaines réductions peuvent s'appliquer aux billets, une seule réduction ne pouvant être appliquée à la fois, la plus intéressante pour le visiteur étant choisie:

Critère Réduction
Etudiant ayant moins de 25 ans -30% par personne (non cumulable avec d'autres réductions)
Personnes à Mobilité Réduite (PMR) -15% par personne (non cumulable avec d'autres réductions)

Le musée a de plus des tarifications variant en fonction du jour de la semaine:

Jour Spécificité
Mardi Musée fermé
Samedi +2€ par personne

 

Exercice Musée 1.

Créer un programme musee.c qui permettra d'implanter la gestion de la tarification du musée pour une visite. Le programme contient pour l'instant le code:

#include<stdio.h>

int main(void){


    return 1;
}

 

La première étape dans le calcul d'un tarif est de déterminer le jour de visite.

Exercice Musee 2.

Dans le programme musee.c, demander à l'utilisateur de saisir un jour de visite sous forme de nombre compris entre 1 et 7 et stocker cette valeur dans une variable jour. 

Lors de l'exécution du programme, si le jour saisi est invalide, le programme doit afficher "Jour invalide" et s'arrêter. Si je jour saisi est un jour ou le musée est fermé, le programme doit afficher "Musee ferme" et se terminer également.

Si le jour saisi est valide, afficher ensuite sur le terminal "Jour: <jour>" où <jour> vaut "Lundi" pour 1, "Mardi" pour 2, ..., "Dimanche" pour 7. 

Aide: Un numéro de jour est un nombre entier petit et strictement positif. Le unsigned char est très adapté pour le représenter. De plus, pour saisir un unsigned char depuis un scanf, l'expression "%hhu" doit être utilisée à la place de "%d". 

Exemples d'utilisation

Jour de visite (1 ... 7): 3

Visiteur
  Jour    : Lundi
  
Jour de visite (1 ... 7): 2
Musee ferme

Jour de visite (1 ... 7): 9
Jour invalide

 

#include<stdio.h>

int main(void){

    unsigned char jour;

    printf("Jour de visite (1 ... 7): ");
    scanf("%hhu", &jour);

    if (jour == 2){
        printf("Musee ferme");
        return 0;
    }

    if ((jour <1) || (jour > 7)){
        printf("Jour invalide");
        return 0;
    }

    printf("\n\nVisiteur");
    
    printf("\n  Jour    : ");
    switch(jour){
        case 1: printf("Lundi"); break;
        case 2: printf("Mardi"); break;
        case 3: printf("Mercredi"); break;
        case 4: printf("Jeudi"); break;
        case 5: printf("Vendredi"); break;
        case 6: printf("Samedi"); break;
        case 7: printf("Dimanche"); break;
        default: printf("Inconnu");
    }
    

    return 0;
}

La base d'un tarif est conditionnée à l'age de la personne réalisant la visite.

Exercice Musee 3.

Dans le programme musee.c, ajouter une variable age du type entier adéquat qui contiendra l'âge du visiteur et une variable tarif de type réel qui contiendra le prix de la visite. Ajouter ensuite au programme la saisie de l'âge d'un visiteur. Une fois l'âge saisi, affecter à tarif le prix d'un billet en fonction du jour et de l'âge du visiteur.   

Exemples d'exécution:

Jour de visite (1 ... 7): 3
Age du visiteur: 12

Visiteur
  Jour    : Mercredi
  Age     : 12
  Tarif   : 8.000000
  
Jour de visite (1 ... 7): 6
Age du visiteur: 45


Visiteur
  Jour    : Samedi
  Age     : 45
  Tarif   : 17.000000

#include<stdio.h>

int main(void){

    unsigned char jour;

    unsigned char age;

    float tarif;

    printf("Jour de visite (1 ... 7): ");
    scanf("%hhu", &jour);

    if (jour == 2){
        printf("Musee ferme");
        return 0;
    }

    if ((jour <1) || (jour > 7)){
        printf("Jour invalide");
        return 0;
    }
	
    printf("Age du visiteur: ");
    scanf("%hhu", &age);
	
    // Calcul du tarif e nfonction de l'âge
    if (age < 6)
        tarif=0.0f;
	else if (age <= 17)
        tarif = 8.0f;
	else if (age <= 25)
        tarif = 10.0f;
    else if (age <= 64)
        tarif = 15.0f;
    else
        tarif = 11.0f;

    // Ajout de 2 euros si visite le mardi
    if (jour == 6)
        tarif += 2.0f;

    printf("\n\nVisiteur");
    
    printf("\n  Jour    : ");
    switch(jour){
        case 1: printf("Lundi"); break;
        case 2: printf("Mardi"); break;
        case 3: printf("Mercredi"); break;
        case 4: printf("Jeudi"); break;
        case 5: printf("Vendredi"); break;
        case 6: printf("Samedi"); break;
        case 7: printf("Dimanche"); break;
        default: printf("Inconnu");
    }
    
    printf("\n  Age     : %d", age);

    printf("\n  Tarif   : %f", tarif);

    return 0;
}

 

Pour obtenir le tarif final d'une visite, il faut savoir si le visiteur bénéficie de réductions.

Exercice Musée 4.

Dans le programme musee.c, ajouter les variables etudiant et pmr permettant de savoir si le visiteur est un étudiant ou une Personne à Mobilité Réduite (PMR).

Ajouter au programme la saisie des statuts du visiteur, à savoir s'il est étudiant et s'il est PMR.

Par convention si le visiteur est un étudiant alors etudiant vaut 1 sinon etudiant vaut 0. De la même façon, si le visiteur est PMR alors pmr vaut 1 sinon pmr vaut 0.

Calculer et afficher le tarif final, prenant en compte les réductions. L'affichage final doit être de la forme:

Visiteur
  Jour    : <jour>
  Age     : <age>
  Etudiant: <'O' si etudiant et 'N' sinon>
  PMR     : <'O' si PMR et 'N' sinon>
  Tarif   : <tarif>

Exemples d'exécution

Jour de visite (1 ... 7): 4
Age du visiteur: 18
Le visiteur est-il étudiant (0/1): 1
Le visiteur est-il PMR (0/1): 0


Visiteur
  Jour    : Jeudi
  Age     : 18
  Etudiant: O
  PMR     : N
  Tarif   : 7.000000
  
  
Jour de visite (1 ... 7): 8
Age du visiteur: 28
Le visiteur est-il étudiant (0/1): 1
Le visiteur est-il PMR (0/1): 0


Visiteur
  Jour    : Vendredi
  Age     : 28
  Etudiant: O
  PMR     : N
  Tarif   : 15.000000

 

2. Structures itératives

Cette section illustre l'utilisation simple des structures itératives du langage C.

Exercice 2.1.

Ecrire un programme tp2-ex21.c permettant d’effectuer des opérations entre deux nombres entiers entrés au clavier. L’utilisateur devra saisir au clavier une expression de la forme : a op b, où op est un opérateur à choisir parmi + - * / %. Le programme affichera alors le résultat de l'opération.

Exemple d’exécution

Entrer une opération : 
1 + 2

Le résultat de 1 + 2 est 3

#include <stdio.h>

int main()
{
    char op;
    int a, b, res;
    
    printf("Entrer une opération: ");
    scanf("%d %c %d", &a, &op, &b);
    
    switch(op){
        case '+':
                 res = a+b;
                 break;
        case '-':
                res = a-b;
                break;
        case '*':
                res = a*b;
                break;
        case '/':
                res = a/b;
                break;
        case '%':
                res = a%b;
                break;
        default:
                printf("Operateur %c inconnu", op);
                return 1;
    }
    
    printf("%d %c %d = %d", a, op, b, res);

    return 0;
}

Exercice 2.2.

Ecrire un programme tp2-ex22.c qui reprend le code de l’exercice précédent mais en permettant à l’utilisateur de répéter la saisie d’opération ou d’arrêter. La structure itérative utilisée doit être le while.

Exemple d’exécution

Entrer une opération : 

1 + 2

Le résultat de 1 + 2 est 3

Voulez-vous continuer (O/N) ?
N

#include <stdio.h>

int main()
{
    char op, ok='O';
    int a, b, res;
    
    while(ok == 'O'){
    
        printf("Entrer une opération : ");
        scanf("%d %c %d", &a, &op, &b);
    
        switch(op){
            case '+':
                     res = a+b;
                     break;
            case '-':
                    res = a-b;
                    break;
            case '*':
                    res = a*b;
                    break;
            case '/':
                    res = a/b;
                    break;
            case '%':
                    res = a%b;
                    break;
            default:
                    printf("Operateur %c inconnu", op);
                    return 1;
        }
    
        printf("Le resultat de %d %c %d est %d\n\n", a, op, b, res);
        
        printf("Voulez-vous continuer (O/N) ? ");
        
        getchar();
        scanf("%c", &ok);
    }
    return 0;
}

Exercice 2.3.

Écrire un programme tp2-ex23.c qui calcule le plus petit carré supérieur à un nombre entier saisi par l’utilisateur. Le résultat est affiché sous la forme : « Le plus petit carré supérieur à <nombre> est <resultat> ». La structure itérative utilisée doit être le while.

Exemple d’exécution

Entrer un nombre :
50

Le plus petit carre supérieur a 50 est 64.

#include <stdio.h>

int main()
{
    int nombre, carre=0;
    
    printf("Entrer un nombre: ");
    scanf("%d", &nombre);
    
    for(int i = 0; carre < nombre; i++){
            carre = i*i;
    }
    
    printf("Le plus petit carre supérieur a %d est %d", nombre, carre);
    
    return 0;
}

Exercice 2.4.

Ecrire un programme tp2-ex24.c qui affiche le nombre de chiffres d’un nombre entier saisi par l’utilisateur. La structure itérative utilisée doit être le do … while.

Rappel : Le nombre de chiffres d’un nombre entier n est égal au nombre de divisions réalisées au cours de l’opération suivante : diviser n par 10, si le quotient q est égal à 0 arrêter, sinon, répéter l’opération avec n = q.

#include <stdio.h>

int main()
{
    int nombre;
    unsigned int chiffres=0;
    
    printf("Entrer un nombre: ");
    scanf("%d", &nombre);
    
    do {
        nombre = nombre / 10;
        chiffres++;
    } while(nombre > 0);
    
    printf("Le nombre possede %u chiffres", chiffres);
    
    return 0;
}


Exercice 2.5.

Ecrire un programme tp2-ex25.c qui calcule puis affiche la somme des carrés des entiers de 1 à n où n est un entier strictement positif, saisi par l’utilisateur. Ce programme devra tester si l’entier saisi est valide (> 0) et renvoyer un message d’erreur s’il ne l’est pas. La structure itérative utilisée doit être le for.

#include <stdio.h>

int main()
{
    unsigned int n;
    unsigned int somme=0;
    
    printf("Entrer un nombre: ");
    scanf("%u", &n);
    
    if (n < 1){
        printf("Le nombre saisit doit etre superieur a 1.");
        return 1;
    }
    
    for(int i = 1; i <= n; i++)
        somme += i*i;
        
    printf("La somme des carres de 1 a %d est %d", n, somme);
    
    return 0;
}

3. Itérations et Mathématiques

Représenter des calculs mathématiques en langage C.

Exercice 3.1.

Ecrire un programme tp2-ex31.c qui calcule puis affiche la moyenne empirique d’une série de nombres. Le programme demande à l’utilisateur d’entrer des nombres positifs et s’arrête si l’utilisateur saisit un nombre négatif.

Rappel: Soit $\{x_1,\ \ldots,\ x_n\}$ un ensemble de valeurs, la moyenne empirique, notée $\bar{x}$, est telle que:

$$\bar{x}\ =\frac{1}{n}\ \sum_{i=1}^{n} x_i\ $$

Exemple d’exécution :

Entrer un nombre (<0 pour terminer) : 
1

Entrer un nombre (<0 pour terminer) : 
2

Entrer un nombre (<0 pour terminer) : 
3

Entrer un nombre (<0 pour terminer) : 
-1

La moyenne des nombres est 2.

#include <stdio.h>

int main()
{
    unsigned int n;
    float nombre = 0.0;
    float somme = 0.0;
    
    printf("Entrer un nombre (<0 pour terminer) : ");
    scanf("%f", &nombre);
    
    while(nombre >= 0){
        n += 1;
        somme += nombre;
        
        printf("Entrer un nombre (<0 pour terminer) : ");
        scanf("%f", &nombre);
      
    }
    
    if (n > 0)
        printf("%f", somme / n);
    else
        printf("Pas de nombre saisi.");
    
    return 0;
}

Exercice 3.2.

Soit un trinôme du second degré $ax^{2}\ +\ bx\ +\ c$ où $a$, $b$ et $c$ sont des nombres réels. La résolution de l’équation $ax^{2}\ +\ bx\ +\ c\ =\ 0$ peut être réalisée grâce à la méthode du déterminant.

Soit le discriminant du trinôme, noté $\Delta$, défini tel que $\Delta\ =\ b^{2}\ -\ 4ac$. Selon la valeur de $\Delta$, l’équation :

  • N’admet pas de solution si $\Delta\ <\ 0$.
  • Admet l'unique solution $\frac{-b}{2a}$ si $\Delta\ =\ 0$.
  • Admet deux solutions $\frac{-b\ -\ \sqrt{\Delta}}{2a}$ et $\frac{-b\ +\ \sqrt{\Delta}}{2a}$ si $\Delta\ >\ 0$.

Ecrire un programme trinome.c qui calcule les solutions d'une équation du second degré, $ax^{2}\ +\ bx\ +\ c=0$, où $a$, $b$ et $c$ sont trois entiers entrés au clavier.

Aide: Le fichier en-tête math.h permet d’utiliser la fonction sqrt() qui calcule la racine carrée du nombre donné en paramètre. Lorsque des fonctions de math.h sont utilisées dans un programme C, l’option -lm doit être ajoutée lors de la compilation ce qui donne par exemple pour compiler cet exercice : 

gcc tp2-ex22.c -lm -o tp2-ex22

#include <stdio.h>
#include <math.h>

int main()
{
    
    float a, b, c, delta;
    
    printf("Calcul de ax^2 + bx +c = 0 avec \n");

    printf("a = ");
    scanf("%f", &a);

    printf("b = ");
    scanf("%f", &b);

    printf("c = ");
    scanf("%f", &c);

    // Ce n'est pas un polynome
    if ((a == 0) && (b == 0)){
        printf("Ce n'est pas un polynome");
        return 2;
    }

    // Binome lineaire (bx = 0) ou affine (bx +c = 0)
    if (a == 0){
        printf("Ce binome affine admet %f comme solution", -c/b);
        return 0;
    }

    // Trinome du second degre (ax^2 + bx +c = 0)
    delta = b*b - 4*a*c;

    if (delta == 0){
        printf("Ce trinome admet %f comme solution", -b/(2*a));
    } else if (delta > 0){
        printf("Ce trinome admet %f et %f comme solutions", (-b - sqrt(delta))/(2*a), (-b + sqrt(delta))/(2*a));
    } else {
        printf("Ce polynome n'admet pas de solution");
    }

    return 0;
}

4. Formule du binôme de Newton

La formule de Newton est une formule mathématique donnée par Isaac Newton pour trouver le développement d’une puissance entière quelconque d’un binôme.

Soit un binôme composé des nombres réels $x$ et $y$ et un entier naturel $n$, La valeur $(x\ +\ y)^{n}$ est donnée par :

$$(x\ +\ y)^n=\sum_{k=0}^{n}c_{k}x^{n-k}y^k$$

avec:

$$c_{k}\ =\ \binom{n}{k}\ =\ \frac{n!}{k!\left(n-k\right)!}$$

Où $n!$ représente la factorielle de $n$ définit telle que $n!\ =\ n\times\left(n-1\right)\times\cdots\times1$.

Par exemple, en utilisant la formule du binôme de Newton, ont peut écrire:

$$(x\ +\ y)^{7}\ =\ x^{7}\ +\ 7x^{6}y\ +\ 21x^{5}y^{2}\ +\ 35x^{4}y^{3}\ +\ 35x^{3}y^{4}\ +\ 21x^{2}y^{5}\ +\ 7xy^{6}\ +\ y^{7}$$

Exercice 4.1.

Ecrire un programme tp2-ex41.c qui affiche le polynôme correspondant au binôme $\left(x\ +\ 1\right)^{n}$, $n$ étant un entier positif saisit au clavier. Il est interdit d’utiliser des fonctions.

Rappel: L’écriture polynomiale d’un binôme $\left(x+1\right)^n$ est de la forme $c_nx^n\ +\ \ c_{n-1}x^{n-1}\ +\ \cdots\ +\ c_{k}x^{n-k}\ +\ \cdots\ +\ c_1x\ +\ c_0$ où $c_{k}$ est le coefficient d’ordre $k$ du polynôme.

Exemple d'exécution:

Entrer une valeur pour n: 

7

(x+1)^7 = x^7 + 7x^6 + 21x^5 + 35x^4 + 35x^3 + 21x^2 + 7x + 1

#include <stdio.h>
#include <math.h>

int main()
{
    
  int n;
  
  int nf; // n!
  
  int kf; // k!

  int nkf; // (n-k)!
  
  int ck; // ck, k ieme coeeficient du polynome
  
  printf("Entrer n: ");
  scanf("%d", &n);

  // S'assurer que n est positif ou nul
  if (n < 0){
      printf("n doit etre positif ou nul.");
      return 1;
  }

  // Cas ou n = 0
  // (x + y)^0 = 1
  if (n == 0){
      printf("(x + y)^0 = 1");
      return 0;
  }

  // Cas général

  // calcul de n! (N'est necessaire qu'une seule fois)
  // ATTENTION: 0! = 1
  if (n == 0){
    nf = 1;
  } else {
    nf = 1;
    for(int i = 2; i <= n; i++)
      nf = nf*i;
  }
  
  // Debut de l'affichage
  // Quand k = 0, k! = 0 et (n-k)! = n!
  // on a donc c0 = n! / n! = 1 quoi qu'il arrive
  printf("(x + 1)^%d = 1", n);
  
  // Calcul des coefficients ck a partir de k = 1 et jusqu'a n-1 
  // (voir pourquoi après le for) ---------------------
  for(int k = 1; k <= n-1; k++){                     
      
      // calcul de k!
      kf = 1;
      for(int i = 2; i <= k; i++)
        kf = kf*i;  
        
      // calcul de (n-k)!
      nkf = 1;
      for(int i = 2; i <= (n-k); i++)
        nkf = nkf*i;    
      
      // ck = n! / (k!*(n-k)!)  
      ck = nf/(kf*nkf);
      
      printf(" + %dx^%d", ck, k);
  }

  // Quand k = n, k! = n! et (n-k)! = 0! = 1
  // on a donc cn = n!/n! = 1 quoi qu'il arrive
  printf(" + x^%d", n);

  return 0;
}

Exercice 4.2.

Ecrire un programme tp2-ex32.c qui affiche la valeur d’un binôme $\left(x+y\right)^n$, avec $x$, $y$ et $n$ saisis au clavier ($n$ positif ou nul) en utilisant la formule du binôme de Newton. Aucune fonction ou macro ne doit être utilisée.