Aller au contenu

Programmation C source/itérations

Un livre de Wikilivres.
Programmation C source
Programmation C++
Programmation C++
Sommaire
Modifier ce modèle
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	printf("----------------------------------------\n");
	printf(" Boucle for\n");
	printf("----------------------------------------\n");

	#if 0
	 for (initialisation ; condition ; itération)
	 bloc
	#endif

	/* Une boucle for commence par l' initialisation, puis exécute le bloc de code tant
	   que la condition est vérifiée et en appelant l'itération après chaque bloc. */

	int i;
	for (i = 0; i < 3; i++)
	{
		printf("i = %d\n", i);
	}

	/* La norme C99 permet maintenant de déclarer des variables dans la partie
	   initialisation de la boucle for. Ces variables ne peuvent qu'être de classe
	   automatic ou register. Leur portée est limitée à la boucle. Elles n'interfèrent
	   pas avec les variables de même nom déclarées en dehors de la boucle. Leur
	   utilisation pourrait conduire à de possibles optimisations du code par le
	   compilateur. */

	// En C99 :
	for (int j = 0; j < 3; j++)
	{
		printf("j = %d\n", j);
	}

	// Le bloc de code étant réduit à une instruction, on aurait pu écrire :
	for (int k = 0; k < 3; k++)
		printf("k = %d\n", k);

	int l = 0;
	for( ; l != 1; l = rand() % 4)
	{
		printf("je continue\n");
	}
	/* cet exemple montre plusieurs choses :

	   1. l'initialisation de la boucle a été omise, en fait n'importe laquelle des trois
	      parties peut l'être (et même les trois à la fois, ce qui résulte en une boucle
	      infinie) ;
	   2. l'expression itération est réellement une expression, on peut y faire appel à
	      des fonctions ;
	   3. le nombre d'itérations n'est pas fixe, le programme affichera « je continue »
	      un nombre (pseudo-)aléatoire de fois. */

	printf("\n----------------------------------------\n");
	printf(" Boucle while\n");
	printf("----------------------------------------\n");

	#if 0
	 while (condition)
		bloc
	#endif

	// Une boucle while exécute le bloc d'instructions tant que la condition est vérifiée.

	int m = 0;
	while (m < 3)
	{
		printf("m = %d\n", m);
		m = m + 1;
	}

	printf("\n----------------------------------------\n");
	printf(" Boucle do-while\n");
	printf("----------------------------------------\n");

	#if 0
	 do
		bloc
	 while (condition);
	#endif

	/* Cette boucle est une légère variante de la précédente. Elle exécute donc le bloc
	   au moins une fois, et ce jusqu'à ce que la condition soit fausse (ou tant que la
	   condition est vraie). */

	int n = 0;
	do
	{
		printf("n = %d\n", n);
		n = n + 1;
	} while (n < 3);

	char c;
	do
	{
		printf("Veuillez taper la lettre 'o'\n");
		scanf("%c", &c);
		getchar();
	} while (c != 'o');
	/* Tant que l'utilisateur n'aura pas tapé la lettre o, le programme redemandera de
	   taper la lettre. */

	printf("\n----------------------------------------\n");
	printf(" Arrêt et continuation des boucles\n");
	printf("----------------------------------------\n");

	/* Il arrive fréquemment qu'en évaluant un test à l'intérieur d'une boucle, on
	   aimerait arrêter brutalement la boucle ou alors « sauter » certains cas non
	   significatifs. C'est le rôle des instructions break et continue. */

	/* break permet de sortir immédiatement d'une boucle for, while ou do-while. À noter
	   que si la boucle se trouve elle-même dans une autre boucle, seule la boucle où le
	   l'instruction break se trouvait est stoppée. */

	/* continue permet de recommencer la boucle depuis le début du bloc. Dans le cas de
	   la boucle for, le bloc lié à l'incrémentation sera exécuté, puis dans tous les
	   cas, la condition sera testée. */

	printf("\n----------------------------------------\n");
	printf(" Saut inconditionnel (goto)\n");
	printf("----------------------------------------\n");

	/* Cette instruction permet de continuer l'exécution du programme à un autre
	   endroit, dans la même fonction. On l'utilise de la manière suivante : */

	goto label;

	/* Où label est un identificateur quelconque. Cet identificateur devra être défini
	   quelque part dans la même fonction, avec la syntaxe suivante : */

	label:

	/* Ce label peut être mis à n'importe quel endroit dans la fonction, y compris avant
	   ou après le goto, ou dans un autre bloc que là où sont utilisés la ou les
	   instructions goto pointant vers ce label. Les labels doivent être uniques au sein
	   d'une même fonction, mais on peut les réutiliser dans une autre fonction. */

	/* Un cas où l'emploi d'une instruction goto est tout à fait justifié, par exemple,
	   est pour simuler le déclenchement d'une exception, pour sortir rapidement de
	   plusieurs boucles imbriquées. */

	#if 0
	 void boucle(void)
	 {
		while (1)
		{
			struct Evenement_t * event;
			attend_evenement();
			while ((event = retire_evenement()))
			{
				switch (event->type) {
					case FIN_TRAITEMENT:
						goto fin;
					/* ... */
				}
			}
		}
		fin:
		/* ... */
	 }
	#endif

	/* Dans ce cas de figure, il serait possible d'utiliser aussi un booléen qui indique
	   que le traitement est terminé, pour forcer la sortie des boucles. L'utilisation
	   de goto dans cet exemple ne nuisant pas à la lisibilité du programme et étant
	   tout aussi efficace, il est tout à fait légitime de l'utiliser.

	   Il faut cependant noter que cette instruction est souvent considérée comme à
	   éviter. */

	return 0;
}