IV. Un programme est une série d'instructions▲
IV-A. Introduction▲
Si vous apprenez à conduire une voiture, vous devez apprendre à manier plusieurs choses en même temps. Vous devez saisir à la fois le fonctionnement des pédales d'embrayage, de l'accélérateur et des freins. La programmation exige également d'avoir à l'esprit un grand nombre de choses, sans quoi votre programme plantera. Si l'intérieur d'une voiture vous était déjà familier avant de commencer à apprendre à conduire, vous n'aurez pas cet avantage en apprenant comment programmer avec Xcode. Afin de ne pas vous submerger, nous garderons la question de l'environnement de programmation pour un chapitre ultérieur. Tout d'abord, nous allons vous mettre à l'aise avec le code Objective-C, en commençant par des mathématiques de base qui vous sont familières.
À l'école primaire, vous deviez faire des calculs en remplissant les pointillés :
2 + 6 = … ?
... = 3 * 4 (l'étoile * est le moyen conventionnel de représenter la multiplication sur les claviers d'ordinateur)
En secondaire les pointillés n'étaient plus à la mode, et des variables nommées x et y (ainsi qu'un nouveau nom sophistiqué, "algèbre") faisaient tout un foin. Avec le recul, on peut se demander pourquoi les gens furent si intimidés par ce tout petit changement de notation.
2 + 6 = x ?
y = 3 * 4
IV-B. Variables▲
Objective-C utilise aussi des variables. Les variables ne sont rien de plus que des noms opportuns pour se référer à un morceau de données spécifique, tel un nombre. Voici une déclaration en Objective-C, c'est-à-dire une ligne de code dans laquelle une certaine valeur est donnée à une variable :
//[1]
x =
4
;
IV-C. Le point-virgule▲
La valeur 4 est donnée à la variable nommée x. Vous noterez qu'il y a un point-virgule à la fin de la déclaration. Ceci car le point-virgule est indispensable à la fin de chaque déclaration. Pourquoi ? En fait, le fragment de code de l'exemple [1] peut vous paraître très simple, mais un ordinateur ne sait pas du tout qu'en faire. Un programme spécial, appelé compilateur, est nécessaire pour convertir le texte que vous avez tapé en 0 et 1 que seul votre Mac comprend. Lire et comprendre le texte tapé par un humain est très difficile pour un compilateur, donc vous devez lui fournir un certain nombre d'indices, par exemple l'endroit où se termine une déclaration donnée. C'est ce que vous faites en utilisant le point-virgule.
Si vous oubliez un seul point-virgule dans votre code, le code ne pourra pas être compilé, ce qui signifie qu'il ne pourra être converti en un programme exécutable par votre Mac. Ne vous souciez pas trop de cela, car s'il ne peut compiler votre code, le compilateur vous le dira. Comme nous le verrons dans un prochain chapitre, il essaiera de vous aider à découvrir ce qui ne va pas.
IV-D. Nommer les variables▲
Alors que les noms des variables en eux-mêmes n'ont pas de signification précise pour le compilateur, des noms de variables descriptifs peuvent grandement faciliter la lecture d'un programme, et donc sa compréhension par les humains. C'est un grand plus si vous devez dépister une erreur dans votre code.
Les erreurs dans un programme sont traditionnellement appelées des bogues.
Les trouver et les corriger se dit déboguer.
Donc, dans du vrai code, on évite d'utiliser des noms de variables non descriptifs tels que x. Par exemple, le nom de la variable pour la largeur d'une image pourra s'appeler imageLargeur [2].
//[2]
imageLargeur =
8
;
Du gros problème de ce que l'ordinateur fait de l'oubli d'un point-virgule, vous comprendrez que la programmation est toute affaire de détails. L'un de ces détails auquel il faut faire très attention est le fait que le code est sensible à la casse : c'est-à-dire qu'il importe de savoir si vous utilisez ou non des majuscules. Le nom de variable imageLargeur n'est pas le même que imageLARGEUR, ou ImageLargeur. En accord avec les conventions générales, je crée mes noms de variables en fusionnant plusieurs mots, le premier sans majuscule, et tous les autres mots composant le nom de la variable commençant par une majuscule, tout comme vous pouvez le voir dans l'exemple [2]. Ce style est souvent appelé « camelCase » (casseDuChameau). En collant à ce modèle, je réduis fortement les risques d'erreurs de programmation dus à la sensibilité de casse.
Bien noter qu'un nom de variable n'est toujours composé que d'un seul mot (ou d'un seul caractère, à la rigueur).
Bien que vous ayez toute liberté pour choisir les noms de variables, il y a diverses règles auxquelles votre nom de variable doit se conformer. Bien que je puisse toutes les citer, ce serait ennuyeux à ce stade. La principale règle à suivre est que votre nom de variable ne doit pas être un mot réservé d'Objective-C (c'est-à-dire un mot ayant une signification particulière en Objective-C). En composant un nom de variable par la contraction de mots, comme imageLargeur, vous êtes tranquille. Pour que le nom de variable reste lisible, l'usage des capitales à l'intérieur des noms de variables est recommandé. Si vous collez à ce modèle, vous aurez moins de bogues dans vos programmes.
Si vous tenez vraiment à apprendre deux ou trois règles, finissez ce paragraphe. En dehors des lettres, l'usage des chiffres est autorisé, mais un nom de variable ne doit pas commencer par un chiffre. Le caractère de soulignement « _ » est également autorisé. Voici quelques exemples de noms de variables.
Noms de variables corrects :
- porte8k ;
- po8rte ;
- po_rte.
Défendu :
- porte 8 (contient un espace) ;
- 8porte (commence par un nombre).
Déconseillé :
- Porte8 (commence par une majuscule).
IV-E. Utiliser des variables pour calculer▲
Maintenant que nous savons comment donner une valeur à une variable, nous pouvons réaliser des calculs. Jetons un œil au code du calcul de la surface d'une image. Voici le code [3] qui ne fait que cela.
//[3]
imageLargeur=
8
;
imageHauteur=
6
;
imageAire=
imageLargeur*
imageHauteur;
Curieusement, le compilateur ne pinaille pas sur la présence ou non d'espaces (excepté à l'intérieur des noms de variables, des mots-clés, etc. !). Pour faciliter la lisibilité du code, nous pouvons utiliser des espaces.
//[4]
imageLargeur =
8
;
imageHauteur =
6
;
imageAire =
imageLargeur *
imageHauteur;
IV-F. Entiers et flottants▲
Maintenant, examinons l'exemple [5], et en particulier les deux premières déclarations.
//[5]
imageLargeur =
8
;
imageHauteur =
4.5
;
imageAire =
imageLargeur *
imageHauteur;
Les nombres peuvent généralement être distingués en deux types : les entiers (nombres entiers) et les nombres fractionnaires. Vous pouvez en voir un exemple de chaque, respectivement, dans les déclarations [5,1] et [5.2]. Les entiers sont utilisés pour compter, chose que nous ferons lorsque nous aurons à répéter un certain nombre de fois une série d'instructions (voir chapitre 7). Par exemple, vous entendez parler de nombres fractionnaires ou à virgule flottante dans les moyennes des frappes au base-ball (en France, dans les chiffres de la natalité… :-)).
Le code de l'exemple [5] ne fonctionnera pas. Le problème est que le compilateur veut que vous lui disiez à l'avance quels noms de variables vous allez utiliser dans votre programme, et à quel type de données elles se rapportent, c'est-à-dire des nombres entiers ou à virgule flottante. En langage branché, cela s'appelle "déclarer une variable".
//[6]
int
imageLargeur;
float
imageHauteur, imageAire;
imageLargeur =
8
;
imageHauteur =
4.5
;
imageAire =
imageLargeur *
imageHauteur;
À la ligne [6.1], int indique que la variable imageLargeur est un entier. À la ligne suivante, nous déclarons deux variables d'un seul coup, en séparant les noms de variables d'une virgule. Plus précisément, la déclaration [6.2] dit que les deux variables sont de type float (flottant), c'est-à-dire des nombres qui contiennent des parties fractionnaires. Dans notre cas, il est un peu ridicule que imageLargeur soit d'un autre type que les deux autres variables. Mais ce que vous pourrez voir, c'est que si vous multipliez un int par un float, le résultat du calcul est un float, c'est la raison pour laquelle vous devez déclarer la variable imageAire comme un float [6,2].
Pourquoi le compilateur veut-il savoir si une variable représente un entier ou un nombre avec une partie fractionnaire ? Eh bien, un programme informatique a besoin d'une partie de la mémoire de l'ordinateur. Le compilateur réserve de la mémoire (des octets) pour chaque variable qu'il rencontre. Puisque les différents types de données, dans ce cas int et float, exigent différentes quantités de mémoire et une représentation différente, le compilateur a besoin de réserver la bonne quantité de mémoire et d'utiliser la bonne représentation.
Et si nous travaillons avec de très grands nombres ou des nombres décimaux de très haute précision ? Ils ne tiendront pas dans les quelques octets réservés par le compilateur, non ? C'est exact. Il y a deux réponses à cela : premièrement, int et float ont tous deux des homologues qui peuvent stocker de plus grand nombre (ou des nombres de plus haute précision). Sur la plupart des systèmes ce sont, respectivement, long et double. Mais même ceux-ci peuvent faire le plein, ce qui nous amène à la seconde réponse : en tant que programmeur, il vous appartiendra d'être aux aguets des problèmes. En tout cas, ce n'est pas un problème à débattre dans le premier chapitre d'un livre d'introduction.
Par ailleurs, les entiers et les nombres décimaux peuvent tous deux être négatifs, ce que vous voyez par exemple sur votre relevé de banque. Si vous savez que la valeur d'une variable ne sera jamais négative, vous pouvez élargir la gamme des valeurs à tenir dans les octets disponibles.
//[7]
unsigned
int
chocolatBarresEnStock;
Il n'existe pas de nombre négatif de barres de chocolat en stock, donc ici un unsigned int pourra être utilisé. Le type unsigned int représente des nombres entiers supérieurs ou égaux à zéro.
IV-G. Déclarer une variable▲
Il est possible de déclarer une variable et de lui assigner une valeur d'un seul coup [8].
//[8]
int
x =
10
;
float
y=
3.5
, z =
42
;
Cela vous évite un peu de frappe.
IV-H. Types de données▲
Comme nous l'avons vu, les données stockées dans une variable peuvent être d'un ou plusieurs types spécifiques, par exemple un int ou un float.
En Objective-C, d'aussi simples types de données que ceux-ci sont aussi appelés données scalaires. Voici une liste des types de données scalaires courants disponibles en Objective-C :
Nom | Type | Exemple |
---|---|---|
void | Vide | Rien |
int | Entier | ...-1, 0, 1, 2... |
unsigned | Entier non signé | 0, 1, 2... |
float | Nombre à virgule flottante | -0.333, 0.5, 1.223, 202.85556 |
double | Nombre double précision à virgule flottante | 0.52525252333234093890324592793021 |
char | Caractère | bonjour |
BOOL | Booléen | 0, 1; TRUE, FALSE; YES, NO. (0, 1; VRAI, FAUX; OUI, NON.) |
IV-I. Opérations mathématiques▲
Dans les exemples précédents, nous avons réalisé une multiplication. Utilisez les symboles suivants, officiellement connus sous le nom d'opérateurs, pour faire des calculs mathématiques de base.
+ pour addition
- pour soustraction
/ pour division
* pour multiplication
À l'aide des opérateurs, nous pouvons effectuer un large éventail de calculs. Si vous examinez le code des programmeurs professionnels en Objective-C, vous rencontrerez quelques particularités, probablement parce que ce sont des flemmards du clavier.
Au lieu d'écrire x = x + 1; les programmeurs recourent souvent à quelque chose comme [9] ou [10]
//[9]
x++
;
//[10]
++
x;
Dans les deux cas, cela signifie : incrémenter x de un. Dans certaines circonstances, il est important que le ++ soit placé avant ou après le nom de la variable. Examinez les exemples [11] et [12] ci-dessous.
//[11]
x =
10
;
y =
2
*
(
x++
);
//[12]
x =
10
;
y =
2
*
(++
x);
Dans l'exemple [11], en fin de compte, y est égal à 20 et x est égal à 11. En revanche, dans la déclaration [12.2], x est incrémenté de un avant que la multiplication par 2 n'ait lieu. Donc, finalement, x est égal à 11 et y est égal à 22. Le code de l'exemple [12] est équivalent à celui de l'exemple [13].
//[13]
x =
10
;
x++
;
y =
2
*
x;
Ainsi, le programmeur a en fait fusionné deux déclarations en une seule. Personnellement, je pense que cela complique la lecture d'un programme. Si vous prenez le raccourci c'est bien, mais soyez conscient qu'un bogue peut y traîner.
IV-J. Parenthèses▲
Cela vous paraîtra ringard si vous avez réussi votre secondaire, mais les parenthèses peuvent être utilisées pour déterminer l'ordre dans lequel les opérations seront effectuées. Ordinairement, * et / ont la priorité sur + et -. Donc 2 * 3 + 4 est égal à 10. En utilisant des parenthèses, vous pouvez forcer l'exécution de la modeste addition en premier lieu : 2 * (3 + 4) est égal à 14.
IV-K. Division▲
La division mérite une attention particulière, parce qu'il y a une différence considérable selon qu'elle est utilisée avec des entiers ou des flottants. Jetez un œil aux exemples ci-après [14, 15].
//[14]
int
x =
5
, y =
12
, rapport;
rapport =
y /
x;
//[15]
float
x =
5
, y =
12
, rapport;
rapport =
y /
x;
Dans le premier cas [14], le résultat est 2. Seul le second cas [15] donne le résultat que vous attendez probablement : 2.4.
IV-L. Booléens▲
Un booléen est une simple valeur logique, vraie ou fausse. 1 et 0 qui signifient vrai et faux sont souvent utilisés à la place, et peuvent être considérés comme équivalents :
True (Vrai) | False (Faux) |
1 | 0 |
Ils sont fréquemment utilisés pour évaluer l'opportunité d'effectuer des actions en fonction de la valeur booléenne d'une variable ou d'une fonction.
IV-M. Modulo▲
% (modulo) est un opérateur qui ne vous est probablement pas familier. Il ne fonctionne pas comme vous pourriez vous y attendre : l'opérateur modulo n'est pas un calcul de pourcentage. Le résultat de l'opérateur % est le reste de la division entière du premier opérande par la seconde (si la valeur de la seconde est égale à zéro, le comportement de % est indéfini).
//[16]
int
x =
13
, y =
5
, reste;
reste =
x %
y;
Maintenant, le résultat est que reste est égal à 3, parce que x est égal à 2 * y + 3.
Voici quelques autres exemples de modulo :
21 % 7 est égal à 0
22 % 7 est égal à 1
23 % 7 est égal à 2
24 % 7 est égal à 3
27 % 7 est égal à 6
30 % 2 est égal à 0
31 % 2 est égal à 1
32 % 2 est égal à 0
33 % 2 est égal à 1
34 % 2 est égal à 0
50 % 9 est égal à 5
60 % 29 est égal à 2
Cela peut parfois être pratique, mais notez qu'il ne fonctionne qu'avec des entiers.
Une utilisation courante de modulo est de déterminer si un entier est pair ou impair. S'il est pair, un modulo de deux sera égal à zéro. Sinon, il sera égal à une autre valeur. Par exemple :
//[17]
int
unInt;
//Du code qui définit la valeur de unInt
if
((
unInt %
2
) ==
0
)
{
NSLog
(
@"unInt est pair"
);
}
else
{
NSLog
(
@"unInt est impair"
);
}