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.
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
.
La formulation d’une condition se fait souvent à l’aide des opérateurs de comparaison. Les opérateurs de comparaison disponibles sont :
==
: égalité
!=
: non-égalité
<
,
<=
: inférieur à, respectivement strict et large
>
,
>=
: supérieur à, respectivement strict et large
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; }
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.
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; }
Notez la présence de l’opérateur de comparaison
==
. N’utilisez jamais
=
pour comparer deux
valeurs !.
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; }
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; }
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.
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..."); }
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.
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é.
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
.
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
.
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
.
Complètons notre tableau des priorités en y adjoignant les connecteurs logiques et les opérateurs de comparaison :
noms | opérateurs |
opérateurs unaires | cast, -, ~, !, ++, -- |
produit | *, /, % |
somme | +, - |
décalage binaire | >>, << |
comparaison | >, <, >=, <= |
égalité | ==, != |
ET binaire | & |
OU Exlusif binaire | ^ |
OU binaire | | |
connecteurs logiques | &&, || |
if ternaire | ()?: |
affectations | =, +=, -=, … |
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
affiche
Debut Milieu Fin
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; }
affiche
Saisissez un entier : 4 Vous avez saisi 4