« Introduction au langage C/Structures conditionnelles » : différence entre les versions
→Introduction : Liens conseils de codage |
m →Introduction : Erreur lien |
||
Ligne 9 : | Ligne 9 : | ||
Elles sont composées de tests basés sur l'évaluation d'expressions logiques. |
Elles sont composées de tests basés sur l'évaluation d'expressions logiques. |
||
Conseils de codage à respecter : [[b:Conseils de codage en C/ |
Conseils de codage à respecter : [[b:Conseils de codage en C/Lisibilité des sources|c_lis_13]], [[b:Conseils de codage en C/Lisibilité des sources|c_lis_14]], [[b:Conseils de codage en C/Recherche des erreurs#Sortie de boucle (c_rec_2)|c_rec_2]], [[b:Conseils de codage en C/Recherche des erreurs#for pour contrôler les boucles (c_rec_3)|c_rec_3]], [[b:Conseils de codage en C/Recherche des erreurs#Les variables ne doivent pas se masquer (c_rec_11)|c_rec_11]], [[b:Conseils de codage en C/Robustesse des programmes#switch et clause default (c_rob_2)|c_rob_2]]. |
||
== Les expressions logiques == |
== Les expressions logiques == |
Version du 27 juin 2008 à 19:46
Introduction
Les structures de contrôle sont basées sur des tests logiques qui permettent :
- d'aiguiller le déroulement du programme vers un groupe d'instruction;
- de répéter un groupe d'instructions.
Elles sont composées de tests basés sur l'évaluation d'expressions logiques.
Conseils de codage à respecter : c_lis_13, c_lis_14, c_rec_2, c_rec_3, c_rec_11, c_rob_2.
Les expressions logiques
Exemple en français :
Si la pression dépasse 200 kPa alors faire ... sinon faire ... fin de la condition.
- En C, on utilise beaucoup l'algèbre de Boole; les variables logiques (vrai, faux) sont nommées booléennes. La norme C99 a introduit type _Bool pour définir un booléen[1]. Auparavant, il n'existait pas de type spécifique. On utilisait des variables entières de type int.
- Une variable est considérée comme contenant une valeur fausse si elle vaut 0 ou NUL. Pour toutes les autres valeurs, elle est considérée comme contenant une valeur vraie.
- Une expression logique peut inclure des affectations de variables, des appels de fonctions, des comparaisons, des opérations logiques et arithmétiques...
Il est important de bien parenthéser ces expressions et de ne pas en abuser pour préserver la lisibilité du programme.
La confusion entre l'opérateur d'affectation = et l'opérateur de comparaison == est aussi une source fréquente d'erreurs.
Tests logiques
if ... else ...
Cette structure de contrôle permet de réaliser ou non une action, en fonction de la valeur d'une expression logique.
Un exemple :
#include <stdio.h>
#include <stdlib.h>
int main(int argv, char *argv[])
{
int age = 0; //declaration de la variable age.
(void)printf("Quel age avez vous ? ");
(void)scanf("%d", &age); //saisie de l'âge de l'utilisateur
if (age < 18) // Si age inférieur a 18
{
// Partie entre { et } executee si (age<18) est vrai
(void)puts("Vous etes mineur !");
}
else //sinon
{
// Partie entre { et } executee dans le cas contraire
(void)puts("Vous etes majeur !");
}
return EXIT_SUCCESS;
}
Tout d'abord, dans ce code, il faut déclarer une variable, ici age, qui sera utilisée dans l'expression conditionnelle. Le programme demandera ensuite d'entrer un entier stocké dans cette variable.
La partie intéressante :
- On commence à tester la condition (age<18) avec l'instruction
if
. - Si le résultat du test est vrai, on exécute le bloc d'instruction (entre {}) situé immédiatement après l'instruction
if
. - Sinon on exécute le bloc précédé du mot-clé
else
. Ce blocelse
est facultatif.
switch ... case ... default
L'instruction switch permet de se brancher vers un endroit parmi plusieurs autres, en fonction de la valeur d'une expression.
exemple :
switch (a)
{
case 'h':
printHelp();
break;
case 'f':
findWord();
break;
case 'q':
exit(0);
break;
default:
(void)printf("Opération inconnue %c\n", a);
}
Remarques :
- L'instruction de contrôle (dans l'exemple, la variable
a
), doit être pouvoir être représentée par un entier (character, short integer, integer contenant des bits, pour tous signés ou non, ou une valeur définies dans une instructionenum
); la conversion en entier donnera unint
ou ununsigned int
. - L'instruction
break
garantit que l'exécution ne passera pas au case ou default suivant. Son oubli est une source d'erreur fréquente. - La clause
default
sera exécutée si aucune constante des autres (case) précédent ne correspondait à la valeur de l'expression de contrôle; Si vous ne prévoyez pas de clausedefault
statement, rien ne sera alors exécuté par l'instruction switch.
Conditions ternaires
La structure if ... else
peut paraître longue pour des conditions très simple.
Il existe en C des conditions ternaires dites condensées.
Format : (expression) ? expr1 : expr2
- expression est évaluée à l'exécution;
- si vraie (différente de 0), alors l'expression ternaire vaut expr1
- sinon, elle vaut expr2
Voici deux exemples d'utilisation :
char *str;
double pression;
// ...
str = ( age < 18 ) ? "mineur" : "majeur";
pression = (vide) ? 0.0 : pression;
Explications :
- La chaine str vaut "mineur" si la condition age < 18 est vraie, "majeur" sinon.
- La variable pression est affectée à 0.0 si la variable vide est vraie (différente de 0), sinon sa valeur est inchangée.
Remarques qualités
Blocs d'instructions
Dans une instruction de test if ou dans une structure itérative, si une seule instruction doit être exécutée, on pourrait ne pas la placer dans un bloc. Cependant cette pratique est déconseillée :
Programme d'origine (extrait) déconseillé :
if (age < 18) // Si age inférieur a 18
(void)puts("Vous etes mineur !");
else //sinon
(void)puts("Vous etes majeur !");
Programme modifié par la suite :
if (age < 18) // Si age inférieur a 18
(void)puts("Vous etes mineure !");
else //sinon
(void)puts("Vous etes majeur !");
(void)puts("Vous pouvez donc passer votre permis de conduire en France.");
Le programmeur a ajouté une instruction à la clause else, mais cette dernière sera exécutée que le test soit vrai ou faux et ce n'est pas ce qu'il souhaite !
Programme plus sûre :
if (age < 18) // Si age inférieur a 18
{
(void)puts("Vous etes mineur !");
}
else //sinon
{
(void)puts("Vous etes majeur !");
}
instruction switch
- Toute suite d'instruction d'une clause case devrait se terminer par un break.
- Toute instruction switch devrait se terminer par une clause default.
TP
Références