• Aucun résultat trouvé

Instructions conditionnelles

N/A
N/A
Protected

Academic year: 2022

Partager "Instructions conditionnelles"

Copied!
29
0
0

Texte intégral

(1)

{!

/* instruction ou bloc d'instructions */!

}!

•  Le bloc d'instructions est exécuté uniquement si l'expression logique est VRAIE

•  Les accolades de début et de fin de bloc ne sont pas nécessaires si une seule instruction est conditionnée

•  Exemples #

int a = 1, b = 0;!

if (a) printf(« %d », a); ! /* le test est VRAI */!

if (b) printf(« %d », b);! /* FAUX */!

if (b<a) { a--; b++; } ! ! /* VRAI */!

if (a == 0) {a = a+b; b--; a = a+b;} /* VRAI */!

if (a = 0) a++; ! ! ! /* FAUX */!

(2)

{!

/* bloc d'instructions */!

}!

else !

{ /* alternative */!

/* bloc d'instructions */!

}!

•  Exemple :#

int i = 0, j = 1;!

!if (i > 0) !

! j++;!

!else !/* alternative : if (i <= 0) { ... } */!

j--;!

(3)

if (i == 0) { /* Bloc d’instructions */ }!

else if (i == 1) { /* Bloc d’instructions */ }!

else if (i == 2) { /* Bloc d’instructions */ }!

else { /* Bloc d’instructions */ }!

•  Les conditions sont évaluées du haut vers le bas jusqu’à ce que l’une d’entre elles soit vraie

•  Le dernier else traite le cas où aucune condition précédente n’est remplie

•  avec switch!

switch <expression>) {!

case <constante1> : <bloc d’instructions> break;!

case <constante2> : <bloc d’instructions> break;!

case <constante3> : <bloc d’instructions> break;!

default : <bloc d’instructions>!

}!

•  Les instructions sont exécutées à partir de l’étiquette de branchement jusqu’au moment où l’on rencontre

« break » ou la fin de « switch ».

•  L’étiquette « default » est branchée si aucune des autres étiquettes ne correspond à la valeur (constante) de l’expression conditionnant « switch »

(4)

condition ? expression1 : expression2

• 

Si la condition est vérifiée, l’expression prend la valeur d’expression1, sinon elle prend la valeur d’expression2.

Exemple :

Max = ( ( a > b ) ? a : b)

(5)

for (<initialisation> ; <expression logique> ; <itération suivante>)!

{!

/* bloc d’instructions */!

}!

!

•  La boucle « for » utilise souvent (comme les autres types de boucle) une variable d’indice de boucle

•  <initialisation>!

•  Quelle valeur de départ doit prendre la variable d’indice de boucle ?

•  Exemple: i = 0!

•  <expression logique>!

•  Le bloc d’instruction est exécuté tant que l’expression logique est VRAIE

•  Exemple: i < 10!

•  <itération suivante>!

•  Quelle instruction pour passer à l’itération suivante ? Progression de la variable d’indice de boucle ?

•  Exemple: i++!

(6)

for(i = 0; i < 10; i++)!

{!

printf(« %d », i+1);!

}!

/* Affiche les 10 premiers entiers naturels */!

•  Possibilité de mettre plusieurs instructions dans les champs

<initialisation> et <itération suivante> (séparation avec une « , »)

int i, j;!

for(i = 0, j = 11; i<10; i+=2, j-=2) ! {!

printf(« %d %d »,i+1, j-1);!

}!

•  Remarque: Si une seule instruction est itérée alors les accolades ne sont pas obligatoires

(7)

while(<expression logique>) ! {!

/* bloc d'instructions */!

}!

!

•  Le bloc d'instructions est exécuté tant que l'expression logique a la valeur VRAI

(8)

Affichage des 10 premiers entiers naturels

int i;!

i = 1;!

while(i <= 10) ! {!

printf(« %d », i); /* cela marche-t-il ? */!

}!

(9)

Affichage des 10 premiers entiers naturels

int i;

i = 1;!

while(i <= 10) ! {!

printf(« %d », i); ! /* NE PAS OUBLIER !*/!

i++; ! /* L'INCREMENT DE LA BOUCLE !*/!

}!

(10)

• 

Exemple

•  Calcul de la partie entière d'un logarithme à base 10 d'un entier positif (on ignore la fin a priori !!!)

