Académique Documents
Professionnel Documents
Culture Documents
UCA
Cet outil est le langage de programmation C++. Mais, au-delà du langage en lui-même, ce sont les bases de
la programmation qui sont ciblées ; ainsi que l’acquisition des techniques algorithmiques qui les
accompagnes.
Dans la réforme précédente le langage étudié était le langage C. Cette transition vers le C++, permet
d’élargir cette base de programmation, en y ajoutant d’autres concepts, en l’occurrence la programmation
orientée objet.
Le langage C++ est un langage compilé, il permet d’appréhender la programmation moderne ; structurée et
orientée objet. Théoriquement, le langage C++ englobe le langage C.
L’étudiant ayant acquis les bases du C++ devrait pouvoir migrer, moyennant un petit effort, vers d’autres
langages comme : Java, C#, Visual Basic, Python par exemple, Qui sont des langages orientés objets (POO).
Comme il pourrait de la même façon aller vers : C, Fortran etc. qui sont eux dans la catégorie des langages
structurés. Une autre catégorie de langages, celle des langages interprétés, très pratiques pour l’analyse des
données, comme Matlab, SciLab, IDL, Mathematica etc. lui seront aussi accessibles.
Le choix du nom C++ fait référence au symbole d'incrémentation ++ du langage C, afin de signaler qu'il s'agit
d'un langage C amélioré (C++ équivaut à C+1).
Quant au langage C, il a été créé en 1972 par Denis Ritchie avec un objectif relativement limité : « écrire un
système d’exploitation UNIX ». Mais ses qualités opérationnelles ont fait qu’il soit vite adopté par une large
communauté de programmeurs.
Une définition rigoureuse du langage a été réalisée en 1978 par Kernighan et Ritchie avec la publication de
leur ouvrage « The C programming language ».
« Un ordinateur est une machine bête, ne sachant qu’obéir, et à très peu de choses :
– Addition, soustraction, multiplication en binaire, uniquement sur des entiers.
– Sortir un résultat ou lire une valeur binaire (dans une mémoire par exemple).
– Comparer des nombres.
Sa puissance vient du fait qu’il peut être Programmé, c'est-à-dire que l’on peut lui donner, à l’avance, la
séquence (la suite ordonnée) des ordres à effectuer l’un après l’autre. Ces ordres codés en binaire sont
sauvés dans un fichier nommé « exécutable » (.exe sous Windows). Le grand avantage de l’ordinateur
est sa rapidité. Par contre c’est le programmeur qui doit TOUT faire. »
2 Premier programme.
Pour entamer l’étude du langage, beaucoup d’auteurs choisissent de présenter de manière très
simple un premier programme dont l’objectif est d’afficher la phrase « Hello, world !». Ce
programme est devenu par la suite très répandu. La finalité est que si vous êtes capable d’écrire, de
compiler et d’exécuter ce programme, alors vous pouvez élaborer d’autres programmes en suivant
ce même modèle.
1 #include<iostream>
2
3 int main()
4 {
5 std::cout << "Hello, World !" ;
6
7 return (0);
8 }
2.1 Edition
On dit éditer le programme, c'est-à-dire l’écrire. Pour cela, il existe beaucoup d’éditeurs de texte
qui permettent de le faire. Même document texte de Windows : « Bloc-notes » peut suffire.
Une fois édité, on obtient un fichier, qu’on appellera fichier source. En principe il doit porter
l’extension "*.cpp". A titre d’exemple on peut l’appeler "premier.cpp".
2.2 Compilation
Le compilateur est un super programme qui se charge de traduire en langage machine, ce que vous
écrivez en langage humain. Un compilateur du langage C++, va faire cette traduction dans le
respect règles d’écriture du langage.
Si le compilateur ne rencontre aucun problème il produit un nouveau fichier qui correspond à la
forme machine du programme "premier.cpp".
En principe l’extension de ce fichier est "*.exe", dans notre cas ce sera : "premier.exe".
La pré compilation.
La compilation.
L’édition des liens
Fichier
Source Objet
Source
Intermédiaire
C++
Autre
Source Objet
Source Exécutable
Intermédiaire
C++
Autres
Objets
Dans les paragraphes ci-après, on aura l’occasion de dire quelques mots à propos de ces différentes
étapes. Pour l’instant, la « compilation » se résume à la transformation d’un fichier source sous
forme d’un fichier texte : premier.cpp, en un fichier cible sous forme binaire : premier.exe.
Pré
compilation
"premier.cpp" "premier.exe"
Compilation
Edition de
liens
La compilation en soit, est réalisée via une commande, formulée au sein du système d’exploitation
utilisé : Windows, Linux etc. Elle diffère légèrement d’un système à un autre. Mais, de manière
générale, elle ressemblera à ceci :
2.3 L’exécution
EDI en français ou IDE en anglais (Integrated development environment) sont des applications fort
utiles, puisqu’elles regroupent dans un même espace les taches décrites ci-dessus : à savoir l’édition,
la compilation et l’exécution.
2.4.1 Aperçu.
L’EDI que nous utilisons en salle de TP et Code::Blocks : dont voici une capture d’écran.
2.4.2 Edition.
L’EDI contient une zone d’édition de texte, on peut y éditer le code source du programme
"premier.cpp".
2.4.3 Compilation et exécution.
Une série d’icones, qui sont des raccourcis, servent pour la compilation et l’exécution du fichier
édité. On laissera la découverte des autres détails sur la manipulation de cet environnement aux
séances de travaux pratiques.
On évoquera juste le résultat de l’exécution du programme ‘premier.exe’ : C’est l’affichage d’un
message. Il est obtenu dans une fenêtre séparée : la console, elle a l’aspect suivant :
#include<iostream> Entête
int main( )
Fonction Principale
std::cout << "Hello, World !";
return (0);
Implémentation
Les éléments qui le composent, sont :
2.5.1 #include<iostream>
Située en entête du fichier, elle demande d’inclure la librairie standard iostream.
En C++, certains aspects, comme les entrées/sorties, font partie de la librairie standard, et non du
noyau du langage lui-même. Cette distinction est importante parce que le noyau du langage est
disponible pour tout programme C++ sans aucune autre formalité, mais pour les parties située dans
la librairie standard, on doit explicitement en demander l’inclusion dans le programme.
#include<iostream> est une directive de pré compilation. Elle intervient avant la compilation.
Un « fichier » constituant la librairie standard iostream sera ajouté au fichier source avant même
l’étape de compilation.
D’autres éléments accompagne le mot main, ce sont : int et ( ). Leur présence est nécessaire, on
trouvera les explications les concernant dans le paragraphe dédié aux fonctions.
Dans la suite on va s’intéresser à la syntaxe d’écriture des instructions dans l’objectif de concevoir
nos propres programmes.
/*
programme : premier.cpp
auteurs : .....
date : Mars 2015
Affiche le message : Hello World !
*/
#include<iostream> // Entete
using namespace std; // espace de nommage
3.1 Généralités
La plus part des langages utilisent la notion de variable. Une variable est un nom (identificateur) qui
sert à repérer un emplacement dans la mémoire centrale. Notion simple qui contribue à faciliter la
réalisation de programmes. Elle permet de manipuler des valeurs sans avoir à se préoccuper de
l’emplacement mémoire. Cela est rendu possible parce qu’il existe un programme de traduction
(compilateur ou interpréteur) de votre programme dans le langage de la machine. C’est lui qui
attribuera une adresse à chaque variable.
Pour toutes les opérations, l’utilisateur n’a pas à connaitre l’adresse en mémoire d’une variable
mais seulement le nom de la variable.
De sa définition jusqu'à son utilisation, une variable n’est complètement définie qu’après avoir
franchi quatre étapes (pas forcément dans l’ordre, sauf la dernière):
1. Avoir obtenu un nom.
2. Avoir un type.
3. Avoir été déclarée.
4. Avoir obtenu une valeur.
La machine code l’information en bits : c'est-à-dire soit 0 soit 1. Ensuite elle les organise en bytes.
Le byte est la plus petite unité adressable d’un ordinateur. Aujourd’hui, les bytes de 8 bits se
sont généralisés en informatique.
Définition : L’octet est une unité de mesure en informatique. Elle mesure la quantité de données. Un octet
est lui-même composé de 8 bits, soit 8 chiffres binaires (0 ou 1). Le byte, qui est un ensemble de bits
adjacents, a presque toujours une taille d'un octet et les deux mots sont généralement, mais abusivement,
considérés comme synonymes.
Le langage C++ donne la possibilité d’attribuer à chaque variable un certain nombre d’octets, 1,2 ,4
ou plus. De plus il offre plusieurs possibilités de codages. Il adapte la variable à la nature de
l’information qu’elle représente.
La combinaison : taille en octets et codage de la représentation s’appelle le type de la variable.
Le langage C++ prévoit 3 types de base, avec des variantes pour chacun :
i. Types caractères
ii. Types entiers et Logique
iii. Types flottants. (réels)
3.2.2.1 Les types caractères.
Les différents types servant à représenter les caractères sont donnés dans le tableau suivant :
Pour ce type un seul bit suffirait pour coder les variables logiques, mais comme la plus petite
quantité adressable est l’octet (8 bit) alors les autres bits ne sont pas utilisés.
Le langage C a une approche quelque peu originale de représenter les variables logiques. En effet,
pour le langage C, la valeur 0 (zéro) représente la valeur logique 0 (faux/false) et tout autre
nombre non nul représente 1 (vrai/true). Tout type de base est bon pour représenter le type logique
en C. Mais il est courant de prendre le type int pour les variables logiques du C.
Il est important de savoir comment le langage C gère les valeurs logiques, parce que le C++, qui est
l’objet de notre étude, intègre d’office la syntaxe du C.
Le comportement du langage C, pour les variables logiques est résumé dans ce tableau :
Le comportement du langage C++ est plus clair, il est résumé dans ce tableau :
Type logique Taille (Octets) Valeurs acceptées
true false
Type identificateur ;
Exemples :
1
2 int main()
3 {
4 float prix;
5 int x1, y_1, z;
6 char _a, b, c;
7 unsigned short int A, B, C;
8 double prixPain, ageCapitane,dureeDeVie;
9 /** les incorrectes
10 long int 1A, A', A+B;
11 */
12 return 0;
13 }
A noter que le langage C restreignait les déclarations au début des programmes, le C++ quant à lui,
a étendu la possibilité de déclaration à tout le corps du programme.
A l’instar des mathématiques qui disposent d’opérateurs qui peuvent agir sur des fonctions ou sur
des variables, et les transformer ainsi en d’autres objets ; les langages C/C++ possèdent des
opérateurs qui vont agir sur des variables ou autres objets, et les transformer ou créer de nouveau
objets.
Il est d’une importance capitale de définir à chaque stade des opérations les éléments mis en
jeu. Les éléments dans une opération sont :
- Les opérateurs.
- Les opérandes.
Dans une opération il est possible que l’on soit en présence de l’un des trois cas suivants :
- d’un seul opérateur et d’un seul opérande. L’opérateur est dit être unaire.
- d’un seul opérateur et de deux opérandes. L’opérateur est dit être binaire.
- d’un seul opérateur et de trois opérandes. L’opérateur est dit être ternaire.
Dans le cas de plusieurs opérations, le langage définit un ordre d’exécution, il réalise une seule
opération à la foi. Si bien que l’on revient toujours à la distinction faite ci-dessus.
Il faut, d’un autre côté, préciser les positions relatives de l’opérateur et des opérandes.
A partir d’ici il faut dégager et assimiler une notion fondamentale en programmation. A savoir, la
notion de lecture/ écriture.
Par lecture, on veut dire lecture dans une adresse mémoire. Et par écriture on comprend l’écriture
dans l’adresse mémoire.
Ces deux notions se ressemblent beaucoup ; mais une différence de taille les sépare. Pour C/C++,
la lecture dans la mémoire est possible pratiquement pour toute les adresses sans conséquence
négative sur le déroulement du programme. Car l’adresse lue n’est pas modifiée par l’opération de
lecture.
Par contre l’écriture dans une mémoire efface le contenu précédent l’écriture. On dit aussi écrase ou
détruit le contenu de la mémoire. Par conséquent cette opération conduit à la perte
d’information. Les langages C/C++ prévoient la protection de certaines adresses, comme les
constantes par exemple ; et ne va pas permettre d’y écrire en signalant une erreur à la compilation.
Le langage C++, avec l’introduction des classes, va permettre une plus grande protection des
variables –qu’il va appeler attributs−. Il va verrouiller l’accès à certains attributs, ne permettant
qu’un accès restreint à celles-ci.
Toute fois, c’est au programmeur d’être vigilant quant à sa façon de gérer ces variables.
Affectation correcte :
A=5 ;
Affectation invalide :
5=A ;
Forme unaire.
Comme opérateurs unaires. Leurs écritures sont alors :
op opérande
Où op est + ou −. Et opérande peut être une variable de tout type parmi les types de base,
int, char, float etc.
L’effet de l’opérateur – est de changer le signe de la variable. Et + quant à lui, il laisse invariable
le signe de la variable.
Forme binaire.
Comme opérateurs binaires. Leurs écritures sont alors :
Operande_1 op operande_2
Les opérandes peuvent être là aussi des variables de types de base. Le résultat des opérations
sont comme en mathématiques : l’addition ou la soustraction des valeurs contenues dans les
variables.
3.3.2.2 Les opérateurs * de multiplication et / de division.
Ce sont des opérateurs binaires. On les utilise comme dans les opérations mathématiques de
multiplication et de division. La syntaxe est la suivante :
Opérande_1 op opérande_2
Les opérandes peuvent être là aussi des variables de tous les types de base.
3.3.2.3 L’operateurs % de modulo.
int a = 5, b = 3, c = 2 ;
float x ;
x = a + b / c;
Si on souhaite que le résultat soit un réel, il y aurait problème avec le terme b/c qui va être un
entier puisque b et c sont des entiers. Il faut forcer la conversion, en réel, de l’un des deux : b ou c.
pour cela on utilise l’opération de cast, de cette manière :
x = a + (float) b / c;
On a souvent besoin d’incrémenter, ou de décrémenter, d’une unité les variables qui servent de
compteurs. Pour ça, il y a dans C/C++ des opérateurs pour cet effet. Prenons par exemple le code
suivant :
int i = 0, j = 1 ;
/* instructions */
j = j - 1 ; //décrémentation
i = i + 1 ; //incrémentation
Ce code peut être remplacé par celui-ci :
int i = 0 ;
/* instructions */
j--;
i++;
++ (−−) est en lui-même un seul opérateur, composé de 2 caractères. Sa position par rapport à la
variable admet deux écritures : avant ou après la variable.
i++ ;
++i ;
La différence est dans la priorité attribuée à chacune. ++i est plus prioritaire que i++. Il en est de
même pour −−.
Prenons un exemple.
int i = 0, j = 0;
cout << "i = " << i++ << "j = " << ++j ;
Ce code affichera : i=0 et j=1. Parce que cout est prioritaire sur i++.
Et au contraire ++j et prioritaire sur cout.
opérateur équivalence
++i i=i+1
−−i i=i−1
i++ i=i+1
i−− i=i−1
Dans ce tableau la priorité est plus élevée en haut, elle décroit vers le bas
Avant de passer aux autres genres d’opérateurs, on va s’arrêter sur une notion qu’on a souvent
évoquée, sans vraiment en donner explication claire.
C’est la notion de priorité dans les opérations, ainsi que la notion d’associativité qui lui est
afférente.
3.3.5.1 Priorité.
Que se passe-t-il si dans une même instruction se trouve réunis plusieurs opérateurs et opérandes ?
On peut prendre comme exemple :
Opérande1 op1 opérande2 op2 opérande3
Où opérateurs 1 et 2 sont binaires par exemple. On s’attend à ce que le compilateur exécute les
opérations les unes après les autres et non simultanément. Tout comme en mathématiques en
définitive. La question devient quelle opération va-t-il effectuer en premier ?
En fait le langage donne un ordre de priorité aux différents opérateurs. Et il donne un tableau
résumant ces priorités par défaut.
Supposons que l’opérateur 2 est prioritaire sur l’opérateur 1. Alors les opérations vont se dérouler
selon le diagramme ci-dessous :
opérande1 op1 Opérande2 op2 opérande3
Résultat final
Si on souhaite que le compilateur fasse les opérations suivant un ordre défini ; et si cet ordre n’est
pas celui qui va être adopté par le compilateur ; alors dans ce cas on utilisera les parenthèses ( )
pour fixer les priorités.
Les parenthèses permettent d’imposer un ordre de priorité. Les opérations mises entre parenthèses
sont prioritaires sur les autres.
3.3.5.2 Associativité.
Dans le cas où, ça arrive, les opérateurs sont à égalité de priorité c.à.d. la priorité est identique pour
tous, c’est le principe d’associativité qui est utilisé.
le même qu’en mathématiques. A savoir qu’on associe les opérandes soit à partir de la gauche soit à
partir de la droite. Cela reste à préciser selon chaque opérateur.
L’égalité de priorité peut se produire dans le cas de la répétition du même opérateur. Mais aussi
dans le cas d’opérateur différents.
Exemple :
int a = 5, b = 7, c = 12, d ;
d = a + b + c ;
L’associativité pour + est de gauche vers la droite. Donc le calcul se fera comme si on faisait :
d = (a + b) + c ;
L’ensemble des priorités connues sur les opérateurs que nous avons évoqués jusqu’à présent est
résumé dans le tableau ci-dessous.
La priorité est décroissante de haut en bas.
Les opérateurs d’une même cellule ont la même priorité même s’ils sont sur des lignes différentes.
Sa syntaxe :
Opérande1 op opérande2
Opérande1 op opérande2 est une expression dont la valeur est 1 ou 0.
Il y a là, une différence très importante avec les opérateurs arithmétiques.
Pendant que dans une expression arithmétique, le type pouvait être celui de l’Opérande1, ou celui
de l’opérande2, le type d’une expression relationnel est nécessairement booléen.
Voir la représentation schématique de cette comparaison :
Les affirmations qui sont vraies se verront attribuer la valeur 1 celles qui sont fausses auront la valeur
0.
Si on utilise des variables au lieu des constantes de l’exemple précédent, le résultat serait similaire.
Soit l’exemple suivant :
int main()
{
int a = 10, b = 2;
float x = 1., y = 10.6;
char u = 'a', v = 'A';
return 0;
}
Remarque :
L’affichage par défaut, dune valeur booléenne, se fait avec les valeurs 0 et 1. Celui avec les valeurs
false et true, peu être obtenu par l’usage des manipulateurs boolalpha et noboolalpha –
inclure la bibliothèque iomanip –.
#include<iostream>
#include<iomanip>
int main()
{
cout << boolalpha << (10 > 2) << endl; ///affichera : true
cout << noboolalpha << (10 > 2) << endl; ///affichera : 1
return 0;
}
3.3.7.1 Définition.
Les opérateurs logiques sont des opérateurs qui agissent sur des objets de type booléens, et
produisent des résultats de type booléens aussi.
Il faut arriver à faire la distinction avec les opérateurs relationnelle, qui eux agissent sur des objets
de tout type et produisent des résultats de type booléen.
Opérateurs arithmétiques et opérateurs relationnels
3.3.7.2 Exemples
Voici quelques exemples pour fixer les idées :
(5<10) && (6>3) devient 1 && 1 et enfin donne 1
Si a = 5, b = 10, c = 6 et d = 3 alors l’expression ci-dessus s’écrirait :
(a<b) && (c>d) et elle donnerait 1.
! (a==b) deviendrait !(0) et donnerait 1.
Et aussi :
a || b 5 || 10 1||1 1.
!c !6 !1 0.
Avec la représentation du langage C pour les logiques ; ces écritures sont correctes
3.3.7.3 Les priorités et les associativités.
L’opérateur unaire ! est prioritaire sur tous les opérateurs arithmétiques binaires et sur les
opérateurs relationnels.
L’opérateur || est moins prioritaire que l’opérateur &&. Tous deux ont une priorité inférieure aux
opérateurs arithmétiques ou relationnels.
Tous ces opérateurs sont associatifs de gauche à droite. Par exemple, si on a :
bool d ; (ou int d )
d=a && b && c est équivalente à : (a && b) && c
Les instructions de contrôle sont des instructions qui permettent de contrôler et d’orienter
l’exécution du programme.
L’exécution du programme se fait pas à pas, on dit, de façon séquentielle. On a souvent besoin de
rompre cette séquence d’exécution :
Parfois on veut sauter certaines instructions : on dira d’elles que ce sont des instructions
conditionnelles.
D’autres fois on a besoin de répéter certaines instructions : on dira que ces instructions sont
répétitives.
Les structures de contrôle confèrent aux machines “un comportement intelligent”, les rendent plus
intéressantes. Et contribuent à la résolution d’un certain nombre de problèmes.
Les structures de contrôles sont au nombre de deux :
– Les structures conditionnelles. Dites aussi séquentielles ou de choix.
– Les structures de répétition. On dit aussi structures itératives
Début
faux/false/0
Condition
vrai/true/1
Instructions 1 Instructions 2
Fin
3.4.1.1.3 Sa syntaxe.
La traduction de l’algorithme précédent en langage C est :
if (expression)
instruction 1
else
Instruction 2
Dans le cas où, plusieurs instructions seraient présentes, il serai impératif de les grouper au sein d’un
bloc {} ; de cette manière :
if (expression)
{
instruction 11;
instruction 12;
...
}
else
{
instruction 21;
instruction 22;
...
}
3.4.1.1.4 Un exemple.
Appliquons la structure de choix dans le cas d’un programme qui lit 2 entiers au clavier et qui
affiche la plus grande des 2 valeurs :
int a, b;
cout << "entrez 2 nbres entiers : ";
cin >> a >> b;
if (a>b)
cout << "le maximum est: " << a << endl; // Instrunction 1
else
cout << "le maximum est: " << b << endl; // Instrunction 2
En saisissant les valeurs a = 5 et b = 1, par exemple, la condition a>b vaut 1 ; c’est l’expression 1
qui sera exécutée.
faux/false/0
Condition
vrai/true/1
Instructions
Fin
3.4.1.2.3 Sa syntaxe.
La traduction de l’algorithme précédent en langage C est :
if (expression)
instruction 1
if (expression)
{
instruction 11;
instruction 12;
...
}
3.4.1.2.4 Un exemple.
Dans cet exemple, trois variables a, b et c sont saisies, le programme affichera la valeur maximale.
int a, b, c, max;
cout << "Entrez 3 Entiers : " << endl;
cin >> a >> b >> c;
max = a;
if(b > max) max = b;
if(c > max) max = c;
On mémorise la variable a dans max. Si b est plus grand que a ; alors c’est b qui est mémorisé. Si c
est plus grand que a et b, alors c sera mémorisé dans max.
3.4.1.3 Les structures conditionnelles imbriquées
Cette forme de branchement conditionnel permet d’effectuer une suite de tests en cascade (les uns
après les autres), jusqu’à ce qu’à la première condition vraie. Si aucune n’est vraie, il exécute
l’instruction par défaut.
3.4.1.3.1 Son algorithme.
Si la première condition vraie porte le numéro i, alors les instructions exécutées seraient les
instructions i. ensuite le programme, sort de la structure conditionnelle.
Si aucune condition n’est vraie, alors les instructionsDefaut seront exécutées.
Comme la dernière ligne de cette structure est facultative, si elle est absente, aucune instruction ne
serait exécutée dans le cas où toutes les conditions seraient fausses.
3.4.1.3.2 Son organigramme.
Début
Fausse
Condition 1
Fausse
Vraie Condition 2
Fausse
Instruction(s) 2 Vraie
Instruction(s) 3
InstructionDefaut
Fin
Si la condition 1 est vraie alors les instructions 1 sont exécutées, et le programme ignore toutes les
autres instructions et va à la fin de si. Si elle est fausse, la condition 2 est évaluée ; si elle est vraie
les instructions 2 sont alors exécutées. Ainsi de suite. Si aucune des conditions n’est vraie, le
programme va à la ligne sinon (la dernière) et exécute les instructions par défaut.
3.4.1.3.3 Sa syntaxe.
if( condition_1)
instruction_1;
else if( condition_2)
instruction_2;
else if( condition_3)
instruction_3;
else if( condition_4)
instruction_4;
[else instructionDefaut;] // Facultatif
3.4.1.3.4 Un exemple.
Voici un programme qui lit la note d’un étudiant, et affiche le résultat de validation avec la mention
obtenue.
int N;
cout << "Entrer Note N, telle que 0<= N <=20" << endl;
cin >> N;
if( N < 0 || N > 20) cout << "Note Invalide " << endl;
else if ( N >= 16 ) cout << "Mention TB " << endl;
else if ( N >= 14 ) cout << "Mention B " << endl;
else if ( N >= 12 ) cout << "Mention AB " << endl;
else if ( N >= 10 ) cout << "Mention P " << endl;
else cout << "Module NV " << endl;
Qu’on interprète en disant : selon la valeur de expression, c.à.d. que si expression est
égale à valeur1, alors les instruction1 seront exécutées. Sinon, si expression est
différente de valeur1, on passe à valeur2 et on refait le même raisonnement. Et ainsi de
suite. Dans le cas où toutes les valeurs sont différentes de expression alors les instructions
par défaut seront exécutées.
3.4.1.4.2 Son organigramme.
Début
1 Avec break
Variable Valeur1 instructions1
0 Sans break
1 Avec break
Valeur2 Instructions2
0 Sans break
1 Avec break
Valeurn instructionsn
0 Sans break
Fin
Pour le cas de switch, il n y a pas de condition explicite, mais il y a une comparaison entre la
variable et la valeur, en cas d’occurrence d’égalité, il y a branchement vers les instructions.
3.4.1.4.3 Sa syntaxe.
switch (Variable)
{
case Valeur_1 : instructions_1
[break;] // facultatif
case Valeur_2 : instructions_2
[break;] // facultatif
case Valeur_n : instructions_n
[break;] // facultatif
default : instructions_def
[break;] // facultatif
}
Le compilateur vérifie, dans l’ordre, si variable est égale à une des constantes, dans lequel cas les
instructions correspondantes sont exécutés.
Si break est absent, les instructions qui suivent sont aussi exécutées. Si break est présent, le
programme va vers la fin de la structure.
Si aucune des constantes n’est égale à la variable de switch alors les instructions de default sont
exécutées.
3.4.1.4.4 Exemples.
Supposons que l’on veuille vérifier si une lettre saisie au clavier est une voyelle ou non ?
char c ;
cout << "Entrez une lettre : ";
cin >> c ;
switch(c)
{
case 'a' :
case 'e' :
case 'i' :
case 'o' :
case 'u' :
case 'y' : cout << c << " est une voyelle" << endl;
break;
default : cout << c << " n\'est pas une voyelle" << endl;
}
int n ;
cout << "Entrez une entier : ";
cin >> n ;
switch(n%2)
{
case 0 : cout << n << " est pair";
break;
case 1 : cout << n << " est impair";
}
TantQue <condition>
DebutTantQue
Instructions
FinTantQue
Tant que la condition est vraie on exécute les instructions. Dès que la condition devient fausse on
va à la ligne du programme situé après tant que, sans exécuter les instructions.
Début
0/false
Condition
1/true
Instructions
Fin
3.4.2.1.3 Sa syntaxe
En C/C++ la structure while est la traduction de tantQue, elle a la syntaxe suivante :
while(condition)
instruction
Où :
Condition est une expression logique, elle doit être entre parenthèses.
Instruction instruction à exécuter.
Dans le cas de la présence de plusieurs instructions, on place les instructions entre accolades.
while(condition)
{
Instructions
}
3.4.2.1.4 Exemples.
Exemple 1 : Une structure while qui affiche les nombres entiers compris entre deux nombres a et b
tels que a < b.
#include<iostream>
using namespace std;
int main()
{
int a = 10, b = 20, i;
i = a;
while(i <= b)
{
cout << i << endl;;
i++;
}
cout << "Valeur de i en sortie de boucle : " << i;
return 0;
}
Il est à noter que la valeur de i à la sortie de la boucle est 21. Puisque b vaut 20 ; la condition ne
sera fausse qu’à partir de i = 21.
Ce même exemple peut servir pour chercher si n est un nombre premier ou non. Il suffit de
contrôler si le nombre de diviseurs est égal ou supérieur à 2.
Exemple 4 : lire des nombres réels positifs ou nuls, dès qu’un nombre négatif est saisi la lecture
s’arrête.
float x;
x=1.;
while(x>=0.)
{
cin >> x;
}
Pour que l’on puisse accéder la première fois à l’intérieur de la boucle, il faut bien initialiser x à une
valeur non négative quelconque.
On peut ensuite modifier ce programme pour qu’il calcule la moyenne des valeurs saisies.
float x,som=0.;
int compt=0;
x=1.;
while(x>=0.)
{
cin >> x;
if (x>=0.)
{
compt++;
som+=x;
}
}
if(compt) cout << "la moyenne est : " << som/compt;
Faire
instructions
TantQue(condition)
Les instructions sont exécutées, au moins, une fois. Leur exécution plus d’une fois dépendra de l’état
de la condition.
Début
Instructions
Condition
1/true
0/false
Fin
3.4.2.2.3 Sa syntaxe
La traduction de Faire … TantQue dans le langage C/C++ est do…while() ;
do
instruction
while(condition);
Attention au point-virgule présent après la condition. La condition entre parenthèse doit être une
expression logique. Par ailleurs, dans le cas de la présence de plusieurs instructions, il faut les placer
entre accolades.
Do {
instructions
} while(condition);
3.4.2.2.4 Exemples.
D’une manière générale, tout ce qui est écrit avec une des deux formes de boucle peut être réécrit
avec l’autre moyennant des adaptations mineures.
Exemple 1 : Reprenons l’exemple 4 précédent.
Il s’agit de lire, au clavier, des nombres réels tant qu’ils sont positifs ou nuls ; dès qu’un nombre
négatif est saisi la lecture doit s’arrêter. Calculer ensuite la moyenne des nombres saisis.
do
{
cin >> x;
if (x>=0.)
{
compt++;
som+=x;
}
} while(x>=0.);
if(compt) cout << "la moyenne est : " << som/compt;
Comme on peut le constater, on lit d’abord x et ensuite on teste son signe. Selon sa valeur on
revient faire une autre lecture ou on sort de la boucle. Il n’a pas été nécessaire d’initialiser x comme
dans le cas de while.
Exemple 2 :
Afficher tous les multiples pairs de 3 inferieurs à 100.
int n = 100, i = 1;
do
{
if (i%2 == 0 && i%3 == 0) cout << i << " est pair et mult de 3" <<endl;
i++;
}while( i <= 100 );
3.4.2.3.2 Exemple.
On va prendre un exemple avec un cas de boucle fait avec la forme while que l’on convertie en
forme for. On pourrait écrire un programme qui affiche 5 fois le mot « hello » en utilisant une
variable de contrôle qui est un entier i :
On remarquera que :
L’expression1 : i = 0 correspond à l’initialisation.
L’expression2 : i < 5 correspond à la condition.
L’expression3 : i++ correspond à l’incrémentation.
Pour montrer que la présence des expressions, dans for( ; ; ) est facultative, on peut apporter
ces quelques modifications, au code ci-dessus :
int i;
i = 0;
for( ;i < 5; )
{
cout << "Hello ! " << i << endl;
i++;
}
L’opérateur séquentiel (,) permet de regrouper des sous-expressions dans une seule expression. Les
sous-expressions y apparaissent sous forme d’une liste, sur une même ligne. Ces sous-expressions
sont évaluées en séquence (à la suite les unes après les autres). La valeur d'une liste d'expressions est
celle de la dernière de la liste.
i++;
j += 5;
k = i + 2 * j;
Si on écrivait
i++, j += 5, k = i + 2 * j;
On obtiendrait un opérateur séquentiel avec (,) dans lequel les expressions précédentes sont
devenues des sous expressions d’une instruction terminée par (;).
L’expression i++ est d’abord évaluée, suivie de j += 5, et k = i + 2 * j est évaluée en
dernier. C'est-à-dire que l’associativité est de gauche vers la droite.
Il ne faut pas confondre cette écriture avec cette autre écriture :
i++; j += 5; k = i + 2 * j;
Laquelle à l’évidence est équivalente à la première, où les expressions occupaient une ligne chacune.
Ici, les trois sont sur la même ligne, mais chacune est terminée par un point-virgule.
Un autre exemple pour montrer la deuxième partie de la définition : La valeur d'une liste
d'expressions est celle de la dernière de la liste.
i = (j++, i+3, k+1);
Dans cet exemple, la variable i prendra la valeur k+1 tout simplement ; mais auparavant, la sous
instruction j++ sera exécutée, suivie de l’expression i+3 et enfin k+1. Comme k+1 est la dernière
expression, alors i sera égale à k+1. Notez que la présence des parenthèses est déterminante, sinon
la séquence précédente aura une autre interprétation.
L’usage de l’opérateur séquentiel se rencontre particulièrement dans les structures de contrôle de
répétition for.
int i, j;
Notez l’utilisation de (,) dans les initialisations et les incrémentations. Le critère d’arrêt de boucle,
est que i doit rester inferieur à j. Dès que ce n’est plus vrai, on arrête la boucle.
A l’exécution, on a la réponse ; l’intersection se trouve dans les intervalles [22,24] pour i et [24,27]
pour j.
6 int N, i, compt;
7
8 cout << "Entrez un nombre : ";
9 cin >> N;
10
11 for ( compt=0, i = 2; i < N; i++ )
12 {
13 if ( N % i != 0 ) continue;
14 cout << i << " est diviseur de " << N << endl;
15 compt++;
16 }
17 cout << "Nbre de diviseurs = " << compt;
A la ligne 13, il y a l’instruction continue. Si le reste de la division de N par i est non nul,
continue est activée. Alors les lignes 14 et 15 sont sautées, on reste dans la boucle mais on passe
dans le pas suivant, c.à.d. à i+1.
3.4.2.6.2 break.
Utilisée dans une boucle, break fait sortir de la boucle, en sautant toutes les instructions qui la
séparent de l’accolade fermant le bloc.
Exemple : étant donné un nombre entier N, on écrit un programme qui permet de dire s’il est un
nombre premier, ou non ?
Pour cela, on passe tous les nombres de 2 à N-1, si N possède un seul diviseur, il ne sera pas
premier. Si on rencontre un tel diviseur, on affiche un message et on utilise break pour arrêter la
boucle.
Une fois en dehors de la boucle, on teste i, s’il a atteint N, c’est qu’il n y a pas de diviseur de N. on
affiche un message.
6 int N, i, compt;
7
8 cout << "Entrez un nombre : ";
9 cin >> N;
10
11 for ( i = 2; i < N; i++ )
12 {
13 if ( N % i == 0 )
14 {
15 cout << i << " est diviseur de " << N << endl;
16 cout << N << " n\'est pas un nombre premier";
17 break;
18 }
19 }
20 if(i>=N) cout << N << " est un nombre premier ";
21
3.4.2.6.3 goto.
Avant de pouvoir utiliser l’instruction goto, on aura besoin de savoir ce qu’est une étiquette.
– Etiquette/Label.
Une étiquette –label en anglais- est une numérotation des lignes d’un programme.
Une étiquette doit porter un nom, qui respecte les règles des identificateurs.
Elle doit être insérée, à l’endroit du programme que l’on voudrait étiqueter, suivie du caractère
spécial (:).
Le nom donné à une étiquette n’a pas besoin d’être déclaré. Les étiquettes possèdent un espace
de noms propre.
– Exemples d’étiquettes.
L0, L1 et L2, dans le programme qui suit sont des étiquettes.
– goto.
Elle s’utilise avec la syntaxe :
goto etiquette :
goto L1 : // par exemple
Elle opère un branchement non conditionnel de la ligne d’appel, vers l’étiquette, sans aucune
formalité.
Pour illustrer ces propos, on va donner comme exemple, la conception d’une boucle avec goto,
sans avoir besoin, ni de while ni de for.
Cette boucle sera faite pour i allant de : i=0 à i=N, N étant un entier quelconque.
6 L0:
7 int N, i, compt;
8
9 cout << "Entrez un nombre >0 : ";
10 cin >> N;
11
12 i = 0;
13 L1:
14 cout << "valeur de i : " << i << endl;
15 /// + autres instructions
16 i++;
17
18 if ( i < N ) goto L1;
19 else goto L2;
20 L2:
21 cout << "Message: sortie de boucle" << endl;
22
Dans la ligne n°18 est présente l’instruction goto. Tant que i reste inférieur à N, goto renvoie vers
l’étiquette L1 (boucle), dès que i devient égale à N, goto renvoie vers L2 (hors boucle).
Les variables, telles que nous les avons vues, jusqu’à présent, ne permettent de stocker qu'une seule
donnée à la fois. Une information requiert un nom. Et donc à plusieurs informations, plusieurs
noms. A ce rythme, un programme risque de consommer un nombre considérable de noms.
Pour réduire le nombre de noms de variables dans un programme, le langage utilise :
Les tableaux – ou listes- pour grouper les données de même type, sous un seul nom.
Les structures pour grouper des données de types hétérogènes sous un même nom.
Il s’avère que ces tableaux et structures, ont des vertus supplémentaires, qui n’étaient pas offertes
avec des variables simples, comme par exemple, la possibilité d’opérer des processus de tri ou de
transferts de données.
3.5.2.1 Déclaration.
Pour exister, un tableau doit être, d’abord déclaré.
La syntaxe de la déclaration d'un tableau unidimensionnel est la suivante :
Type_des_données Nom_du_tableau [Nombre d'éléments] ;
Type_des_données Définit le type des éléments du tableau, char, int, float, etc.
Nom_du_tableau Est le nom attribué au tableau. Ce doit être un identificateur.
Nombre d'éléments Est un nombre entier qui détermine le nombre de cases que contient
le tableau. Ce paramètre doit être bien défini à la compilation. Ça peut
être une variable, déclarée avec #define, ou par const.
[] opérateur –obligatoire- contient la taille.
Exemples :
int t[5];
char lettre[6];
t[0]= 2*t[1]+5;
3.5.2.3 Exemple.
Voici un code dans lequel un tableau, de N entiers, est rempli par lecture au clavier ; puis affiché à
l’écran.
#include<iostream>
using namespace std;
const int N = 5;
int main()
{
int t[N],i;
}
1 INTRODUCTION ............................................................................................................................................... 3
2.3 L’exécution.................................................................................................................................................................... 6