pdf - e-book - archive - github.com

1.4  Traitements conditionnels

On appelle traitement conditionnel une portion de code qui n’est pas exécutée systématiquement, c’est à dire des instructions dont l’exécution est conditionnée par le succès d’un test.

1.4.1  Si ... Alors

Principe

En algorithmique un traitement conditionnel se rédige de la sorte :

Si <condition> alors
                <instructions>
finSi

Si la condition est vérifiée, alors les instructions sont exécutées, sinon, elles ne sont pas exécutées. L’exécution de l’algorithme se poursuit alors en ignorant les instructions se trouvant entre le alors et le finSi. Un traitement conditionnel se code de la sorte :

if (<condition>) 
{
 <instructions>
}

Notez bien qu’il n’y a pas de point-virgule après la parenthèse du if.

Comparaisons

La formulation d’une condition se fait souvent à l’aide des opérateurs de comparaison. Les opérateurs de comparaison disponibles sont :

Par exemple, la condition a == b est vérifiée si et seulement si a et b ont la même valeur au moment où le test est évalué. Par exemple,

#include<stdio.h>

int main()
{
 int i;
 printf("Saisissez une valeur : ");
 scanf("%d", &i);
 if (i == 0)
 {
  printf("Vous avez saisi une valeur nulle\n.");
 }
 printf("Adios !");
 return 0;
}

Télécharger le fichier

fichier source

Si au moment où le test i == 0 est évalué, la valeur de i est bien 0, alors le test sera vérifié et l’instruction printf("Vous avez saisi une valeur nulle.") sera bien exécutée. Si le test n’est pas vérifié, les instructions du bloc délimité par des accolades suivant le if sont ignorées.

Si ... Alors ... Sinon

Il existe une forme étendue de traitement conditionnel, on la note en algorithmique de la façon suivante :

Si <condition> alors
                <instructions>
sinon
                <autresinstructions>
finSi

Les instructions délimitées par alors et sinon sont exécutées si le test est vérifié, et les instructions délimitées par sinon et finSi sont exécutées si le test n’est pas vérifié. On traduit le traitement conditionnel étendu de la sorte :

if (<condition>)
{
 <instructions1>
}
else
{
 <instructions2>
}

Par exemple,

#include<stdio.h>

int main()
{
 int i;
 printf("Saisissez une valeur : ");
 scanf("%d", &i);
 if (i == 0)
 {
  printf("Vous avez saisi une valeur nulle\n.");
 }
 else
 {
  printf("La valeur que vous saisi, "
                "a savoir %d, n'est pas nulle.\n", i);
 }
 return 0;
}

Télécharger le fichier

fichier source

Notez la présence de l’opérateur de comparaison ==. N’utilisez jamais = pour comparer deux valeurs !.

Connecteurs logiques

On formule des conditions davantage élaborées en utilisant des connecteurs et et ou. La condition A et B est vérifiée si les deux conditions A et B sont vérifiées simultanément. La condition A ou B est vérifiée si au moins une des deux conditions A et B est vérifiée. Le et s’écrit && et le ou s’écrit ||. Par exemple, voici un programme C qui nous donne le signe de i× j sans les multiplier.

#include<stdio.h>

int main()
{
 int i, j;
 printf("Saisissez deux valeurs : ");
 scanf("%d %d", &i, &j);
 printf("Le produit de ces deux valeurs est ");
 if ((i < 0 && j < 0) || (i >= 0 &&  j>= 0))
 {
  printf("positif\n.");
 }
 else
 {
  printf("negatif");
 }
 printf(".\n");
 return 0;
}

Télécharger le fichier

fichier source

Accolades superflues

Lorsqu’une seule instruction d’un bloc if doit être exécutée, les accolades ne sont plus nécessaires. Il est possible par exemple de reformuler le programme précédent de la sorte :

#include<stdio.h>

int main()
{
 int i, j;
 printf("Saisissez deux valeurs : ");
 scanf("%d %d", &i, &j);
 printf("Le produit de ces deux valeurs est ");
 if ((i < 0 && j < 0) || (i >= 0 &&  j>= 0))
  printf("positif\n.");
 else
  printf("negatif");
 printf(".\n");
 return 0;
}

Télécharger le fichier

fichier source

Opérateur ternaire

En plaçant l’instruction suivante à droite d’une affectation,

<variable> = (<condition>) ? <valeur> : <autrevaleur> ;

on place valeur dans variable si condition est vérifié, autrevaleur sinon. Par exemple,

max = (i>j) ? i : j ; 

place la plus grande des deux valeurs i et j dans max. Plus généralement on peut utiliser le si ternaire dans n’importe quel calcul, par exemple

  printf("%d\n", (i> (l = (j>k) ? j : k)) ? i : l); 

j = (j>k) ? j : k) place dans l la plus grande des valeurs j et k, donc (i > (l = (j > k) ? j : k)) ? i : l est la plus grande des valeurs i, j et k. La plus grande de ces trois valeurs est donc affichée par cette instruction.

1.4.2  Switch

Le switch en C s’écrit, avec la syntaxe suivante :

switch(<nomvariable>)
{
  case <valeur_1> : <instructions_1> ; break ;
  case <valeur_2> : <instructions_2> ; break ;
  /* ... */
  case <valeur_n> : <instructions_n> ; break ;
  default : /* instructions */
}