int c = 0, m, n;!

scanf (« %d », &n); m = n;!

while (n >= 10) { n /= 10; c++; }!

printf («\n log10(%d) = %d », m, c);!

(11)

•  Similaire à la boucle « while » (à une exception prés)

do {!

/* bloc d instructions *!

} while (<expression logique>);!

!

•  Exécute le bloc d instructions tant que l expression logique est vraie

•  Le test est fait en fin d itération (conséquence : au moins 1 passage dans la boucle)

(12)

•  Exemple

•  Affichage des 10 premiers entiers naturels

int i = 1;!

do {!

printf(« %d », i++);!

} while (i <= 10);!

!

•  Attention: cette boucle est inadaptée dans ce cas !!

(13)

•  L’instruction break provoque une sortie immédiate de la boucle (for, while, do) ou du switch le plus proche

•  L’instruction continue relance immédiatement la boucle dans laquelle elle se trouve

int i, j, c;!

for (i=j=0 ; (c=getchar( )) !=EOF ; i++)!

{!

if (c==  \n  ) break ;!

if (c==  ) continue ;!

j++ ;!

}!

(14)

•  fonction principale « main( ) »

•  printf, scanf, autres...

•  Autres fonctions

• 

Parties de code source qui permettent de réaliser le

même type de traitement plusieurs fois ou sur des objets

différents

(15)

•  Modifier des données globales. Ces données sont dans une zone de mémoire qui peut être modifiée par le reste du programme.

•  Communiquer avec le reste du programme par une interface.

L'appel de la fonction correspond à un échange de données à travers cette interface, au traitement de ces données (dans le corps de fonction), et à un retour de résultat via cette interface.

(16)

ouvrantes et fermantes.

•  Une définition de fonction contient :

•  une interface (un entête)

•  un corps de fonction.

int add(int a, int b) !/*interface-entête*/!

! !{ ! ! ! !/*corps*/!

! ! int c ;!

! ! c=a+b;!

! ! return c;!

! !}!

- type et du nom de la fonction - parenthèse ouvrante

- types et noms des paramètres - parenthèse fermante.

bloc

(17)

<déclaration des variables locales>!

<bloc d instructions>!

<retour de la fonction>!

}!

!

•  <type>

•  N’importe quel type de donnée prédéfini ou pas, pointeur ou non

•  Caractérise le type de valeur qui va être calculée et renvoyée par la fonction

•  <déclaration des variables locales>

•  Toute variable déclarée dans une fonction (y compris la fonction main( )) est connue exclusivement dans cette fonction.

•  <retour de la fonction>

•  Une fonction renvoie toujours une seule valeur. Syntaxe: return(<valeur>);

•  Rq : pas de retour = type void

(18)

•  Syntaxiquement identique à une déclaration de variables

•  Décrit l’ensemble des valeurs (typées) qui doivent être pris en

paramètre par la fonction (à l’appel). Le bloc d’instructions est appliqué sur ces paramètres

•  Exemple : définition d’une fonction « f » prenant en paramètres 2 valeurs de type entier et renvoyant une valeur de type entier

int f(int valeur1, int valeur2)!

!! !{!

… !

! }!

(19)

{ !

v++; ! }!

!

main( ) ! { !

int t = 2;!

f(t);!

}!

Que vaut « t » après l’appel à « f » ?

(20)

main() { int t = 2; f(t); }!

•  2 éventualités

•  Passage de paramètres « par valeur » (par copie)

•  « t » est inchangé dans « main( ) » quelles que soient les modifications qu’il peut subir dans « f( ) » : t vaut 2 après l’appel à f( )!

•  Passage de paramètres « par variable »

•  Les modifications faites à « t » dans « f( ) » sont

préservées dans « main( ) » : t vaut 3 après l’appel à f( )!

(21)

(par copie) !!!!!!

•  la fonction appelante fait une copie de la valeur passée en

paramètre et passe cette copie à la fonction appelée à l'intérieur d'une variable créée dans l'espace mémoire géré par la pile

d'exécution

• 

Exemple :

Définition Appel

int plus(int a,int b) int x=4,y=6,z;

{

a = a + b; z = plus(1,23);

return(a); z = plus(x,y);

}

(22)

les valeurs 1 et 23 sont empilées dans des variables anonymes dont les types correspondent aux types de paramètres de la fonction (dans ce cas deux entiers) ;

