• 20 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

J'ai tout compris !

Mis à jour le 21/06/2013

Conditions, boucles et fonctions

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Dans ce chapitre, vous allez aller un peu plus loin dans la programmation Objective-C. Au fil des pages, vous apprendrez à :

  • effectuer des tests pour exécuter une ou plusieurs instructions si une condition est remplie ;

  • faciliter la répétition d'instructions ;

  • définir et exécuter des fonctions pour exécuter des tâches bien précises.

Ça n'a l'air de rien comme ça, mais à la fin de ce chapitre vous serez capables de créer de petits programmes.

Conditions

En programmation, on utilise des conditions pour tester la valeur des variables. Selon le résultat obtenu, zéro, une ou plusieurs instructions peuvent alors être exécutées.
Avant de nous intéresser aux conditions, nous allons passer un peu de temps avec les opérateurs de comparaison. En effet, ces opérateurs sont très souvent utilisés dans des conditions. Par exemple pour savoir si une variable est supérieure à une autre, ou encore si une variable est égale à zéro.

Opérateurs de comparaison

Les opérateurs de comparaison (dits logiques) sont très importants. Ils permettent de comparer des valeurs entre elles. Par leur intermédiaire, vous pourrez savoir qui de Pierre ou de Jean est le plus grand, ou encore si les prunes sont plus chères au kilo que les bananes. J'ai regroupé tous les opérateurs logiques dans le tableau suivant.

Opérateur

Signification

!

Non

<

Inférieur à

>

Supérieur à

==

Egal à

<=

Inférieur ou égal à

>=

Supérieur ou égal à

!=

Différent de

&&

Et logique (vrai si les deux opérandes ont pour valeur true)

||

Ou logique (vrai si au moins un des deux opérandes a pour valeur true)

^

Ou exclusif (vrai si un seul des deux opérandes a pour valeur true)

Maintenant, nous allons mettre en pratique les opérateurs de comparaison en les utilisant dans des conditions.

if

Pour tester une condition, l'opérateur de base est le if ( « si » en français). Par exemple, imaginez que la variable pointure contienne une pointure de chaussures. Si la pointure est inférieure ou égale à 30, vous voulez afficher un message qui dit « Vous devez vous chausser au rayon enfants ». Vous écrirez quelque chose comme ceci :

if (pointure <= 30)
{
NSLog(@"Vous devez vous chausser au rayon enfants");
}

Si la condition est vérifiée (si la variable pointure est inférieure ou égale à 30), alors ce qui se trouve entre les accolades sera exécuté. Les plus observateurs d'entre vous auront sans doute remarqué que la condition ainsi que les accolades la délimitant ne se terminent pas par un « ; ». C'est tout à fait normal, ce ne sont pas des instructions.

Bien entendu, il est possible d'exécuter plusieurs instructions :

if (pointure <= 30)
{
NSLog(@"Vous avez de petits pieds");
NSLog(@"Vous devez vous chausser au rayon enfants");
// etc.
}
if (pointure <= 30)
NSLog(@"Vous devez vous chausser au rayon enfants"); // Ici les accolades sont facultatives

Que diriez-vous d'un peu de pratique ?
Ouvrez le projet de test créé au chapitre précédent. Si vous ne l'avez plus, pas de panique, vous pouvez en créer un nouveau, il fera aussi bien l'affaire.

Cliquez sur ViewController.m dans le volet de navigation et complétez la méthode viewDidLoad comme suit :

- (void)viewDidLoad
{
[super viewDidLoad];
int pointure = 29;
if (pointure <= 30)
{
NSLog(@"Vous avez de petits pieds");
NSLog(@"Vous devez vous chausser au rayon enfants");
}
}

À la ligne 4, la variable pointure est initialisée à 29. Mais rien ne vous empêche de choisir une autre valeur.

Exécutez l'application en cliquant sur Run. Si nécessaire, affichez le volet de déboguage en cliquant sur Hide or show the Debug area. Voici ce qui devrait s'afficher dans le volet de déboguage :

Attaching to process 877.
2011-11-18 11:35:20.428 test[877:f803] Vous avez de petits pieds
2011-11-18 11:35:20.430 test[877:f803] Vous devez vous chausser au rayon enfants

else

