Boucles (suite)

Pour faire évoluer la valeur contenue dans une variable, il faut extraire l'ancienne valeur, faire un calcul pour trouver la nouvelle valeur, puis affecter celle-ci dans la variable.

variable = variable * 2;
Cette série d'étapes est tellement fréquemment employée que le langage C propose des opérateurs dédiés dont la notation est raccourcie :
variable *= 2;
il y a un opérateur raccourci pour chaque opérateur arithmétique, entre.

Remarque Tout comme l'affectation normale, ces opérateurs sont généralement utilisés comme des instructions, c'est à dire qu'ils ont leur propre ligne, qu'ils sont terminés par un point-virgule, et que leur résultat est volontairement ignoré (nous ne parlons pas ici de son effet sur la variable).

Si vous choisissez d'utiliser un tel opérateur au sein d'une expression, sachez que son résultat est égal à la valeur affectée.

Une situation encore plus fréquente est l'incrémentation : lorsque la valeur contenue dans la variable doit être augmentée de 1.

variable += 1;
On dispose d'un opérateur encore plus raccourci dans ce cas :
++variable;
Là encore, cette opération produit un résultat égal à la valeur affectée, qui est le plus souvent ignoré (l'important étant surtout l'effet sur la variable). Mais il existe une variante dont le résultat est l'ancienne valeur de la variable :
variable++;
La décrémentation est assurée de la même façon par les deux opérateurs --.
int i = 12;
printf("%d", i--);
printf("%d", --i);

Dans la bibliothèque standard (et l'en-tête stdlib.h), on trouve une fonction qui permet de choisir un nombre au hasard, avec quelques réserves.

for(i = 0; i < 10; i++) {
  printf("%d\n", rand());
}
La fonction rand (la contraction de random, qui signifie hasard en anglais) produit une valeur différente à chaque appel, choisie (en apparence) aléatoirement entre 0 et une limite supérieure imposée (représentée par la constante RAND_MAX).

Si vous exécutez plusieurs fois l'exemple précédent, vous constaterez que la même liste de valeurs est produite à chaque fois. C'est parce que rien n'est réellement aléatoire dans le fonctionnement normal d'un ordinateur. Pour simuler un choix au hasard, la fonction rand pioche en fait dans une série prédéterminée.

Pour éviter d'être trop prévisible, on peut demander à rand de faire partir la série d'un endroit différent. C'est le but de la fonction srand, qui fixe la graine (le point de départ) du générateur pseudo-aléatoire.

srand(1478245);
for(i = 0; i < 10; i++) {
  printf("%d\n", rand());
}
Ce nouvel exemple produit une liste de valeurs différente, mais plusieurs exécutions obtiennent tout de même un affichage identique. Une technique souvent employée pour faire varier la graine d'une exécution à l'autre consiste à la choisir en fonction de l'heure.

srand(time(NULL));
for(i = 0; i < 10; i++) {
  printf("%d\n", rand());
}
La fonction time, qui est définie dans la bibliothèque standard et dans l'en-tête time.h, renvoie l'heure courante en secondes. Tant qu'il s'écoule au moins une seconde entre deux exécutions, chaque lancement du programme produira donc des valeurs entièrement différentes.

Remarque Les valeurs «aléatoires» ainsi obtenues sont imprévisibles pour un utilisateur moyen, mais un investigateur appliqué peut quand même parvenir à anticiper les résultats, donc cette méthode est insuffisante pour les jeux d'argent ou les systèmes de sécurité !

  1. Devinette. Écrivez un programme qui donne cinq tentatives à l'utilisateur pour deviner un nombre entre 0 et 100. À chaque tentative infructueuse, le programme offrira un indice en affichant + ou -.

    Utilisez des constantes nommées pour représenter le nombre de tentatives et la valeur maximum.

  2. Primarité. Écrivez un programme qui demande à l'utilisateur un entier naturel puis indique si cet entier est premier.

    Remarque Un entier est premier si et seulement si il admet exactement deux diviseurs stricts : 1 et lui-même.

  3. Table. Écrivez un programme qui affiche la table de multiplication.

      X  |   0   1   2   3   4   5   6   7   8   9  10
    -----+--------------------------------------------
      0  |   0   0   0   0   0   0   0   0   0   0   0
      1  |   0   1   2   3   4   5   6   7   8   9  10
      2  |   0   2   4   6   8  10  12  14  16  18  20
      3  |   0   3   6   9  12  15  18  21  24  27  30
      4  |   0   4   8  12  16  20  24  28  32  36  40
      5  |   0   5  10  15  20  25  30  35  40  45  50
      6  |   0   6  12  18  24  30  36  42  48  54  60
      7  |   0   7  14  21  28  35  42  49  56  63  70
      8  |   0   8  16  24  32  40  48  56  64  72  80
      9  |   0   9  18  27  36  45  54  63  72  81  90
     10  |   0  10  20  30  40  50  60  70  80  90 100
    
    Utilisez dans votre programme une constante nommée pour représenter la taille de la table (10 dans l'exemple ci-dessus). Votre programme devra encore fonctionner si on choisit une taille différente en changeant la valeur de cette constante.

  4. Progression. Ecrire un programme qui affiche le nième terme de la suite de Fibonacci, définie par la relation de récurrence suivante :

  5. Figures. Un théorème dû à Lagrange affirme que tout entier naturel peut s'écrire comme la somme de quatre carrés. Par exemple :

    28=25+1+1+1
    28=16+4+4+4
    28=9+9+9+1
    
    Ou encore :
    10=9+1+0+0
    10=4+4+1+1
    
    Écrivez un programme qui demande un entier naturel, et affiche toutes ses décompositions sous la forme d'une somme de 4 carrés (attention, chaque décomposition ne doit apparaître qu'une seule fois).

  6. Facteurs. Écrivez un programme qui demande un entier naturel non nul, et affiche sa décomposition en facteurs premiers. Par exemple,

    Entrez un entier naturel non nul : 280
    280 = 2*2*2*5*7
    
    Remarque Pour tous les entiers naturels, le plus petit diviseur autre que 1 est nécessairement premier.

retour à la page d'accueil

retour au sommet