LES BOUCLES

DANS LE LANGAGE C

Présenté par Willrich-Moritz Olivier, DEUG TI option EEA, juin 98


SOMMAIRE

  1. Les boucles
    1. Présentation générale des boucles
    2. La boucle while (structure 'tant que')
    3. La boucle do...while (structure 'faire tant que')
    4. La boucle for (structure pour)
    5. Comment choisir une boucle ?
  2. Les sorties anticipées (break-continue)
    1. L'instruction break
    2. L'instruction continue
  3. La récursivité
  4. Programme récapitulatif

INTRODUCTION

L'étude faite dans ce rapport est celle des différentes boucles, la récursivité, les boucles imbriquées dans le langage C. Elle comporte un cours, des exemples, ainsi qu'un programme complet d'application des boucles dans les suites numériques. Le cours est systématiquement suivi d'exemples. Les différents exemples d'application des boucles portent sur le calcul de la factorielle d'un nombre pour montrer ce qui les différentient les unes des autres.

Rappel : Les instructions

Une instruction peut être :


LES BOUCLES

Présentation générale des boucles

Par définition, une boucle est une suite d'instructions répétées jusqu'à ce que la condition de sortie soit vérifiée. En C, on devra spécifier la condition de continuation (complémentaire de la condition de sortie). On va donner une instruction, puis on va demander au programme de répéter cette instruction tant que la condition (qu'on a définie) est vraie.

Il existe trois types de boucles :

La boucle while (structure 'tant que')

On la place dans un programme de la façon suivante :

  while (expression)
    Instruction ;

Elle évalue d'abord l'expression (la condition) entre parenthèses. Si la condition est vraie, elle exécute l'instruction. Puis elle teste de nouveau la condition et cela jusqu'à ce que la condition devienne fausse. Alors la boucle se termine et le programme passe à la suite (ou s'arrête, si c'est la dernière instruction).

Exemple d'utilisation : Calcul de la factorielle d'un nombre

int fact(int n)
  {
    int r=1;
    while (n>1)
      {
      r= r * n - -;
      }
    return (n);
  }

La boucle do...while (structure 'faire tant que')

On la place dans un programme de la façon suivante :

  Do
    Instruction
  While (expression);

L'instruction s'exécute, puis l'expression est évaluée. Si elle est vraie, on effectue de nouveau l'instruction, et ainsi de suite.

Exemple : calcul de la factorielle d'un nombre

int fact(int n)
  {
  int r=1;
  do
    {
    r= r * n- -;
    }
  while(n>1);
  return(r);
  }

La boucle for (structure pour)

On la place dans un programme de la façon suivante :

  for (expression 1; expression 2; expression 3)
    instructions;

Le rôle de l'expression 1 est d'initialiser un paramètre qui contrôle la reprise de la boucle. L'expression 2 est la condition à satisfaire pour continuer l'exécution de la boucle et l'expression 3 sert à modifier la valeur du paramètre initialisé par l'expression 1.

Quand l'instruction for est exécutée, l'expression 2 est évaluée et testée avant chaque parcours de la boucle et l'expression 3 est évaluée à la fin de chaque passage. Ainsi l'instruction for est équivalente à :

  expression 1;
  while (expression 2)
  { instruction; expression 3; }

Exemple : calcul de la factorielle d'un nombre

int fact(int n)
  {
  int r=1, i;
  for (i=n; i>1; i- -)
    r= r * i;
  return(r);
  }

Comment choisir une boucle ?

La boucle for est préférable lorsque l'initialisation et l'incrémentation sont simples, puisqu'elle regroupe les instructions de contrôle en tête de boucle. Elle est la plus simple à mettre en oeuvre lorsque l'on connaît le nombre d'itérations à effectuer.

La boucle do...while, qui teste la condition d'arrêt à la fin, voit donc le corps de la boucle s'exécuter au moins une fois, alors que la boucle while peut ne pas l'exécuter du tout (si la condition est déjà fausse).


LES SORTIES ANTICIPEES (break-continue)

L'instruction break

Elle est utilisée pour mettre fin à une boucle ou sortir d'une instruction de sélection. Elle peut figurer dans les instructions : while, do...while, for (ainsi que switch)

Elle s'écrit tout simplement :

  break ;

sans expression ni instruction imbriquée.

L'instruction continue

Le rôle de l'instruction continue est de suspendre l'itération en cours dans la boucle. La boucle ne se termine pas : ce sont seulement les instructions restantes de l'itération en cours qui sont sautées, et le traitement reprend dans la même boucle au début de l'itération suivante.

(continue et break ont donc un rôle totalement différent).

L'instruction continue peut figurer dans les trois boucles : while, do...while, for, et elle s'écrit :

  continue;

sans expression ni instruction imbriquée.


LA RECURSIVITE

La récursivité est le fait qu'une fonction s'appelle elle-même. C'est à dire qu'on crée une fonction qui a comme instruction de rappeler cette même fonction jusqu'à une certaine condition de sortie.

On utilise la récursivité à la place des boucles uniquement quand celles-ci ne peuvent être utilisées, car le récursivité prend beaucoup de temps et de mémoire pour être exécutée.

Exemple d'application : calcul de la factorielle

  int fact(int n)
    {
    if (n>1) return (n * fact(n-1));
    else return(1);
    }
 

PROGRAMME

Utilisation des boucles while, do...while, et for pour le calcul de la somme d'une suite numérique de raison 1, ainsi que par récursivité.

Le programme calcule la somme des N premiers termes d'une suite numérique de raison 1, c'est à dire 1+2+3+...+N.

De plus, une fonction nous donne le temps mis par chaque boucle pour le calcul des sommes (en millisecondes). Néanmoins, pour que le temps mesuré soit significatif, il faut que le nombre choisi pour le calcul de la somme soit supérieur à 500 000 (sur un pentium 200). On remarque que les durées sont assez proches. En utilisant des fonctions spécifiques à votre compilateur, vous pourriez utiliser une unité de temps plus précise, la ms étant la seule normalisée en ANSI C.

Remarque : Ce type de calcul déconseille la récursivité. En effet, la récursivité permettrait de calculer cette somme, mais dans des temps très importants et de plus l'ordinateur indique un message d'erreur (dépassement capacité mémoire) dés que le nombre choisi dépasse 5000.

Programme :

# include<stdio.h>
# include <time.h>
# include <sys\timeb.h>

#define limite_pour_recurs 200

typedef float nombre; /* pour dépasser 32000 */

long heure_en_ms(void)
/*nb de ms dans l'heure (pb si passage à l'heure suivante) */
 {
  struct timeb t;
  ftime(&t);
  return((t.time%3600)*1000+t.millitm);
 }

nombre add1(nombre n)
  {
  nombre r=1;
  while(n>1)
   {
   r=r+n--;
   }
  return(r);
  }

nombre add2(nombre n)
  {
  nombre r=1;
  do
   {
   r+=n--; /*cette écriture devrait accélérer un peu */
   }
  while(n>1);
  return(r);
  }

nombre add3(nombre n)
  {
  nombre r=1,i;
  for(i=n;i>1;i--) r=r+i;
  return(r);
  }

nombre add4(nombre n)
  {
  nombre r;
  if (n>1) r=n+add4(n-1);
      else r=1;
  return(r);
  }

void main(void)
  {
  nombre nb;
  printf("Entrez un nombre entier naturel:");
  scanf("%f",& nb);
  printf("La somme du nombre %0.0f avec ses antécédents vaut:\n\n",nb);
  long heure_actu, heure_avant;

  heure_avant = heure_en_ms();
  printf("%0.0f pour la boucle while\n",add1(nb));
  heure_actu = heure_en_ms();
  printf("durée du calcul : %ld ms\n\n",heure_actu-heure_avant);

  heure_avant = heure_en_ms();
  printf("%0.0f pour la boucle do...while\n",add2(nb));
  heure_actu = heure_en_ms();
  printf("durée du calcul: %ld ms\n\n",heure_actu-heure_avant);

  heure_avant = heure_en_ms();
  printf("%0.0f pour la boucle for\n",add3(nb));
  heure_actu = heure_en_ms();
  printf("durée du calcul: %ld ms\n\n",heure_actu-heure_avant);

  if(nb<=limite_pour_recurs)
   {
   heure_avant = heure_en_ms();
   printf("%0.0f pour la récursivité\n",add4(nb));
   heure_actu = heure_en_ms();
   printf("durée du calcul: %ld ms\n\n",heure_actu-heure_avant);
   }

  printf("\n\n");
  }


retour retour au sommaire

Free Web Hosting