Il arrive parfois que l'on doive exécuter une instruction si une condition est remplie, et une autre instruction dans le cas contraire. Pour cela, on a recours au mot-clé else (c'est-à-dire « sinon » en français) :

if (pointure <= 30)
NSLog(@"Vous devez vous chausser au rayon enfants");
else
NSLog(@"Vous devez vous chausser au rayon adultes");

elseif

Imaginez maintenant que vous vouliez exécuter :

  • une première instruction si la pointure est inférieure ou égale à 30 ;

  • une deuxième instruction si la pointure est supérieure à 45 ;

  • une troisième instruction si la pointure ne répond à aucune de ces deux conditions.

Pour cela, vous utiliserez les mots clés if (si), else if (sinon si) et else (sinon) :

if (pointure <= 30)
NSLog(@"Vous devez vous chausser au rayon enfants");
else if (pointure > 45)
NSLog(@"Vous devez vous chausser sur mesure");
else
NSLog(@"Vous devez vous chausser au rayon adultes");

Il est bien évidemment possible d'utiliser plusieurs else if. Vous pourriez très bien écrire quelque chose comme ceci, même si l'intérêt de ce code est limité :

if (pointure <= 30)
NSLog(@"Vous devez vous chausser au rayon enfants");
else if (pointure == 36)
NSLog(@"Vous chaussez du trente six");
else if (pointure == 37)
NSLog(@"Vous chaussez du trente sept");
else if (pointure == 38)
NSLog(@"Vous chaussez du trente huit");

N'hésitez pas à tester ce code (n'oubliez pas de déclarer votre variable pointure) en changeant ses valeurs. C'est comme ça qu'on apprend !

Plusieurs conditions dans un test

Les opérateurs logiques && (et), || (ou) et ! (non) peuvent être utilisés dans une condition. Par exemple, pour tester si la pointure est supérieure à 35 et inférieure à 42, vous écrirez ceci :

if (pointure >35 && pointure <42)

D'après-vous, que devriez-vous écrire pour tester si la pointure est comprise entre 35 et 42, mais différente de 40. Je vous laisse quelques instants…

Voilà la solution :

if (pointure >35 && pointure <42 && pointure != 40)

Facile, non ?

Il est parfois nécessaire d'utiliser des parenthèses dans un test complexe pour modifier l'ordre d'exécution des éléments qui composent le test. Par exemple, les deux tests suivants ne sont pas équivalents :

if ((a+3)/4 < 10)
if (a+3/4 < 10)

Le premier test ajoute 3 à la variable a, divise cette somme par 4 et compare le résultat obtenu à 10. Le deuxième test ajoute 3/4 à la variable a et compare le résultat obtenu à 10.

À titre d'information, voici l'ordre d'exécution des principaux opérateurs, du plus prioritaire vers le moins prioritaire :

Nom

Opérateur

Parenthèses

()

Opérateur de changement de signe

-

Opérateurs ++ et -- utilisés en préfixe

++ et --

Négation

!

Multiplication, division et modulo

*, / et %

Addition et soustraction

+ et -

Inférieur, inférieur ou égal, supérieur, supérieur ou égal

<, <=, >, >=

Egal, différent de

== et !=

Et logique

&&

Ou logique

||

Affectation

=

L'instruction switch

Il existe une variante de l'instruction if… elseif… else… : l'instruction switch. Voici sa syntaxe :

switch (variable)
{
case valeur1:
une ou plusieurs instructions;
break;
case valeur2:
une ou plusieurs instructions;
break;
case valeur3:
une ou plusieurs instructions;
break;
...
default:
une ou plusieurs instructions;
break;
}

Où :

  • variable est la variable utilisée dans le test ;

  • les case valeur1:, case valeur2:, etc. correspondent aux valeurs à tester ;

  • une ou plusieurs instructions sont des instructions définies sur une ou plusieurs lignes;

  • les instructions situées après le mot default sont exécutées lorsqu'aucune des conditions spécifiées dans les instructions case n'a été vérifiée ;

  • break marque la fin des instructions qui suivent une instruction case ou default.

L'instruction switch est un peu plus complexe que celles que nous avons vu jusqu'ici. Un exemple va vous aider à en comprendre le fonctionnement.

Considérez le test suivant :