•  Etape 2 :

la fonction plus() est appelée, ce qui se traduit par l'empilement de l'adresse de retour et du pointeur de contexte courant. La fonction plus() dispose de deux variables qu'elle connait sous les noms "a"

et "b". Ces deux variables sont les copies des valeurs dont nous avons parlé au point précédent. Elles ont donc pour valeurs initiales respectivement 1 et 23 ;

(23)

mettant la valeur 24 ;

•  Etape 4

la fonction se termine en retournant cette valeur 24, cette valeur est stockée dans un registre du processeur réservé à cet effet ;

•  Etape 5

les variables créées par l'appel sont détruites (l'espace sur la pile est restitué, le pointeur de pile est remis à sa

valeur initiale).

•  Etape 6

la valeur stockée dans le registre du processeur est

affectée à la variable z (correspondant à l'affectation).

(24)

•  même principe en commençant par le calcul des variables x et y et l empilement de ces valeurs

• 

Le passage des paramètres par valeur empêche de

modifier des objets de la fonction appelante, SAUF si la

fonction appelante passe les adresses de ces objets, et

non les objets eux-mêmes (cf. Pointeurs)

(25)

•  déclaration

•  définition

•  prototype

• 

Déclaration : annoncer que tel identificateur correspond à une fonction, qui renvoie tel type

• 

Définition : une déclaration où, en plus, on donne le code de la fonction elle-même

• 

Prototype : déclaration de fonction où le type des

arguments est également donné

(26)

•  int f(void);/* declaration de f( ), renvoyant un int, prototype (0 arg) */

•  int f(void) /* definition de f( ) avec declaration avec prototype */

{ return 42; }

•  int f(x) /* definition de f( ) avec declaration sans prototype */

int x; { return x; }

•  int f( ) /* definition de f( ) avec declaration sans prototype */

{ return 42; }

(27)

•  utiliser des définitions et déclarations avec prototype

• 

Comme tout objet en C, une fonction doit être déclarée avant son utilisation.

• 

Où déclarer les prototypes ?

•  Un prototype de fonction doit être déclaré avant l'utilisation de la fonction

•  il est conseillé de regrouper tous les prototypes d'un module (fichier xxx.c) dans un en-tête (<xxx.h>). Ce dernier n'a plus alors qu'à être inclus dans le code qui utilise ces fonctions. C'est le cas des

fonctions de la bibliothèque standard.

(28)

• 

void f( ) {!

…!

f( )!

…!

}!

• 

Approche similaire à la notion de récurrence employée en mathématiques

• 

La « récursion » se distingue de l itération.

•  A priori

•  Tous les problèmes peuvent être traités de façon récursive

•  Tous les problèmes peuvent également être traité de façon itérative

(29)

retournant aucun résultat.

•  « n » sera le paramètre de la fonction

•  Itérativement void f(int n) {!

!! ! int i;!

!! ! for(i = 1; i <= n; i++){!

printf(« %d », i); ! }!

!! ! } !!

•  Récursivement void f(int n) {!

if (n > 1) f(n-1);!

printf(« %d », n);!

}!

Références

Documents relatifs

L’usage croissant des échanges de données personnelles en matière de sécurité à l’échelle européenne et transnationale pose des questions centrales tant du point de vue des

Il est donc intéressant de connaître le niveau de communication non verbale lié à l’acquisition des gestes communicatifs chez l’enfant autiste à travers l’imitation

trouve sur une droite, la direction du déplacement est constante, mais la norme de la vitesse varie au cours du temps (augment ou diminue). L’accélération (ou la

Remarque : dans l’exemple 2 on a fait trois tests systématiquement alors que dans l’exemple 1, si le nombre est négatif on ne fait qu'un seul test. Conseil : utiliser les

Copyright © www.mesmaths.com

Ce système sera constitué : ● d’une ​partie matérielle​ permettant ○ l’acquisition d’un certain nombre d’échantillons à un rythme déterminé ○ la possibilité

Identifier dans la liste des personnes ayant le droit de vote, une personne avec certitude ayant séjourné dans cet hôpital et quelle en est la raison.. Préciser

Il y a plusieurs types de traitement des données qui sont organisées en tables comme : - L’affichage qui peut correspondre à une mise en forme, une couleur….. - La recherche