Si vous avez suivi le tuto jusqu’ici, vous avez compilé et fait tourner un premier programme simple. Rentrons maintenant dans la syntaxe même du langage C++. Il y aura une bonne partie de «cours» avant qu’on remette les mains dans le code.
Nous allons voir:
main
)Il y aura un QCM à la fin, et on écrira un programme ensemble pas à pas, c’est pour cela que le nombre de diapos en bas à droite peut paraître impressionnant ^^’
Une instruction est une opération qui sera réalisée par le programme.
En C++ chaque instruction se termine par un point-virgule
;
.
On peut écrire plusieurs instructions sur une même ligne, et une instruction peut être écrite sur plusieurs lignes. Et on peut rajouter autant d’espaces que l’on veut entre les mots et les symboles. Voilà quelques exemples:
int i=0;
double a = -10.; double b = 10;
std::cout << "Cela s'affiche" << std::endl
<< "a l'ecran" << std::endl;
Il y a plein de conventions de mises en forme qui sont possibles, qui diront comment écrire, aligner, etc… Ce qui compte, c’est que votre code soit lisible ! Et si vous êtes plusieurs à travailler sur les mêmes fichiers, il vaut mieux se mettre d’accord sur les règles à suivre.
Les intructions peuvent être regroupées dans un bloc. En C++, un bloc
commence et finit par des accolades {}
. Les blocs peuvent
être imbriqués.
// cette ligne est en dehors d'un bloc
{
// celle-ci est dans un premier bloc
}
{
{
// Un bloc dans un bloc
}
}
On peut considérer un bloc comme étant une seule instruction qui en regroupe plusieurs.
Sur la slide précédente, j’ai écrit des commentaires pour donner des informations sur le code.
Les commentaires sont très importants dans un programme. Ils permettent de faire comprendre ce que fait un code qui devient souvent très compliqué. Les codes restent rarement utilisés par une seule personne, ou alors il arrive de rouvrir un code qu’on a écrit des années auparavant et dont on se souvient pas. Il faut donc savoir transmettre l’information de manière efficace: il faut suffisamment de commentaires, mais pas trop, et assez clairs même pour une personne qui repart de (presque) zéro (mais qui connaît le langage).
En C++, les commentaires s’écrivent de deux façons:
/*
et */
Les variables sont des emplacements dans la mémoire de l’ordinateur, qui servent à stocker des valeurs. Par exemple, des nombres, des caractères, etc.
Chaque variable a un nom, de la même manière qu’on donne un nom en mathématiques à une valeur numérique x ou une fonction f.
Le principe de fonctionnement des programmes est de modifier les valeurs des variables à l’aide d’algorithmes.
Quand je représenterai les variables dans la suite du tuto, je le ferai comme ceci:
avec le nom de la variable au dessus, et la valeur stockée à cet
endroit dans la case. Ici, j’ai représenté un nombre réel x
qui vaut -2.5.
En C++, il y a quelques règles pour les noms de variables. Un nom de variable:
_
truc
et
la variable Truc
ne sont pas les
mêmes.
Choisissez bien vos noms de variables. Comme pour les commentaires, il
doivent être assez clairs, mais pas trop lourds non plus.
Par exemple, si vous devez garder en mémoire le nombre de fois qu’une
opération a réussi, vous pourrez appeler votre variable
successCount
ou encore
nSuccess
, mais évitez
n
ou
number_of_times_the_function_succeeded
.
Lorsque j’ai parlé des variables, j’ai dit qu’elles occupaient un emplacement mémoire. Mais en fonction de ce qu’on veut stocker, la place prise en mémoire sera différente. Par exemple, il faut plus de bits (0 et 1) pour représenter un nombre réel que pour représenter un nombre entier.
C++ fait partie des langages pour lesquels il faut indiquer au compilateur quel est le type de variable associé au nom de la variable. Pour d’autres langages ce n’est pas obligatoire (Python par exemple), mais cela peut créer de très mauvaises surprises!
Une règle très importante en C++ est qu’une variable doit être déclarée avant toute utilisation. Au moment de la déclaration, on donne le type de la variable, et ce type ne changera pas durant la suite du programme.
C’est pour cela qu’on dit que C++ est un langage typé statiquement.
Chaque variable doit être déclarée avant sa première utilisation.
Cela se fait en suivant cette syntaxe:
où il faudra remplacer le type et le nom par ceux qu’on souhaite. On peut cumuler la déclaration d’une variable avec son initialisation, c’est à dire le fait de lui donner une première valeur. C’est une très bonne pratique qui évite beaucoup de bugs!
type nom = valeur;
// ou
type nom(valeur);
// Exemples:
int a = 1;
double x = -2.5;
std::string s("coucou");
Nous allons maintenant voir quelques uns des types qui sont prédéfinis dans le langage C++, pour quels usages, et comment écrire les valeurs qu’ils peuvent prendre.
Commençons par les entiers. Le type vraiment basique est
int
. Mais il existe aussi:
long
: entiers codés sur plus de bits,
pour représenter des entiers plus grands en valeur absolue que les
int
unsigned int
,
unsigned long
: entiers non signés, c’est
à dire forcément positifs. C’est pratique pour représenter des indices
dans des tableaux ou des algorithmeslong long
,
short
, …
Ça fait beaucoup de possibilités pour représenter les entiers! Même
trop, et pour compliquer l’affaire, le nombre de bits en mémoire auquel
ces types correspondent change suivant la machine! Mon conseil
est le suivant: pour les tutos et les cours, n’utilisez que
int
et éventuellement
unsigned int
. Pour un programme
pour lequel la taille des entiers est importante, utilisez
int32_t
et
int64_t
, qui disent explicitement
leur taille.
- Les int32_t
sont dans
l’intervalle [−2 147 483 648; +2 147 483 647],
- Les
int64_t
dans l’intervalle [−9 223 372 036
854 775 808; +9 223 372 036 854 775 807].
Les nombres constants entiers s’écrivent tels quels:
1, 2, -10
. Vous pourrez parfois trouver
les suffixes l
et
u
pour signifier que ces valeurs doivent
être utilisées en temps qu’entiers longs et non-signés, respectivement:
1234567889012l, 2u
.
Les nombres réels sont représentés en interne avec l’écriture à virgule flottante:
signe * mantisse *2exposant
Les types de base les plus courants pour les réels sont:
float
, avec une précision
d’environ 7 chiffres significatifsdouble
, qui utilise deux fois
plus de bits, a une précision d’environ 16 chiffres significatifs.IMPORTANT. Étant donné que les nombres réels ne peuvent souvent pas être représentés de façon exacte à cause du nombre limité de bits sur lesquels ils sont codés, c’est dangereux de tester l’égalité stricte de deux réels. L’égalité est définie à la précision machine près. Si on note cette précision ε, alors on regarde si |a-b|< εmin(|a|,|b|) plutôt que de tester si a=b. Il y aura plusieurs exemples dans les programmes et QCM de ces cours.
Pour écrire les réels en C++, on peut utiliser
1., -2.3, 0.00454, .05
(on peut retirer le
0 avant la virgule)1.e0, -2.3e0, 4.54e-3, 5.e-2
Attention avec les valeurs entières pour des nombres réels. La constante “3” sera considérée comme un entier, et pas un réel. Si on veut que ce soit un réel, on peut simplement rajouter un point: “3.”. On verra plus tard pourquoi ça peut créer des problèmes.
Les booléens sont un type à part qu’on rencontre dans les programmes car ils sont très simples. Ils ne peuvent prendre que deux valeurs: vrai ou faux.
En C++ le type des booléens est bool
,
vrai et faux s’écrivent true
et
false
, sans majuscules.
Les types associés aux nombres entiers peuvent être considérés comme
des booléens. Dans ce cas on associe 0
à
false
, et toutes les autres valeurs
(positives ou négatives) à true
. On en
reparlera quand on verra les expressions, d’ici quelques slides.
Un autre type très utile est celui qui sert à écrire directement des mots.
À la base, en C, on trouve le type char
qui sert à encoder un seul caractère.
char c = 'a';
char d = '1'; // Attention, ce n'est pas le nombre entier 1, mais le caractère pour écrire le chiffre 1
Mais on veut écrire des mots, c’est-à-dire une suite de caractères. En C, il y a une façon de les représenter qui se base sur les tableaux, mais qui n’est pas très pratique.
En C++, il a les std::string
qui sont
des objets qui permettent de manipuler les chaînes de caractères bien
plus facilement. Ces chaînes de caractères ne sont pas présentes
nativement dans un programme, il faut les inclure depuis la bibliothèque
string
.
On reviendra sur l’utilisation des
std::string
au fur et à mesure du
tuto.
Nous pouvons maintenant déclarer des variables de types usuels. Cependant, il faut savoir qu’une variable n’existera pas forcément pendant toute la durée d’exécution du programme.
Les variables ont ce qu’on appelle une portée, c’est-à-dire une durée de vie.
La portée d’une variable est limitée au bloc d’instructions dans laquelle elle est déclarée.
Prenons l’exemple suivant:
{ // debut bloc 1
unsigned int i = 0u;
{ // debut du bloc 1.1
double x = -1.;
{ // debut du bloc 1.1.1
unsigned int j=0u;
} // fin du bloc 1.1.1
} // fin du bloc 1.1
{ // debut du bloc 1.2
unsigned int i = 1u;
} // fin du bloc 1.2
} // fin du bloc 1
À la ligne 3, dans le bloc 1, on déclare un entier positif
i
, qui vaut 1. Quand on rentre dans le
bloc 1.1 à la ligne 5, i
existe toujours,
car on n’est pas sorti du bloc 1.
{ // debut bloc 1
unsigned int i = 0u;
{ // debut du bloc 1.1
double x = -1.;
{ // debut du bloc 1.1.1
unsigned int j=0u;
} // fin du bloc 1.1.1
} // fin du bloc 1.1
{ // debut du bloc 1.2
unsigned int i = 1u;
} // fin du bloc 1.2
} // fin du bloc 1
À la ligne 8, les entiers positifs i
et
j
existent, ainsi que le nombre réel
x
. On est dans les blocs 1.1.1, 1.1 et
1.
En revanche, à la ligne 10, la variable
j
n’existe plus : elle a été déclarée dans
le bloc 1.1.1, et on en est sorti. Idem ligne 12, les variables
j
et x
ne
sont plus connues.
{ // debut bloc 1
unsigned int i = 0u;
{ // debut du bloc 1.1
double x = -1.;
{ // debut du bloc 1.1.1
unsigned int j=0u;
} // fin du bloc 1.1.1
} // fin du bloc 1.1
{ // debut du bloc 1.2
unsigned int i = 1u;
} // fin du bloc 1.2
} // fin du bloc 1
J’ai ajouté le bloc 1.2 pour illustrer une bizarrerie du langage. Vous pouvez déclarer deux variables qui ont le même nom, du moment qu’elles ne sont pas déclarées dans le même bloc. Évidemment, je déconseille de le faire! Mais sachez que ça existe, et que ça peut être une source de bugs!
On va tester ça: téléchargez ce code : porteeVariables.cpp. C’est le même qu’à la slide précédente, mais j’ai ajouté ce qu’il faut pour que ça compile.
Compilez le et exécutez le. Vous devriez avoir ça:
On peut voir qu’une fois sorti du bloc 1.2, la valeur de
i
est revenue à 0. En fait, la deuxième
variable n’écrase pas la première. Les deux variables ne partagent pas
le même espace mémoire. Ce qui fait qu’en sortant du bloc 1.2, la
seconde variable i
a été détruite, mais la
première reste.
Les opérateurs sont des symboles qui définissent des opérations sur une variable (opérateur unaire) ou entre deux variables (opérateur binaire). Voici les principaux opérateurs, par priorité décroissante. Il en existe d’autres.
++ --
(unaires) : incrémentation, décrémentation. Pour
les entiers faire i++;
revient à faire i=i+1;
.
+ - ! not
(unaires): pour modifier le signe d’une
variable ou d’une constante (-3.5
, -i
). Le
point d’exclamation est équivalent à not
. Tous deux servent
à exprimer la négation pour les booléens.
* / %
(binaires) : multiplication, division, reste
de la division entière)< > <= >=
(binaires) : comparaison== !=
(binaires) : comparaison, pour tester l’égalité
et l’inégalité.&& and
(binaires) : ET logique. Les deux
opérateurs sont équivalents.|| or
(binaires) : OU logique. Les deux opérateurs
sont équivalents.= += -= *= /= %=
(binaires) : affectation,
affectation avec une opération. a += 2;
revient à faire
a = a+2;
Ne confondez pas le test d’égalité ==
et le signe
d’affectation =
.
Les notations &&, ||
et !
sont
héritées du C. Je préfère utiliser and or
et
not
en toutes lettres car c’est plus lisible.
Le comportement des opérateurs change en fonction du type de(s)
opérande(s).
Notamment, l’exemple le plus courant est
celui de la division. Je ne compte plus le nombre de points que j’ai
retirés à cause de ça.
Si les deux opérandes du symbole
/
sont des entiers, alors c’est la
division entière qui est réalisée.
Si au
moins une des deux opérandes est réelle, alors c’est la
division réelle qui est faite.
Dans cet exemple, au premier affichage la constante “1
”
est considérée comme entière, N
est entier, donc le
résultat est 0. Il y a 0 fois 1000 dans 1. Dans le second cas, on fait
la division réelle car la constante “1.
” est réelle.
Si on veut faire la division réelle de deux variables entières, on peut
faire ça de plusieurs manières:
int a=1; int b=2;
std::cout << a/(1.*b) << std::endl; // methode "sale", on multiplie une des deux variables par le reel 1.
// Ainsi (1.*b) est reel, et on effectue la division reelle.
std::cout << a/(double)(b) << std::endl; // methode "propre", on effectue un "cast" de la variable b
// en une variable de type double. Une variable temporaire est creee,
// b reste un entier apres l'operation. L'avantage de faire ceci
// est qu'on voit clairement le mot "double" dans le code, ce
// qui montre sans aucun doute possible qu'on veut faire la division reelle
main
C’est bientôt fini pour cette partie! Il ne nous reste plus qu’un élément nécessaire pour qu’un programme en C++ puisse être compilé.
Il s’agit de la fonction main
. On
reviendra plus tard sur la notion de fonction, mais on peut déjà parler
de celle-ci parce qu’elle est très particulière.
Tout programme C++ doit avoir une et une seule fonction
main
. Il s’agit en fait du point d’entrée dans le
programme. Les instructions commencent à être exécutées à partir de ce
point du programme.
L’entier 0 retourné à la fin du programme est un signal envoyé au système d’exploitation, qui a lancé le programme, pour dire que le programme s’est déroulé normalement, sans erreur.
Voilà pour la partie cours, je vais ensuite poser quelques questions d’exercice pour voir si vous avez bien retenu et compris ce que j’ai présenté.
Je compile le code suivant, et le compilateur m’envoie cette erreur:
#include <iostream>
int main() {
double a=2 double b=3;
std::cout << "La somme vaut " << a+b << std::endl;
return 0;
}
Qu’est-ce qui cause cette erreur ?
Je compile le code suivant, et le compilateur m’envoie cette erreur:
#include <iostream>
int main() {
double a=2 double b=3;
std::cout << "La somme vaut " << a+b << std::endl;
return 0;
}
Qu’est-ce qui cause cette erreur ?
J’ai oublié un point-virgule qui complèterait la déclaration de
a
: double a=2;
. Tant que le compilateur ne
voit pas de point-virgule, il continue, et doit donc comprendre ce que
veut dire “2 double
”. Ça n’a pas de sens en C++, donc il
dit qu’il y a une erreur à cet endroit, même si l’oubli est juste
avant.
Dans un programme, je dois afficher l’heure à laquelle un train arrive, si je connais son heure de départ, sa vitesse moyenne et la distance à parcourir.
Quel type de variable vais-je utiliser pour manipuler le résultat à afficher en heure et minutes ?
Quel type de variable puis-je utiliser pour calculer le résultat à une minute près avant l’affichage ?
Dans un programme, je dois afficher l’heure à laquelle un train arrive, si je connais son heure de départ, sa vitesse moyenne et la distance à parcourir.
Quel type de variable vais-je utiliser pour manipuler le résultat à afficher en heure et minutes ?
Quel type de variable puis-je utiliser pour calculer le résultat à une minute près avant l’affichage ?
L’affichage à l’écran se fait à l’aide de caractères. Surtout si je
veux un bel affichage avec un format (hh:mm). On utilisera donc une
chaîne de caractères.
Pour calculer le résultat, on aura sans doute
un opération qui impliquera des nombres réels (vitesse*distance). On
peut stocker le résultat dans un float
ou un
double
, mais également dans un int
, ce qui
tronquerait la partie décimale du nombre. Ce ne serait pas grave, parce
que le résultat est à une minute près.
Pour votre culture, il existe en fait un type time_t
qui a
été spécifiquement conçu pour gérer les données temporelles.
J’ai eu 11, 9 et 9 à mes contrôles dans un module. Je calcule la moyenne en faisant
#include <iostream>
int main() {
int n1(11), n2(9), n3(9);
std::cout << "Ma moyenne est de " << (n1+n2+n3)/3 << std::endl;
return 0;
}
Et ce programme me dit que j’ai 9, alors qu’en fait j’ai 9,66 et je pourrais espérer être remonté à 10!
Quel est le souci ?
J’ai eu 11, 9 et 9 à mes contrôles dans un module. Je calcule la moyenne en faisant
#include <iostream>
int main() {
int n1(11), n2(9), n3(9);
std::cout << "Ma moyenne est de " << (n1+n2+n3)/3 << std::endl;
return 0;
}
Et ce programme me dit que j’ai 9, alors qu’en fait j’ai 9,66 et je pourrais espérer être remonté à 10!
Quel est le souci ?
On peut déclarer et initialiser plusieurs variables d’un même type en
une fois sur un même ligne, pas de souci. (j’avoue je ne vous
l’avais pas dit avant) En revanche, l’erreur est dans la
division, car (n1+n2+n3)
est une addition d’entiers, donc
un entier. “3
” est une expression constante entière, donc
la division réalisée est entière, et le résultat tronqué par rapport à
la valeur réelle. Il aurait fallu écrire “3.
” au
dénominateur, ou mieux, utiliser des réels pour les notes, car elles
peuvent avoir des demi-points!
Laquelle de ces expressions utiliser pour tester l’égalité de deux
float
a
et b
?
(std::abs
calcule la valeur absolue de l’argument entre
parenthèses, et std::min
le minimum de deux nombres donnés
en argument)
a==b
std::abs(a-b)<1.e-7*std::min(std::abs(a),std::abs(b))
(a-1.e-7)==(b-1.e-7)
std::min(a,b)<1.e-7
Laquelle de ces expressions utiliser pour tester l’égalité de deux
float
a
et b
?
(std::abs
calcule la valeur absolue de l’argument entre
parenthèses, et std::min
le minimum de deux nombres donnés
en argument)
a==b
std::abs(a-b)<1.e-7*std::min(std::abs(a),std::abs(b))
(a-1.e-7)==(b-1.e-7)
std::min(a,b)<1.e-7
On ne peut pas tester directement l’égalité de deux nombres réels en
programmation, car ils ne sont définis qu’avec une certaine précision: 7
chiffres après la virgule pour les float
.
On va donc plutôt tester si l’écart entre a
et
b
est inférieur à cette précision, relativement à la valeur
de a
ou de b
.
Oui c’est long à écrire, mais on verra comment faire pour que ce soit plus court par la suite :)
Pour conclure cette partie, on va écrire un programme entier, pas à pas. N’hésitez pas à l’écrire vous même en parallèle, pour que ça rentre dans les doigts.
Ce programme demandera à l’utilisateur de rentrer 3 paires de coordonnées \(x\) et \(y\), et dira si le triangle formé par les 3 points est rectangle.
La première question à se poser est comment faire en termes mathématiques ? Si on appelle ces points A,B,et C, on calculera trois produits scalaires:
Si un des trois produits scalaires est nul, alors le triangle est rectangle.
Un programme C++ doit toujours comporter une fonction
main
. Commençons par ça. Écrivez ceci dans un fichier, que
vous pouvez enregistrer sous le nom `triangleRectangle.cpp``, par
exemple.
Il va ensuite falloir demander à l’utilisateur d’entrer des
informations au clavier, et ensuite afficher un résultat à l’écran. On
va donc lire depuis l’entrée standard, et écrire dans la sortie
standard. Cela se fait en C++ avec les objets std::cin
et
std::cout
, qui sont les flux depuis l’entrée et vers la
sortie standard. Ils sont définis dans la bibliothèque
iostream
. Incluons donc cette bibliothèque.
Il faut demander à l’utilisateur des infos, qui sont les coordonnées des points. Ce sont donc 6 nombres réels dont nous aurons besoin, déclarons les:
Même si ce n’est pas nécessaire, je les initialise à 0 par habitude. J’ai eu trop de bugs à cause de variables non initialisées ! Même si c’est souvent le cas, rien ne garantit qu’un double non-initialisé vaut 0.
Rappel : “0.e0” est juste la notation exponentielle du réel 0, qu’on peut aussi écrire “0.”.
Ensuite, les valeurs doivent être lues depuis le clavier. Ça se fait comme ça:
Si on laisse ça tel quel, l’utilisateur verra que le programme
tourne, mais ne saura pas nécessairement quoi faire. Ajoutons un peu
d’interactivité en indiquant poliment ce qu’il faut rentrer. On affiche
une phrase à l’écran avant de lire avec std::cin
.
#include <iostream>
int main() {
double xa(0.e0),ya(0.e0),xb(0.e0),yb(0.e0),xc(0.e0),yc(0.e0);
std::cout << "Entrez svp 3 paires de coordonnees 2D" << std::endl;
std::cin >> xa >> ya >> xb >> yb >> xc >> yc;
return 0;
}
std::endl
est un objet de C++ qui permet d’effectuer un
retour à la ligne dans les flux de sortie. Il n’y a pas besoin de
std::endl
dans les flux d’entrée comme
std::cin
. Essayez de compiler et faire tourner le programme
avec et sans std::endl
pour voir la différence.
Les coordonnées sont lues. Calculons à présent les produits
scalaires. Ce sont aussi des nombres réels, donc utilisons le type
double
.
#include <iostream>
int main() {
double xa(0.e0),ya(0.e0),xb(0.e0),yb(0.e0),xc(0.e0),yc(0.e0);
std::cout << "Entrez svp 3 paires de coordonnees 2D" << std::endl;
std::cin >> xa >> ya >> xb >> yb >> xc >> yc;
double scal1 = (xb-xa)*(xc-xa)+(yb-ya)*(yc-ya);
double scal2 = (xb-xa)*(xc-xb)+(yb-ya)*(yc-yb);
double scal3 = (xc-xa)*(xc-xb)+(yc-ya)*(yc-yb);
return 0;
}
Maintenant il faut dire si ces produits scalaires sont nuls. Comme ce
sont des nombres réels, on va plutôt vérifier qu’ils ne sont pas plus
petits (en valeur absolue) qu’un nombre correspondant à la précision du
type double
.
Je vais donc comparer deux doubles. Le résultat de cette évaluation
sera vrai ou faux. Je vais mettre ce résultat dans une variable de type
bool
, pour chaque produit scalaire.
#include <iostream>
int main() {
double xa(0.e0),ya(0.e0),xb(0.e0),yb(0.e0),xc(0.e0),yc(0.e0);
std::cout << "Entrez svp 3 paires de coordonnees 2D" << std::endl;
std::cin >> xa >> ya >> xb >> yb >> xc >> yc;
double scal1 = (xb-xa)*(xc-xa)+(yb-ya)*(yc-ya);
double scal2 = (xb-xa)*(xc-xb)+(yb-ya)*(yc-yb);
double scal3 = (xc-xa)*(xc-xb)+(yc-ya)*(yc-yb);
bool isOrtho1 = std::abs(scal1) < 1.e-16;
bool isOrtho2 = std::abs(scal2) < 1.e-16;
bool isOrtho3 = std::abs(scal3) < 1.e-16;
return 0;
}
Quand je fais isOrtho1 = std::abs(scal1) < 1.e-16
,
l’opérateur “<
” est prioritaire à l’assignation
“=
”. Le programme évalue donc d’abord
std::abs(scal1) < 1.e-16
qui vaut soit vrai soit faux,
et le résultat est ensuite mis dans isOrtho1
.
Il n’y a plus qu’à afficher le résultat !
#include <iostream>
int main() {
double xa(0.e0),ya(0.e0),xb(0.e0),yb(0.e0),xc(0.e0),yc(0.e0);
std::cout << "Entrez svp 3 paires de coordonnees 2D" << std::endl;
std::cin >> xa >> ya >> xb >> yb >> xc >> yc;
double scal1 = (xb-xa)*(xc-xa)+(yb-ya)*(yc-ya);
double scal2 = (xb-xa)*(xc-xb)+(yb-ya)*(yc-yb);
double scal3 = (xc-xa)*(xc-xb)+(yc-ya)*(yc-yb);
bool isOrtho1 = std::abs(scal1) < 1.e-16;
bool isOrtho2 = std::abs(scal2) < 1.e-16;
bool isOrtho3 = std::abs(scal3) < 1.e-16;
std::cout << "Le triangle est rectangle ? (1: vrai, 0: faux) "
<< (isOrtho1 or isOrtho2 or isOrtho3) << std::endl;
return 0;
}
Dernière étape, essentielle : TESTER. Même si “tester, c’est douter”, il faut toujours tester !
Compilez votre programme, et essayez de rentrer des coordonnées pour des triangles rectangles et des triangles qui ne le sont pas.
Pour faire un test idéal, il faut essayer plusieurs cas qui fonctionnent, et plusieurs qui ne fonctionnent pas.
Et voilà qui conclut cette première partie ! Dans la suite, nous verrons ce qu’on appelle les structures de contrôle, qui permettent de ne pas réaliser toutes les instructions les unes à la suite des autres.