if (pointure == 30)
NSLog(@"Vous devez vous chausser au rayon enfants");
else if (pointure ==36)
NSLog(@"Vous chaussez du trente six");
else if (pointure ==37)
NSLog(@"Vous chaussez du trente sept");
else if (pointure ==38)
NSLog(@"Vous chaussez du trente huit");
else
NSLog(@"Vous ne chaussez pas du 30, 36, 37 ou 38");

Vous pourriez tout aussi bien écrire :

switch (pointure)
{
case 30:
NSLog(@"Vous devez vous chausser au rayon enfants");
break;
case 36:
NSLog(@"Vous chaussez du trente six");
break;
case 37:
NSLog(@"Vous chaussez du trente sept");
break;
case 38:
NSLog(@"Vous chaussez du trente huit");
break;
default:
NSLog(@"Vous ne chaussez pas du 35, 36, 37 ou 38");
break;
}

Encore une fois, n'hésitez pas à tester ce code en modifiant ses valeurs.

Boucles

En programmation, il est souvent nécessaire d'exécuter à plusieurs reprises une instruction ou un groupe d'instructions, par exemple tant qu'une condition n'est pas vérifiée.

Supposons que vous vouliez afficher à dix reprises le mot « Bonjour ». Comment vous y prendriez-vous ? La première idée qui vient à l'esprit consiste à répéter dix fois l'instruction d'affichage NSLog :

NSLog(@"Bonjour");
NSLog(@"Bonjour");
NSLog(@"Bonjour");
NSLog(@"Bonjour");
NSLog(@"Bonjour");
NSLog(@"Bonjour");
NSLog(@"Bonjour");
NSLog(@"Bonjour");
NSLog(@"Bonjour");
NSLog(@"Bonjour");

Imaginez maintenant que vous vouliez répéter 100 fois l'affichage du mot « Bonjour ». Allez-vous écrire cent fois la même instruction ? Heureusement non ! Il existe plusieurs solutions bien plus élégantes : vous utiliserez pour cela une boucle for, while ou do&nbsp;while.

Dans tous les cas, la procédure est la même. Regardez la figure suivante, elle représente le fonctionnement d'une boucle.

Image utilisateur

Voici ce qui se passe:

  • l'ordinateur lit les instructions de haut en bas ;

  • arrivé à la fin de la boucle, il retourne à la première instruction ;

  • il lit de nouveau les instructions de haut en bas ;

  • il repart à la première instruction ;

  • etc

Malheureusement il y a un problème : la boucle est infinie! Si on ne l'arrête pas, l'ordinateur va lire les instructions ad vitam æternam. Heureusement, les conditions vont nous aider. Lorsqu'on crée une boucle, on indique une condition pour sortir de la boucle.

La boucle for

La boucle for est là pour vous éviter une luxation du poignet. Voici sa syntaxe :

for (début; fin; incrément)
{
//Une ou plusieurs instructions
}

Trois paramètres sont passés à l'instruction for :

  • début représente la valeur initiale du compteur de boucle ;

  • fin représente la condition qui permet de décider si la boucle se poursuit ou se termine ;

  • incrément modifie la valeur du compteur de boucle à la fin de chaque tour de boucle.

Tout ceci vous semble peut-être obscur. Rassurez-vous, un petit exemple va vite clarifier les choses. Considérez le code suivant :

int compteur;
for (compteur = 0; compteur < 100; compteur++)
{
NSLog(@"Bonjour");
}

Lors de la première exécution de la boucle, la variable entière compteur est initialisée à 0. La condition compteur < 100 est alors vérifiée, puisque 0 < 100. L'instruction NSLog est exécutée, l'ordinateur repart au début de la boucle.

Lors de la deuxième exécution de la boucle, le compteur est incrémenté de 1 (compteur++). Il a donc pour valeur 1. La condition étant vérifiée (1 < 100), l'instruction NSLog est de nouveau exécutée.

Ainsi de suite jusqu'à ce que compteur soit égal à 100. Dans ce cas, la boucle for prend fin et le programme continue de s'exécuter. Si vous faites le compte, l'instruction NSLog aura été exécutée … 100 fois, ce qui est exactement l'effet recherché.

Etant donné qu'une seule instruction est exécutée dans la boucle for, les accolades ne sont pas obligatoires. Dans notre exemple, vous auriez donc tout aussi bien pu écrire :

for (compteur = 0; compteur < 100; compteur++)
NSLog(@"Bonjour");