N’oubliez surtout pas les break ! Si par exemple, nous voulons afficher le nom d’un mois en fonction de son numéro, on écrit

switch(numeroMois)
{
  case 1 : printf("janvier") ; break ;
  case 2 : printf("fevrier") ; break ;
  case 3 : printf("mars") ; break ;
  case 4 : printf("avril") ; break ;
  case 5 : printf("mai") ; break ;
  case 6 : printf("juin") ; break ;
  case 7 : printf("juillet") ; break ;
  case 8 : printf("aout") ; break ;
  case 9 : printf("septembre") ; break ;
  case 10 : printf("octobre") ; break ;
  case 11 : printf("novembre") ; break ;
  case 12 : printf("decembre") ; break ;
  default : printf("Je connais pas ce mois...");
}

1.4.3  Booléens

Une variable booléenne ne peut prendre que deux valeurs : vrai et faux. Il n’existe pas de type booléen à proprement parler en C. On utilise des int pour simuler le comportement des booléens. On représente la valeur booléenne faux avec la valeur entière 0, toutes les autres valeurs entières servent à représenter vrai.

Utilisation dans des if

Lorsqu’une condition est évaluée, par exemple lors d’un test, cette condition prend à ce moment la valeur vrai si le test est vérifié, faux dans le cas contraire. La valeur entière 0 représente la constante faux et toutes les autres sont des constantes vrai. Observons le test suivant :

if (8)
{
  //...
}

1 est un littéral de type entier dont le valeur est non nulle, donc il représente le booléen vrai. De ce fait, le test if (8) est toujours vérifié. Par contre le test if (0) n’est jamais vérifié.

La valeur vrai

Même si tout entier non nul a la valeur vrai, on prend par défaut la valeur 1. Lorsqu’une condition est évaluée, elle prend la valeur 1 si elle est vérifié, 0 dans le cas contraire. par exemple,

x = (3>2);

On remarque que (3>2) est une condition. Pour décider quelle valeur doit être affectée à x, cette condition est évaluée. Comme dans l’exemple ci-dessus la condition est vérifiée, alors elle prend la valeur 1, et cette valeur est affectée à x.

Connecteurs logiques binaires

Les connecteurs || et && peuvent s’appliquer à des valeurs (ou variables) entières. Observons l’exemple suivant :

x = (3 && 0) || (1);

Il s’agit de l’affectation à x de l’évaluation de la condition (3 && 0) || (1). Comme 3 est vrai et 0 est faux, alors leur conjonction est fausse. Donc (3 && 0) a pour valeur 0. La condition 0 || 1 est ensuite évaluée et prend la valeur vrai. Donc la valeur 1 est affectée à x.

Opérateur de négation

Parmi les connecteurs logiques se trouve !, dit opérateur de négation. La négation d’une expression est vraie si l’expression est fausse, fausse si l’expression est vraie. Par exemple,

x = !(3==2);

Comme 3 == 2 est faux, alors sa négation !(3 == 2) est vraie. Donc la valeur 1 est affectée à x.

1.4.4  Les priorités

Complètons notre tableau des priorités en y adjoignant les connecteurs logiques et les opérateurs de comparaison :

nomsopérateurs
opérateurs unairescast, -, ~, !, ++, --
produit*, /, %
somme+, -
décalage binaire>>, <<
comparaison>, <, >=, <=
égalité==, !=
ET binaire&
OU Exlusif binaire^
OU binaire|
connecteurs logiques&&, ||
if ternaire()?:
affectations=, +=, -=, …

1.4.5  Préprocesseur

Macro-instructions

Le C nous permet de placer à peu près n’importe quoi dans les constantes. Si par exemple, on est lassé d’écrire des instructions de retour à la ligne, il suffit de définir

#define RC printf("\n")

Dans ce cas, toutes les occurrences de RC dans le code seront remplacées par des printf("$\setminus$n"). Par exemple

#include<stdio.h>

#define BEGIN {
#define END }

#define RC printf("\n")
#define AFFICHE_DEBUT printf("Debut")
#define AFFICHE_FIN printf("Fin")
#define AFFICHE_MLILIEU printf("Milieu")
#define RETOURNE_0 return 0


int main()
BEGIN
  AFFICHE_DEBUT;
  RC;
  AFFICHE_MLILIEU; 
  RC;
  AFFICHE_FIN; 
  RC;
  RETOURNE_0;
END

Télécharger le fichier

fichier source

affiche

Debut
Milieu
Fin

Macros paramétrées

Il est possible de paramétrer les instructions du préprocesseur. Par exemple,

#define TROIS_FOIS_N(n) (3 * (n))

va remplacer toutes les occurences de TROIS\_FOIS\_N(...) par (3 * (...)) en substituant aux points de suspension la valeur se trouvant entre les parenthèses de la constante. Par exemple

#include<stdio.h>

#define RC printf("\n")
#define DECLARER_INT(i) int i
#define AFFICHER_INT(i) printf("%d", i)
#define SAISIR_INT(i) scanf("%d", &i)

int main()
{
  DECLARER_INT(k);
  printf("Saisissez un entier : ");
  SAISIR_INT(k);
  printf("Vous avez saisi ");  
  AFFICHER_INT(k);
  RC;
  return 0;
}

Télécharger le fichier

affiche

Saisissez un entier : 4
Vous avez saisi 4