Que diriez-vous d'un peu de pratique?

Toujours dans votre projet test, cliquez sur ViewController.m dans le volet de navigation. Repérez la méthode viewDidLoad et complétez-la comme suit :

- (void)viewDidLoad
{
[super viewDidLoad];
int compteur;
for (compteur = 0; compteur < 100; compteur++)
NSLog(@"Bonjour");
}

Exécutez l'application en cliquant sur Run. Très rapidement, cent lignes contenant le mot "Bonjour" sont affichées dans le volet de déboguage :

Attaching&nbsp;to&nbsp;process&nbsp;2440.
2011-11-18&nbsp;15:22:32.967&nbsp;test[2440:f803]&nbsp;Bonjour
...
2011-11-18&nbsp;15:22:33.048&nbsp;test[2440:f803]&nbsp;Bonjour

La boucle while

La boucle while est une variante de l'instruction for. Elle exécute une ou plusieurs instructions tant qu'une condition est vérifiée. Voici sa syntaxe :

while(condition)
{
//Une ou plusieurs instructions
}

Voyons comment résoudre notre problème précédent avec une boucle while.

int compteur = 0;
while (compteur < 100)
{
NSLog(@"Bonjour");
compteur++;
}

La première instruction initialise à 0 la variable compteur.

La boucle while se poursuit jusqu'à ce que la variable compteur soit supérieure ou égale à 100 (while (compteur < 100)). Lors de l'entrée dans la boucle, compteur vaut 0.

Les instructions entre les accolades sont donc exécutées: la première affiche le texte « Bonjour », la deuxième incrémente d'un la variable compteur, qui vaut alors 1.

Après l'incrémentation, la condition compteur < 100 est toujours vérifiée, puisque compteur vaut 1. Les instructions à l'intérieur des accolades sont donc exécutées une nouvelle fois.

Ainsi de suite jusqu'à ce que compteur soit égal à 100.

N'hésitez pas à tester le fonctionnement de la boucle while. Dans votre projet test, repérez la méthode viewDidLoad et complétez-la comme suit :

- (void)viewDidLoad
{
[super viewDidLoad];
int compteur = 0;
while (compteur < 100)
{
NSLog(@"Bonjour");
compteur++;
}
}

Exécutez l'application en cliquant sur Run pour constater que cent lignes contenant le mot "Bonjour" sont affichées dans le volet de débogage.

Vous pouvez vous amuser à modifier la condition initiale du compteur (ligne 4) et la limite supérieure du compteur (ligne 5). Relancez l'application pour voir l'effet résultant.

La boucle do while

L'instruction do while est une variante de l'instruction while. Mais ici, la condition est testée après l'exécution des instructions entre accolades. Dans tous les cas, les instructions entre les accolades seront donc exécutées au moins une fois. Voici la syntaxe de cette instruction :

do
{
//Une ou plusieurs instructions
} while (condition);

Si on voulait adapter notre exemple précédent, voici comment il faudrait faire avec une boucle do while :

int compteur = 0;
do
{
NSLog(@"Bonjour");
compteur++;
} while (compteur < 100);

La première instruction initialise la variable compteur à 0. Les instructions entre les accolades sont alors exécutées une première fois : le mot « Bonjour » est affiché avec la fonction NSLog() et la variable compteur est incrémentée de 1.

La condition à la suite du while est alors examinée. Après la première exécution des instructions entre les accolades, compteur vaut 1. Il est donc bien inférieur à 100 et la boucle se poursuit. Ainsi de suite jusqu'à ce que compteur devienne égal à 100.

Fonctions

Une fonction peut être comparée à une boîte dont l'intérieur ne peut être vu. On lui fournit (éventuellement) une ou plusieurs données, elle effectue un traitement et retourne (éventuellement) une ou plusieurs autres données (figure suivante).

Image utilisateur

Une fonction consiste donc en un ensemble d'instructions qui effectuent un traitement et transforment les données qui lui sont fournies en d'autres données.

Découper le code d'une application en plusieurs fonctions présente plusieurs avantages : chaque fonction étant indépendante du reste du code, il est facile de la tester et de la faire évoluer au grès des différentes versions de l'application.

Pour déclarer une fonction, vous utiliserez la syntaxe suivante :

type nom(paramètres)
{
//Une ou plusieurs instructions
return retour;
}

Où :

  • type indique le type de la donnée retournée par la fonction (int, float etc.),

  • nom est le nom de la fonction ;

  • paramètres représente les éventuelles données fournies à la fonction ;

  • retour représente la donnée renvoyée par la fonction.

La fonction nom utilise le ou les paramètres qui lui sont fournis pour effectuer un traitement et retourner la donnée retour.

L'appel d'une fonction n'a rien de bien compliqué : il suffit d'indiquer son nom, éventuellement suivi des paramètres qui doivent lui être passés. Si la fonction renvoie une valeur, vous l'affecterez à une variable du même type que la valeur renvoyée.

À titre d'exemple, la fonction ttc ci-après renvoie le prix TTC correspondant au prix HT qui lui est passé. Le prix HT et le prix TTC sont de type float.

float ttc(float ht)
{
return ht * 1.196;
}

Ici un paramètre de type float doit être fourni à la fonction (le prix HT) qui renvoie une valeur de type float. L'instruction utilisée sera donc du type suivant (ici, nous calculons la valeur TTC correspondant à un prix HT de 100) :

float lePrixTTC = ttc(100);

Il est possible d'aller plus loin! Supposons que la fonction TTC doive calculer deux types de prix TTC : un avec une TVA de 5,5%, un autre avec une TVA de 19.6%. Comment devriez-vous compléter la fonction ttc précédente ? Je vous laisse réfléchir.

...

Si c'est vraiment trop difficile pour vous, je vais vous mettre sur la voie :

  • La fonction va avoir besoin de connaître le prix HT et la TVA à appliquer. Ces éléments seront passés à la fonction sous la forme de paramètres, donc entre les parenthèses. La TVA peut être fournie à la fonction telle quelle, au format float, ou représentée par un nombre int, qui pourrait valoir "1" dans le cas d'une TVA à 5,5% et "2" dans le cas d'une TVA à 19,6%.

  • Dans la fonction, il faudra effectuer un calcul ou un autre en fonction du taux de TVA à appliquer. Une instruction if semble donc tout à fait appropriée.

Cette fois-ci, je vous laisse vraiment réfléchir. Vous avez tous les éléments pour écrire cette fonction.

Voici le code que je vous propose :

float ttc(float ht, int tva)
{
if (tva==1)
return ht * 1.055;
else
return ht * 1.196;
}

La fonction ttc a maintenant deux paramètres : le prix HT et la TVA. Le deuxième paramètre est de type int. S'il est égal à 1, la fonction ttc renverra un prix TTC calculé avec une TVA de 5.5%. Dans tous les autres cas, la fonction ttc renverra un prix TTC calculé avec une TVA de 19.6%.

Et pour appeler la fonction:

float prix1 = ttc (100, 1); // Prix HT de 100 et TVA à 5,5%
float prix2 = ttc (100, 2); // Prix HT de 100 et TVA à 19,6%

Par exemple, une fonction qui affiche le mot « Bonjour » dans le volet de débogage ne demande aucun paramètre et ne retourne aucune valeur. Elle pourrait avoir l'allure suivante :

void bonjour(void)
{
NSLog(@"Bonjour\n");
}

En résumé

  • Pour comparer des valeurs entre elles, on utilise des opérateurs logiques.

  • Pour tester une condition, on utilise if, else if et else.

  • Il est possible d'effectuer plusieurs conditions dans un test, en séparant ces conditions par un opérateur logique.

  • switch est équivalent à if... elseif... else.... Cela permet de comparer une variable avec plusieurs valeurs et d'exécuter une ou plusieurs instructions en conséquence.

  • Pour répéter un certain nombre de fois une ou plusieurs instructions, vous utiliserez une boucle for, while ou do while. La boucle for est particulièrement bien adaptée lorsque l'on connaît le nombre d'itérations de la boucle. Les instructions while et do while prennent fin lorsqu'une condition logique est vérifiée.

  • Une fonction consiste en un ensemble d'instructions qui effectuent un traitement et transforment les données qui lui sont fournies en d'autres données. Pour définir une fonction, précisez son type, la ou les variables qui lui sont passées en paramètre et utilisez return pour retourner une valeur. Pour appeler une fonction, indiquez son nom et passez-lui une ou plusieurs variables entre parenthèses.

Exemple de certificat de réussite
Exemple de certificat de réussite