You are on page 1of 38

INTRODUCTION AU C++

Le C++ est un langage parmi d'autres. Tous ne sont pas équivalents et peuvent avoir des utilisations
différentes. Je te propose ici de te donner quelques informations qui te permettront de mieux orienter
ton apprentissage. Tu sais c'est la partie chiante d'un cours quand le prof commence à raconter sa
vie...

L'historique

Toutes les machines qui nous entourent fonctionnent grâce à des suites d'impulsions (des
bits en base 2: "0" ou "1"). Les premiers programmeurs codaient directement leurs
instructions en binaire. Afin de faciliter la communication entre le développeur et la machine,
il fut nécessaire de développer une interface, un langage.

Dans un premier temps vinrent des langages bas niveau: les assembleurs. Ces langages
sont spécifiques à chaque machine et s'adressent directement aux composants constituant
celle-ci. C'est en fait une traduction directe du train binaire en instructions simples. (ex:
charger en mémoire une valeur, lire une valeur, faire une addition,...)

Ensuite, dans un souci de simplicité, les langages devinrent de plus en plus complexes,
proches de l'anglais écrit. Se succédèrent alors: BASIC, COBOL, FORTRAN. Notons que
plus un langage est dit évolué plus il devient spécifique et facile d'utilisation (nous parlons
ici uniquement de la syntaxe).

En 1972, Dennis Ritchie créa le C ancêtre du C++. Ce langage peut être qualifié à la fois de
bas niveau car il permet de faire appel à toutes les ressources de la machine mais aussi de
langage évolué. En effet, il introduit une syntaxe assez complexe par rapport aux langages
précités ainsi que de nombreuses fonctions évoluées. Ces fonctions sont regroupées en
librairies que tu peux considérer comme des boîtes à outils.

La mise à jour la plus marquante du C fut apportée par Bjarde Stroustup en 1982. Il y
intégra la programmation objet. Le C++ est en fait une surcouche du C (C++ signifie une
incrémentation du C). Il hérite donc de tous les outils du C.

Principe de la programmation objet

Trois générations de langage se sont succédés et coexistent encore aujourd'hui: les


langages dits linéaires, modulaires puis objets.

Tous les premiers langages s'exécutaient de façon linéaire. Chaque ligne du programme
était lue puis exécutée jusqu'à la dernière. Il était possible de faire des sauts ou des boucles
mais le principe restait le même. Cette approche simpliste ne pouvait pas s'appliquer à des
programmes complexes. De plus, les développeurs ne pouvaient pas réutiliser des outils
déjà écrits. Le langage assembleur est un exemple de langage linéaire.

Afin, de réutiliser le code et d'éviter les redondances, les langages dits modulaires virent le
jour. Le principe est de regrouper un ensemble d'instructions dans des fonctions ou
procédures. En effet, chaque tâche exécutée par un programme représente un nombre
variable d'instructions. Ces instructions sont réunies afin de pouvoir segmenter le code et de
favoriser la réutilisation de celui-ci. Le C fait partie de ces langages.
Enfin, la méthode objet apparue. Elle est en fait une évolution de l'approche modulaire. Elle
lui apporte principalement trois aspects primordiaux:

• L'encapsulation: cette technique permet de réunir des variables et des fonctions au


sein d'une même entité nommée classe. Les variables sont appelées les données
membres, les fonctions sont appelées les méthodes. L'accès aux données et
méthodes peut-être aussi réglementé.

• L'héritage: cette technique permet de définir une hiérarchie de classe. Chaque


classe fille hérite des méthodes et des données de ces "pères". En pratique, la
classe de base est une classe générique, ainsi plus on descend dans la hiérarchie,
plus on spécialise cette classe.

• Le polymorphisme (non ce n'est pas un gros mot!): nous verrons que les objets sont
définis par leur classe (sorte de moule). Pour expliquer le polymorphisme, retenons
que deux objets, héritant une même méthode d'une classe parente, peuvent réagir
de façon différente à l'appel de cette méthode.
Par analogie, nous pouvons considérer l'exemple débile de l'ascenseur et de la
bombe nucléaire... ben oui... Ces deux objets descendent de l'objet machine et
donc héritent de la fameuse fonction "bouton rouge" que chaque machine possède.
Maintenant, je te mets au défi d'appuyer sur le bouton rouge d'un ascenseur: c'est
beaucoup plus violent que pour la bombe nucléaire. En effet, dans le cas de la
bombe H, elle pète loin de toi sur un atol de Polynésie, alors que les coups de
balais de ton gardien qui te coure dans la cage d'escalier, ça tu les sens!
L'appel de la même fonction a donc entraîné un comportement différent.

Au cas où tu n'aies pas suivi les dernières notions, ne t'inquiète pas. Premièrement,
rappelle toi que tu es un (gros) nul et fier de l'être : NULL POWER, deuxièmement ces
notions sont vues en détail dans la partie 2 du cours.

Quel type d'utilisation?

Saches tout d'abord que le C++ est le langage le plus utilisé par la communauté des
développeurs. Ce langage est utilisé aussi bien sur UNIX que MacOS ou Windows. Entre
autres, la plupart des applications graphiques comportent une partie en C++, ce qui inclut
les traitements de textes, utilitaires, jeux,...
Toutefois, il ne faut pas croire que tout est possible avec le C++ ou au contraire que c'est un
langage dépassé face au Java ou C#. Tu verras, si l'informatique devient ton métier, que
l'on ne peut pas se limiter à un seul langage. Le choix du langage est souvent imposé par
différents facteurs: portabilité, rapidité, disponibilité de composants déjà écrits, outils de
développement,...

En fait, nous ne rentrerons pas dans un débat stérile afin de savoir quel langage est le plus
avancé technologiquement. Le C++ est ici un choix d'apprentissage. En effet, à cause de
sa conception le C++ hérite des langages modulaires et objets. Il n'est ni totalement objet ni
restreint à un langage modulaire de type C. Ce conflit de génération qui rend le C++ un peu
"bâtard" est un avantage pour les débutants. En fait, lorsque tu auras fini cet apprentissage
tu auras la possibilité et la compétence de t'orienter tout seul vers le langage de ton choix.

Je te rappelle aussi que ce site à pour vocation de t'apprendre les bases de la


programmation. Il n'a pour l'instant pas l'ambition de se spécialiser dans un sous-ensemble
du C++. Il ne sera donc pas fait question d'environnement graphique ou de développement
spécialisé dans une technologie donnée (Microsoft DirectX, Open GL, Linux, réseau,...)
Différence C/C++

Le C++ introduit un certain nombre d'améliorations syntaxiques, d'extensions et de


nouveautés par rapport au C, dont les principales sont essentiellement liées à la
programmation orientée objet. On peut décomposer le langage en C++=C+E+S+P avec:

• C désigne la norme AINSI C

• E représente les écarts à la norme

• S représente les spécificités de C++ non liées à la théorie objet

• P représente les possibililités de la programmation objet (la programmation objet


n'est pas imposée)

Pour le néophyte, ces différences ne poseront aucun problème. Pour la personne qui sait
déjà programmer en C, les quelques incompatibilités ou différences seront exposées tout le
long du cours.

Conclusion

Une fois les connaissances de ce site acquises, il te sera facile de trouver des ouvrages
permettant d'aller plus loin dans l'apprentissage du C++. Tu passeras alors du stade "gros
nul" au stade "nul mais se soigne".

OUTILS DE PROGRAMMATION
Nous allons commencer par la prise en main d'un outil de programmation. Après ce cours tu pourras
écrire un programme basique, le corriger (tout le monde ne s'appelle pas Billou), le compiler puis
l'exécuter. C'est top, non?

Introduction

Les applications réalisées à partir de ce site se présenteront sous la forme d'une console
du type Dos pour les adorateurs du WindowsPlanté et du MacOsTropCher.Quant aux fans
de Linux ou autres Unix, nul besoin de leur présenter leur cher Shell. En fait, ces
applications seront semblables à ce que l'on trouve sur calculette: les informations
s'affichent sous forme de texte uniquement, le curseur clignotant te permet d'entrer des
informations lorsque c'est nécessaire; la validation se fait grâce à la touche Enter.

Nous allons nous appuyer sur un outil appelé DevC++ qui a l'avantage d'être gratuit et très
clair. Nul ne t'empêche d'utiliser un autre éditeur/compilateur. Pour trouver en une liste non
exhaustive, cliquez ici. Et si tu cherches une assurance: par là, ou un site de funboard, par
ici. Enfin si tu es décidé à aller plus loin ça se passe sur cette page! Non mais!

Compilation

On peut dès maintenant créer l'application correspondante. Pour cela, utilise le bouton
compile ou dans le menu Execute clique sur Compile.

Cette fenêtre permet de voir l'évolution de la compilation des fichier C++.


Pour lancer l'application ainsi créée, il suffit d'appuyer sur le bouton Execute.

Il ne se passe rien (une fenêtre apparaît puis disparaît)

L'application est créée dans le même dossier que le projet. Tu peux aussi la lancer en
double cliquant sur son icône.

Premier Programme

Par tradition, tout apprentissage d'un nouveau langage commence par l'affichage du
message "Hello World". C'est en fait l'opération la plus simple que l'on puisse apercevoir.
Tape le code suivant ou récupère le fichier associé, puis compile à nouveau le projet (le
fichier doit être inclus dans le projet et visible dans la fenêtre projet).
#include <iostream.h>
#include <stdio.h>

void main()
{

cout<<"Hello World!";

}
fichier
> Hello World!

Tu peux voir très rapidement une fenêtre, avec le message Hello World, s'ouvrant puis se
refermant. Pour que la fenêtre persiste, il suffit de rajouter la ligne suivante: getchar();
.Elle donne l'ordre au programme d'attendre que tu appuies sur une touche.

#include <iostream.h>
#include <stdio.h>

void main()
{

cout<<"Hello World!";
getchar();

}
fichier
> Hello World!
>

Ne t'inquiète pas si tu ne comprend pas le code précédent, son explication est vue en détail
dans le chapitre suivant.
Correction d'erreurs

Nous allons voir ce qui se passe si une erreur se glisse dans le code C++. Modifie le
programme comme ci-dessous, puis compile-le:

#include <iostream.h>
#include <stdio.h>

void main()
{

cout<<"Hello World!" //le point virgule est


gtchar(); manquant
//la fonction est mal
} ecrite

fichier

> 7
outilprogrammation4.cpp parse error before '('

Lors de la compilation, Dev-C++ t'affiche 1 erreur à la ligne 7. "Parse error" signifie une
erreur de syntaxe; cela est consécutif, la plupart du temps, à l'oubli d'un point-virgule ou
d'une parenthèse.
Ajoute à nouveau le point-virgule et compile:

> 7 outilprogrammation4.cpp implicit declaration of function `int


gtchar(...)'

Une nouvelle erreur est signalée ligne 7. "Implicit declaration" signifie que la fonction
concernée n'existe pas. En effet la fonction utilisée se nomme getchar() avec un "e".
Modifie à nouveau le programme, la compilation ne présente alors plus de problème.

Conclusion

Voilà, il ne te reste plus qu'à explorer le logiciel pour compléter sa prise en main (une aide
et un tutorial en anglais te sont fournis avec Dev-C++ 4). Pour commencer l'apprentissage
du langage C++, en lui-même, je te propose le prochain chapitre: Premiers Pas.
PREMIERS PAS
Nous y voilà! C'est un pas ridicule pour l'homme, mais un pas de géant pour des gros nuls comme
nous! Tu rentres dans le monde merveilleux de la programmation et si tu viens à bout de ce chapitre
sur les structures de base d'un programme en C++, tu auras le droit de... passer à l'étape suivante!

Les instructions:

Voici les éléments de base d'un programme écrit en C++:

#include <iostream.h>

void main()
{

int grosNul;
grosNul = 0;
//pour éviter que
char fin; // l'application ne
cout<<"Appuyer sur une touche pour // quitte d'elle même
quitter!";
cin>>fin;

}
fichier
>[ne
renvoie rien après compilation et exécution]
>Appuyer sur une touche pour quitter!
>

#include <iostream.h>
Les premières lignes de code servent à introduire des informations utiles au compilateur:
directive du préprocesseur. Ici on lui demande d'inclure la librairie iostream.h qui gère les
fonctions standards d'entrée et de sortie d'informations (entrée/sortie). Ce sont les fonctions
qui te permettront d'écrire à l'écran ou de rentrer des données par le clavier. De même, si
on veut utiliser des fonction du type mathématique (cos, sin,...), il faudra inclure la
bibliothèque math.h par le code: #include <math.h>.

void main()
Ce sont des mots clefs introduisant le corps du programme principal. Sachez dès
maintenant que void veut dire néant et que main veut dire principal. Tous programmes en
C++ nécessitent un point d'entrée qui constitue la première fonction appelée dans ton
programme: c'est le rôle de la fonction main(). Elle est appelée automatiquement lors de
l'exécution du programme. Comme void l'indique notre fonction ne renvoie rien. Nous
aurions pu choisir de renvoyer un entier en écrivant int main() par exemple. Mais ne sois
pas pressé, ce point fait partie du cours sur les fonctions, alors patience!
De plus, tu peux remarquer que main() est suivi de parenthèses. C'est le cas pour toutes
fonctions. Les parenthèses servent à passer des arguments à la fonction, c'est-à-dire des
données. Pour plus de détails et d'exemples concrets sur ce point tu peux encore aller jeter
un oeil du côté des fonctions! Dans notre cas, les parenthèses sont vides, cela veut dire que
notre fonction ne prend pas d'arguments, elle n'a besoin d'aucune donnée extérieure pour
fonctionner.

{}
Le programme principal est délimité par les deux accolades, {}, une ouvrante, une fermante.
Le contenu de ces deux accolades constitue un bloc d'instruction. Note qu'il est préférable
lors de l'écriture du code de fermer une accolade juste après l'avoir ouverte. Ainsi, tu
éviteras de te poser les questions du type Pourquoi ça ne marche pas ? alors qu'il suffisait
de fermer l'accolade!
Comme dans l'exemple, l'alignement vertical et le décalage du code par rapport à celles-ci
permettent aussi une lecture et un déboggage plus aisée du code. En pratique, utilise les
tabulations qui te permettent d'aligner facilement ton code. Attention, cette convention n'est
pas obligatoire, mais elle te facilitera la vie!

";"
A l'intérieur d'un bloc d'instruction, chaque ligne se termine par un point virgule, ;. Chaque
ligne représente alors une "phrase" indépendante des autres, interprétée séparément par le
compilateur, appellée une instruction.

int grosNul;
Cette instruction correspond à la déclaration d'une variable de type int (entier) nommée
grosNul. Attention! Le C++ fait la différence entre les majuscules et les minuscules, les
variables GrosNul et grosNul ne sont donc pas les mêmes: on dit que le C++ respecte la
casse. Elles seront détaillées plus loin. Tu remarqueras que cette ligne se finit par un point
virgule (;). C'est donc une instruction. L'absence du ; entraînerait une erreur de compilation.

La ligne suivante comporte l'initialisation de la variable grosNul à 0: l'entier grosNul contient


maintenant 0. Remarque que le C++ ne tient pas compte des espaces: grosNul=0 signifie la
même chose que grosNul = 0. Tu peux donc aérer ton code pour qu'il soit le plus lisible
possible.

Ne prête pas attention aux 3 dernières lignes du programme. Tu les comprendras par la
suite. Elles sont là seulement pour éviter que l'application ne se ferme d'elle-même. Il te
suffit d'appuyer sur une touche pour quitter le programme.

Les commentaires:

Reprenons le même morceau de code:

#include <iostream.h>

void main() //ne retourne rien


{
/* grosNul est un entier
int grosNul; valant 0 */
grosNul = 0;

char fin; //pour éviter que


cout<<"Appuyer sur une touche pour // l'application ne
quitter!"; // quitte d'elle même
cin>>fin;

}
fichier
>[ne
renvoie rien après compilation et exécution]
>Appuyer sur une touche pour quitter!
>

Par rapport au premier code, nous avons ajouté des lignes qui apparemment ne servent à
rien. Ce sont des commentaires. Ceux-ci sont pourtant fondamentaux dans un programme.
Un développeur un peu moins nul doit s'assurer que son code est suffisamment clair et
explicite pour qu'un autre programmeur puisse le lire et éventuellement le modifier. Tu dois
donc commenter en détail ton programme pour qu'il soit lisible pour les autres, mais aussi
pour toi (après un mois de bronzette au soleil et de perte de neurones, tu auras du mal à
comprendre ton code s'il n'y a aucun commentaire !).

Les commentaires sont ignorés par le compilateur. Il en existe deux sortes en C++ :

• pour une ligne : // le commentaire sera ce qui suit sur un même


ligne
• pour un ensemble de lignes : /* le commentaire sera tout ce qui est
entre les caractères slash et étoile sur plusieurs lignes*/

Les flux d'entrées et de sorties

Les flux d'entrée et de sortie vont nous permettre d'entrer des valeurs au clavier ou bien
d'en afficher à l'écran. Bon, au lieu de regarder un code tout fait et d'avoir la solution tout de
suite, construisons ensemble notre programme. Entre nuls, on arrivera peut-être à avancer!
Alors, nous allons afficher une phrase à l'écran. Pour cela, si tu as été attentif plus haut,
nous avons tout d'abord besoin de la bibliothèque gérant les entrées/sorties : iostream.h.
Le code commence donc ainsi:

#include <iostream.h>

void main()
{

Maintenant, nous avons


besoin d'afficher des instructions. Nous utiliserons la fonction cout de l'anglais output:
sortie (prononcé cé a outte). Elle se construit comme suit:

cout << element1 <<...<< elementn;

Tout ce qui suit << est affiché à l'écran. Si element1 est une variable, la valeur de cette
variable s'affichera (0 pour notre variable grosNul). Nous pouvons aussi remplacer element1
par une chaîne de caractères, c'est-à-dire un mot ou une phrase, qui doit être
nécessairement entre guillemets " ". Notre code peut donc se continuer de la manière
suivante:
#include <iostream.h>

void main()
{

cout << " Bienvenue sur C++ pour les (gros)


nuls " << endl ;

char fin;
cout<<"Appuyer sur une touche pour quitter!";
cin>>fin;

}
fichier
>Bienvenue sur C++
pour les (gros) nuls
>Appuyer sur une touche pour quitter!
>

Remarque qu'après la première instruction, nous en avons rajouté une seconde: endl (end
lign) qui réalise un retour à la ligne.
De plus, certains caractères spéciaux ne sont pas compréhensibles par le compilateur tel
quel. Ainsi, pour effectuer un retour à la ligne à l'intérieur de la chaîne de caractère, il faudra
inclure \n et pour inclure un guillemet, \". Par exemple:

#include <iostream.h>

void main()
{

cout << "Les \"nuls\" sont parmi nous!\nLes


nulles aussi!" << endl ;

char fin;
cout<<"Appuyer sur une touche pour quitter!";
cin>>fin;

}
fichier
>Les "nuls" sont
parmi nous! (\n= retour à la ligne)
>Les nulles aussi!
>Appuyer sur une touche pour quitter!
>

D'autre part, dans tout programme qui se respecte, il y a une interaction entre l'utilisateur et
la machine. Pour saisir un élément puis l'utiliser ultérieurement, nous utiliserons alors ici la
fonction cin de l'anglais input: entrée. Elle se construit comme suit:

cin >> element1 >> element2;

Attention, pour saisir une variable element1, tu dois l'avoir définie auparavant dans ton
programme. Après l'avoir récupérée, tu pourras l'utiliser dans la suite du programme.
Note bien que cout est suivi de << et cin de >>, << et >> vont dans le sens du flux.
Voyons un exemple de saisie:

#include <iostream.h>

void main()
{

int grosNul; //définition de la


variable
cin >> grosNul;
//saisie d'une valeur au
cout <<"Un (gros) nul vaut: clavier
"<<grosNul<<endl; //(par exemple 0)
//affichage
char fin;
cout<<"Appuyer sur une touche pour //pour éviter que
quitter!"; // l'application ne
cin>>fin; // quitte d'elle même

}
fichier

>0 (saisie)
>Un gros nul vaut: 0 (sortie + retour à la ligne)
>Appuyer sur une touche pour quitter!
>

Je pense que tu as compris maintenant le fonctionnement les 3 dernières lignes du


programme. En effet, après avoir déclaré la variable fin de type char (caractère), celui-ci
affiche à l'écran le message "Appuyer sur une touche pour quitter!" et attend que l'utilisateur
saisisse un élément. Lorsque tu appuieras sur une touche, le programme quittera alors
automatiquement.

Bonus

Maintenant que tu as assimilé et compris toute la base de la base du C++, va faire quelques
exercices ! Tu verras, après tu te sentiras beaucoup moins nul, et en plus, ils sont corrigés,
alors tu n'as vraiment rien à craindre!

• Exercice n°1: As-tu bonne mémoire?


• Exercice n°2: Trouve l'erreur!
• Exercice n°3: Qu'est ce que je renvoie?
• Exercice n°4: Affiche à l'écran.
• Exercice n°5: Petit problème de géométrie...

Si ça ne te suffit pas, tu as le droit à des petits bonus!

• La notation hongroise.

Si tu maîtrises le sujet, tu peux passer à l'étape suivante qui fera de toi un moins nul parmi
les gros nuls: les variables.
C++ pour les (gros) nuls
http://www.cplusnul.com
exercice@cplusnul.com

Premiers pas 2001


As tu une bonne mémoire?

/////////////
// Enoncé //
/////////////
------------------------------------------------------------------------------

Serais-tu capable de réécrire le premier programme du cours,


qui consistait à initialiser un entier nomme grosNul à zéro?

////////////////
//Indiquation //
////////////////
------------------------------------------------------------------------------
Afin de verifier ton résultat, compile ton code pour en faire un executable ou
regarde la solution indiquée plus bas.
Tu peux télécharger le fichier en faisant un "clique droit> enregistrer la cible sous..."
sur le lien "Sources" en dessous de la fenêtre de dialogue.

/////////////
//Solution //
/////////////
----------------------------------------------------------------------------*/

#include <iostream.h>

void main()
{
int grosNul; //declaration de la variable
grosNul = 0; //initialisation de la variable

//pour que l'application ne quitte pas seule


char a;
cout<<"Appuyer sur une touche pour quitter!";
cin>>a;
}

/*------------------------------ EOF ---------------------------------------*/

http://www.cplusnul.com
exercice@cplusnul.com

Premiers pas 2001


Trouve l'erreur!

/////////////
// Enoncé //
/////////////
------------------------------------------------------------------------------

Voici un programme. Celui-ci doit m'écrire un message à l'écran.


Il y a une erreur, laquelle?
*/

#include <iostream.h>

void main()
{
/*Message de bienvenue
cout << " Bienvenue sur C++ pour les (gros) nuls!" << endl ;
*/

//pour que l'application ne quitte pas seule


char a;
cout<<"Appuyer sur une touche pour quitter!";
cin>>a;
}

/*
/////////////
//Solution //
/////////////
------------------------------------------------------------------------------*/
//Les commentaires /* */ englobent le flux de sorties cout.
//Il n'est donc pas pris en compte par le compilateur et le programme n'affiche rien à l'écran.

C++ pour les (gros) nuls


http://www.cplusnul.com
exercice@cplusnul.com

Premiers pas 2001


Qu'est ce que je renvoie?

/////////////
// Enoncé //
/////////////
------------------------------------------------------------------------------

Que renvoie à l'écran ce programme?

#include <iostream.h>

void main()
{
int a=4;
cout <<"a vaut: "<< a <<endl;

//pour que l'application ne quitte pas seule


char c;
cout<<"Appuyer sur une touche pour quitter!";
cin>>c;
}

/////////////
//Solution //
/////////////
----------------------------------------------------------------------------*/

//Ce programme écrit à l'écran: "a vaut: 4", retourne à la ligne et écrit:
//"Appuyer sur une touche pour quitter!".
/*------------------------------ EOF ---------------------------------------*/

C++ pour les (gros) nuls


http://www.cplusnul.com
exercice@cplusnul.com

Premiers pas 2001


Petit Problème de géométrie

/////////////
// Enoncé //
/////////////
------------------------------------------------------------------------------

Afficher à l'écran la valeur du périmètre d'un cercle.


La valeur du rayon de ce cercle devra être saisi au clavier lors du lancement du programme.

////////////////
//Indiquation //
////////////////
------------------------------------------------------------------------------
L'équation donnant la valeur du périmètre d'un cercle est: P=2*Pi*R.
Le type d'un nombre réel (comportant des décimales) est le type "double".

/////////////
//Solution //
/////////////
----------------------------------------------------------------------------*/

#include <iostream.h>

void main()
{
double Rayon, Pi; //définition des données: double=réel
Pi = 3.14;
cin>>Rayon; //saisi de la valeur du rayon
cout <<"le perimetre est "<<2*Pi*Rayon<<endl;

//pour que l'application ne quitte pas seule


char a;
cout<<"Appuyer sur une touche pour quitter!";
cin>>a;
}

/*------------------------------ EOF ---------------------------------------*/

LES VARIABLES
Tout programme informatique nécessite de stocker et de manipuler des informations. Ces
informations peuvent être de plusieurs types comme le nom de ton chat dans un programme de
gestion d'animaux domestiques (très utile), une date, un nombre,… Les variables ont pour but de
satisfaire ce besoin.

Définition

Une variable est une zone de mémoire réservée possédant plusieurs attributs :

• Un nom : c'est un identifiant permettant de faire référence à cette zone mémoire.


L'appel de ce nom sera substitué par sa valeur par l'ordinateur.

• Un type : c'est une propriété définissant quels types de données peuvent être
stockées dans une variable. Cela peut être un nombre, un caractère,…

• Une taille : à un type correspond généralement une taille de mémoire maximum


pouvant contenir la valeur de cette variable. Cette taille est exprimée en bit.

• Une valeur : c'est l'information qui nécessite d'être stockée, comme le nom de ton
chat.

• Une portée: c'est le domaine de validité des varaibles. Ce point est vu plus en détail
à la fin du chapitre.

-C'est bien beau tout cela, mais comment définit-on une variable ?
-Est-ce que c'est l'endroit pour répondre à de telles questions ? Il y a quand même des
sujets plus importants dans le monde : la libération des bébés phoques du zoo de
Vincennes, l'entartrage de Billou ou les discussions philosophiques sur la légitimité du
couteau dans le pot de Nutella.
-Ben oui, c'est le lieu ! Alors fait pas [censuré] tu es là pour apprendre !

Pour déclarer une variable, on utilise la syntaxe suivante :


type1 nomVariable; //déclaration de la
variable "nomVariable"

type2 nomVariable1, //définition de


nomVariable2,...,nomVariableN; plusieurs variables à
la suite

typeN est le type de la variable ; il définit la nature des données qu'elle peut recevoir.
nomVariableN représente le nom servant à y faire référence. On peut comme dans
l'exemple déclarer plusieurs variables de suite à condition qu'elles soient du même type. On
les sépare alors par une virgule. Notons aussi que deux variables ne peuvent pas avoir le
même nom même si elles sont de types différents.

Pour l'initialisation d'une variable, on utilise la syntaxe suivante :

type1 nomVariable = valeur;


//initialisation d'une
type2 Variable; variable
Variable = valeur;
//autre possibilité
type3 nomVariable1 = valeur1,
nomVariable2 = valeur2;
//initialisation de
plusieurs variables à
la suite

L'affectation d'une valeur à une variable s'effectue, pour les types simples, grâce à
l'opérateur =. La valeur affectée à la variable doit respecter son type et sa taille. Enfin,
comme indiqué, il est possible d'initialiser plusieurs variables successivement.
Notons aussi que l'initialisation d'une variable, préalablement déclarée, est obligatoire pour
permettre la compilation d'un code. C'est à dire que l'on ne peut pas déclarer une variable
qui ne sert à rien.

Le nommage des variables ne respecte pas de règle particulière hormis l'exclusion des
espaces et des caractères accentués. Pourtant il est généralement conseillé de respecter
des règles de normalisation: voir notation Hongroise.
Les types simples

Nous avons vu que toute variable possède un type. Par défaut, plusieurs types simples sont
prédéfinis comme les entiers, les caractères ou les décimaux. Toutefois, il est possible de
définir son propre type; mais ne mettons pas le traîneau avant les rennes:

Mot Clef Type Taille Intervalle Exemple


16
int entier -32768 à 32768 int i=2;
bits
-128 à 127
char caractère 8 bits (ASCII)
char lettre='a';
32 3.4e-38 à
float réel 3.4e+38
float Pi=3.14;
bits
64 1.7e-308 à
double réel 1.7e+308
double alpha=0.001;
bits
unsigned 16
int entier 0 à 65535 unsigned int absolu=0;
bits
unsigned 0 à 255
char caractère 8 bits (ASCII)
unsigned char enter='/n';
32 -2.15e-9 à
long int entier 2.15e+9
long int grand=33700;
bits
long 80 3.4e-4932 à long double
double réel 1.1e+4932 tresGrand=39565655.2323565;
bits
L'initialisation d'une variable de type char se fait avec la valeur entre simple guillemet: '. De
façon générale, un caractère est représenté par sa valeur entre guillemets ou sa valeur
numérique correspondante: voir ASCII .
Le tableau des types exposés plus haut n'est pas exhaustif. En effet, on peut tout à fait
combiner un mot clef du type short (court), unsigned (valeur absolue), long (long) avec
un des types primaires char, int, float ou double. De plus, il n'est pas nécessaire
de tous les retenir, saches seulement les utiliser à bon escient. Le choix de type doit
dépendre de la nature de l'information à stocker et de l'intervalle des valeurs possibles.
#include <iostream.h>

void main()
{

int entier= 235,k=9;


char a, lettre='b'; //initialisation
a='B'; d'entiers et de
caractères
cout<<"Un chiffre: "<<entier<<endl;
cout<<"Un caractere: "<<lettre<<endl; //affichage de leur
valeur
cout<<"Appuyer sur une touche pour
quitter!"; //pour éviter que
cin>>a; l'application ne
quitte d'elle même
}
fichier

>Un
chiffre: 235
>Un caractere: b
>Appuyer sur une touche pour quitter!
>

Nous verrons tout au long du cours qu'il existe des types de variables plus complexes
comme les tableaux, les classes, les structures et les énumérations.

Les opérations

Une information stockée dans une variable peut être lue mais aussi manipulée. En effet, on
peut effectuer une grande quantité d'opération sur ces variables.

La réallocation : par défaut, une variable n'est pas une constante ; c'est à dire que sa
valeur peut être modifiée. Pour réallouer une variable on utilise l'opérateur d'initialisation,
généralement =.
#include <iostream.h>

void main()
{

int entier= 235; //allocation de la


entier=0; variable entier
//modification de sa
cout<<"La valeur de \"entier\" est: : valeur
"<<entier<<endl;
//affichage
cout<<"Appuyer sur une touche pour
quitter!";
cin>>entier;

}
fichier
>La
valeur de "entier" est: 0
>Appuyer sur une touche pour quitter!
>

Si on désire imposer la constance d'une variable grâce au mot clef const, alors cette
opération de réallocation n'est plus possible.

Opération arithmétique : une opération arithmétique est une instruction permettant de


stocker le résultat d'une opération arithmétique dans une variable, de l'afficher à l'écran ou
bien d'autres jolies choses encore. Par exemple, a=1+2 ; est une opération arithmétique
dont les opérandes sont 1 et 2 et dont l'opérateur est +. Les opérateurs arithmétiques
existants sont les suivants:

Mot Clef Signification Exemple


+ addition int i=2+3;
- soustraction float alpha=2-0.3;
* multiplication float P; int R=2; P=2*3.14*R;
/ division int j=2/3; //j est égal à 0 car j est un entier
modulo
% (reste de la int j=2%3; //j est égal à 2
division)

Le résultat de la division de deux entiers donne un autre entier. Dans notre exemple,
2/3=0.667 en réalité; pourtant la valeur retournée dans j est la valeur 0 car j est un entier
(int) qui ne peut pas recevoir de valeur décimale. De plus, l'opérateur % permet de
récupérer le reste de cette division entière. Le signe % s'applique uniquement aux entiers
(int). Si tu essayes de compiler l'expression suivante: int j=2%0.5; le compilateur t'indiquera
une erreur.

Les opérandes de toutes ces expressions peuvent être des constantes, des variables, des
résultats d'autres opérations ou des valeurs retournées par des fonctions. Pour faciliter, la
lecture d'expressions pouvant être parfois très complexes, il est recommandé d'utiliser les
parenthèses aussi souvent que possible.
#include <iostream.h>

void main()
{

int a= 1,b=3,c=1; //allocation des


double racine1=0,racine2=0; variables

racine1=(-b-sqrt(b*b-4*a*c))/(2*a);
racine2=(-b+sqrt(b*b-4*a*c))/(2*a); //operation arithmétique
//sqrt() est la fonction
cout<<"Les racines du polynome racine carre
"<<a<<"x2+"<<b<<"x+"<<c<<" sont:
"<<endl; //affichage des racines
cout<<racine1<<endl<<racine2<<endl; d'un polynome du second
degré
cout<<"Appuyer sur une touche pour
quitter!";
cin>>a;

}
fichier

>Les
racines du polynome 1x2+3x+1 sont:
>-2.61803
>-0.38196
>Appuyer sur une touche pour quitter!
>

Opération logique: ce type d'expression permet de stocker le résultat d'une opération


logique dans une variable. Ce résultat peut prendre deux états booléens: vrai (différent de
0) ou faux (égal à 0). C'est à dire que lors de l'exécution du programme l'ordinateur va
évaluer si l'expression est vraie ou fausse. Par exemple, 3>2 est une expression ayant
comme opérateur logique le signe > ; cette expression renvoie le booléen Vrai (1). Les
opérateurs logiques existant sont les suivants:

Mot Clef Signification Exemple


< inférieur à int resultat=2<3; //resultat=1 c'est vrai
inférieur ou égal int resultat=(2.5<=(6/2)); //resultat=1 c'est
<=
à vrai
> supérieur à int resultat=2>3; //resultat=0 c'est faux
supérieur ou égal
>= int resultat=(2>=(4/2)); //resultat=1 c'est vrai
à
== égal à int resultat=2==3; //resultat=0 c'est faux
int resultat=(2==2) && (3==2); //resultat=0
&& ET logique
c'est faux
int resultat=(2==2) || (3==2); //resultat=1
|| OU logique
c'est vrai
!= différent de int resultat=2!=3; //resultat=1 c'est vrai
Ces opérateurs sont très utiles dans le cas des boucles et branchements conditionnels vus
plus tard.

Opération d'incrémentation et de décrémentation : ces opérateurs sont incontournables


pour les langages dont la syntaxe est héritée du C, ce qui est le cas du C++. Derrière ce
terme barbare (à prononcer avec un accent suédois) ce cache un mécanisme très simple.
L'incrémentation est l'ajout de 1 à une variable numérique ou à un caractère, la
décrémentation est la suppression de 1. Voilà la liste de ces opérateurs :

Mot Clef Syntaxe Equivalence


++ x++; x=x+1;
++ y=x++; y=x; puis x=x+1;

++ y=++x; x=x+1; puis y=x;

-- x--; x=x-1;
-- y=x--; y=x; puis x=x-1;
-- y=--x; x=x-1; puis y=x;

L'incrémentation et la décrémentation peuvent être postfixées (après la variable) ou


préfixées (avant la variable). Dans le cas où l'opérateur est préfixé, l'ajout ou la suppression
se fait avant l'allocation donc pour un opérateur postfixé l'allocation se fait avant l'ajout ou la
suppression. C'est assez bête dit comme cela mais c'est régulièrement source d'erreurs.

Entre nous, tu ne trouves pas qu'il est long ce chapitre? Je t'invite à de détendre un peu:
prends une pause, ferme les yeux, pense à une île paradisiaque avec la femme ou l'homme
de tes rêves... STOP! Faut pas déconner quand même, on n'est pas là pour rigoler, allez
hop, exercices:

• Exercice n°1: Division euclidienne

• Exercice n°2: Incrementation

• Exercice n°3: Un peu de logique

Conversion

Tu as vu que chaque variable possède un type qui déterminera quel type de valeur il est
susceptible de contenir. Il n'existe pas de mécanisme permettant de changer le type d'une
variable, pourtant il est tout à fait possible de convertir une valeur et de stocker le résultat
dans une variable de type adéquat. Prenons un exemple: imaginons que l'on veuille stocker
la valeur entière de Pi (3) qui est un décimal (3,14..). Il suffit alors de convertir la valeur de
Pi en entier (int) puis stocker cette valeur dans une autre variable de type entièr.
Il existe trois mécanismes de conversion:

La conversion implicite: Tu vas dire que je t'agresse encore avec des mots savants. C'est
en fait la conversion la plus simple car le compilateur se charge de la réaliser pour toi. Dans
la plupart des cas, si tu essayes d'initialiser une variable avec une valeur qui ne correspond
pas à son type, le compilateur fera la conversion de façon " implicite ".
#include <iostream.h>

void main()
{

int entier= 3.14;


//float dans int
char caractere= 65;
//int dans char
int entier2='A';
//char dans int
double decimal=entier;
//int dans double

cout<<entier<<endl<<caractere<<endl
entier2<<endl<<decimal<<endl;

cout<<"Appuyer sur une touche pour


quitter!";
cin>>caractere;

}
fichier
>3
>A
>65
>3 (la perte de donnée est irrémédiable)
>Appuyer sur une touche pour quitter!
>

Attention, cette technique est à utiliser avec parcimonie (ouah moi aussi je fais des mots
compliqués). Il n'y pas de problème lorsque l'on convertit implicitement un type de petite
taille vers un type de taille supérieure (int vers float), alors que le contraire entraîne au
moins une perte de donnée voire une aberration du résultat.

Le cast: Autrement appelé conversion explicite, cette technique permet de forcer une
conversion. L'opérateur cast consiste à indiquer le type entre parenthèses devant la variable
à convertir: type1 variable1=(type1)variable2. Voici un exemple de syntaxe:
#include <iostream.h>

void main()
{

int entier= (int)3.14;


//cast
d'un
double decimal=6.56; decimal
int entier2=(int)decimal; en entier

char caractere=(char)56; //cast


d'un
decimal
cout<<entier<<endl<<decimal<<endl<<entier2<<endl en entier
<<caractere<<endl;
//cast
cout<<"Appuyer sur une touche pour quitter!"; d'un
cin>>caractere; entier en
caractere
}

fichier
>3
>6.56
>6
>8 (56 est la valeur ASCII de '8')
>Appuyer sur une touche pour quitter!
>

Cette méthode est très utile dans l'emploi des fonctions et des objets. En effet, les fonctions
vues plus tard imposent le type des arguments demandés et peuvent ne pas faire de
conversion implicite. Néanmoins, je te conseille de l'utiliser le plus souvent possible: ton
code sera plus intelligible et moins tu seras assisté par le compilateur mieux tu identifieras
les erreurs.

Les fonctions de conversion: Tu verras l'utilisation des fonctions dans le chapitre suivant.
Pourtant, sache qu'il existe des fonctions fournies avec tous les environnements C et C++
(fonctions standards). Certaines de ces fonctions te permettent de convertir des variables
vers des types différents.
Voici, un exemple que tu comprendras sûrement mieux grâce au chapitre suivant:
#include <iostream.h>

int ctoi(char a)
{

return (a-'0');

}
void main()
{

char caractere= '2';


int entier1, entier2;

entier1=(int)caractere;
entier2=ctoi(caractere);
//cast d'un entier
cout<<entier1<<endl<<entier2<<endl; en caractere
//utilisation d'une
fonction
cout<<"Appuyer sur une touche pour
quitter!";
cin>>caractere;

}
fichier
>50 (le
caractère '2' correspondant à la valeur ASCII 50)
>2 (le caractère '2')
>Appuyer sur une touche pour quitter!
>

Dans cette exemple, la conversion explicite a seulement rangé le caractère '2' dans un type
int, ce qui correspond à une valeur dans le tableau ASCII différente de '2'. La fonction de
conversion int ctoi(char) a initialisé l'entier avec la valeur 2 et non sa représentation
ASCII.

La portée d'une variable

Si tu as bonne mémoire (je sais je déconne:-) tu te rappelles qu'une variable possède un


nom, un type, une taille, une valeur et une portée. Ce dernier point indique le domaine de
validité d'une variable. Il dépend de l'endroit où est placée cette variable:

• en local: tous les exemples précédents et exercices utilisent ce type


d'emplacement. Une variable est déclarée dans un bloc d'instructions: entre deux
accolades. Cela peut être une fonction ou une boucle. La variable n'existe alors
qu'entre ces deux accolades; au-delà la zone mémoire est effacée. La portée d'une
variable locale est son bloc d'instruction.
#include <iostream.h>

void main()
{

int variableLocale=1;
cout<<variableLocale<<endl; //declaration dans un
{ bloc

int variableLocale=2;
cout<<variableLocale<<endl;
//declaration dans un
} autre bloc

cout<<variableLocale<<endl;

cout<<"Appuyer sur une touche pour


quitter!"; //declaration dans le
cin>>variableLocale; premier bloc

}
fichier

>1
>2 (valeur locale au bloc)
>1
>Appuyer sur une touche pour quitter!
>

• en globale: la variable globale est déclarée en dehors de tout bloc. Elle est
déclarée au début du fichier source; c'est d'ailleurs la seule instruction avec les
directives préprocesseurs à être tolérée en dehors des blocs d'instructions
(fonction). La portée d'une variable globale est tout le fichier où elle est déclarée.

#include <iostream.h>

char variableGlobale='a'; //declaration en


dehors du bloc
void main()
{

cout<<"VariableGlobale:
"<<variableGlobale<<endl; //appel

cout<<"Appuyer sur une touche pour


quitter!";
cin>>variableGlobale;

}
fichier
>Variable
Globale: a
>Appuyer sur une touche pour quitter!
>
Il faut toutefois utiliser les variables globales avec modération car il y a des risques de
conflits avec d'autres variables nommées de la même façon.

Bonus

Bon allez encore quelques exercices pour la route,... Pour ceux qui ne voient pas de quelle
route je parle, passez votre chemin,... Et que je n'entende personne me poser la question
sur le chemin!

• Exercice n°4: Conversion

• Exercice n°5: Valeur de la variable

• Exercice n°6: Récapitulatif

Si tu maîtrises le sujet, tu peux passer à l'étape suivante qui fera de toi un moyen nul parmi
les gros nuls: les fonctions.

LES FONCTIONS
Les fonctions de la vie c'est un peu comme en C++, certaines personnes sont vouées à faire grève,
d'autres à gagner du fric, beaucoup à faire chier le monde et enfin les meilleurs d'entre nous à devenir
moins nul en C++. Le rapport avec le schmilblick : tu verras en lisant ce chapitre qu'il n'y en a aucun.

Introduction

Tu as vu dans l'introduction que le C++ hérite des outils du C, en particulier son aspect
procédural. Cela consiste à découper le programme en une série de blocs d'instructions
indépendants les uns des autres. Ces blocs sont les fonctions. Une fonction regroupe une
ou plusieurs instructions qui permettent de réaliser une tâche précise qui peut se répéter
plusieurs fois. Ainsi, un problème complexe peut être découpé en plusieurs sous
problèmes, c'est-à-dire plusieurs fonctions.

Définition et Déclaration

Une fonction est un bloc d'instructions qui demande des informations passées en
paramètres et qui retourne un seul résultat. Tu peux l'identifier au modèle des fonctions en
mathématiques, même si ce n'est pas ta tasse de thé :

z = f(x1, x2,…,xn)

Pour réaliser une opération précise, la fonction f a besoin de données externes (x1, x2,
…,xn). Le résultat de l'opération est stocké alors dans la variable z.
En C++, la déclaration d'une fonction respecte la syntaxe suivante :

typeRetour nomFonction(type1 //declaration de la


argument1, type2 argument2, …) //fonction
{ "nomFonction"

//instructions
return (variableRetour);

}
La
définition d'une fonction se découpe donc en 5 éléments :

typeRetour : il s'agit du type de la variable retournée par la fonction, toujours placé avant
le nom de celle-ci. Ce type peut correspondre aux types standards du C++ (int, char,
double…) ou à d'autres types de données plus complexes vus dans les chapitres suivants.

nomFonction : c'est le nom grâce auquel tu pourras appeler la fonction dans ton
programme. Ce nom doit être suffisamment explicite pour comprendre le but de la fonction.
La première lettre doit être un caractère, les espaces et accents ne sont pas autorisés. (voir
nommage)

(type1 argument1, type2 argument2, …) : tu déclares à cet endroit les arguments


de la fonction. Ce sont des informations extérieures nécessaires à son fonctionnement. Il
s'agit de variables dont la valeur peut être différente à chaque appel de la fonction. Elles
sont donc placées entre parenthèses et séparées par des virgules. Tu dois préciser le type
de chaque argument avant de donner son nom. Cependant, si la fonction ne prend pas de
paramètres (c'est possible si sa tâche ne nécessite pas d'informations externes), on utilise
le mot clé void entre les parenthèses. Ce mot clé est aussi sous-entendu si tu ne mets rien
entre parenthèses. Par exemple tu peux écrire :
int fonction(void)
ou
int fonction()

Le bloc d'instructions : délimité entre accolades, tu peux y inclure tout type d'instructions.
C'est le cœur de ta fonction.

return variableRetour; : Pour retourner le résultat de la fonction, on utilise le mot


clé return suivi du nom de la variable. Il est utilisé en dernière ligne de la fonction. En
effet, dès que ton programme rencontre ce type d'instruction, il quitte automatiquement la
fonction. On verra par la suite que la valeur retournée peut être récupérée et utilisée dans la
suite du programme.

Voici maintenant un exemple de déclaration de fonction. Je sais, il est temps ! Je t'aurais


même proposé de prendre une pause si je n'avais pas un complexe de vieux dictateur raté.

int addition(int a, int b)


{
// declaration d'un entier
int resultat; // operation arithmetique
resultat = a+b; utilisant les arguments

return (resultat); // renvoi du resultat

}
fichier
> (ne
renvoie rien après compilation)

Tu retrouves tous les éléments évoqués plus haut. En cas d'oubli de l'instruction return
(resultat); , le compilateur provoque une erreur, sauf dans le cas des procédures.
Mais qu'est ce que tu me racontes là (me dit Arnold !) ? Un procédure a les mêmes buts et
caractéristiques qu'une fonction, sauf qu'elle ne renvoie pas de résultat et l'instruction
return (resultat); est donc supprimée. Comme elle ne renvoie rien, le type de la
variable de retour est donc remplacé toujours par le mot clé void :

#include <iostream.h>
void affiche(void) // ou void affiche() :
{ declaration d'une
// procedure sans
cout << " Je suis une procédure " << parametres
endl ;
// affichage d'un
} message a l'ecran
fichier
> (ne
renvoie rien après compilation)

Ceci est donc une procédure qui, dans ce cas, ne prend pas de paramètres, elle se
contente d'afficher un message à l'écran.
Appel d'une fonction

Pour appeler une fonction, ou l'exécuter, il suffit d'écrire dans ton programme son nom avec
la valeur des ses arguments éventuels entre parenthèses, suivi d'un point virgule :
nomFonction(argument1,argument2,argument3) ;
Reprenons le premier exemple :

#include <iostream.h>
int addition(int a, int b)
{

int resultat;
resultat = a+b; // declaration d'un
entier
// operation
return (resultat); arithmetique
// utilisant les
} arguments
// renvoi du resultat
void main()
{

int x; // programme
int y=3; principal
int z;
int buf ;
// declarations
d'entiers
x=addition(2,4) ;
cout << "La valeur de x est " << x <<
endl ;
z=addition(x,y) ;
cout << "La valeur de z est " << z <<
endl ;
cout << "z+1 vaut " << addition(z,1) //appels de la
<< endl ; fonction et affichage
//des resultats
cout<<"Appuyer sur une touche pour
quitter!";
cin>>buf;

}
// pour ne pas que
l'application
// quitte seule
fichier
> La
valeur de x est 6 (2+4)
> La valeur de z est 9 (6+3)
> z+1 vaut 10 (9+1)
> Appuyer sur une touche pour quitter!

Dans ce programme, nous avons donc fait plusieurs appels différents de la fonction
addition. Dans le 1er appel, nous avons passé deux arguments de type entier (ici 2 et 4)
comme la fonction le demande. Ces paramètres sont alors substitués aux mots clés des
arguments (ici a et b) de la fonction pour faire le calcul. De plus, pour récupérer le résultat
de l'addition, il suffit d'utiliser l'opérateur d'allocation =. La valeur renvoyée par la fonction
est donc copiée dans x qui est bien un entier défini préalablement. N'oublie pas qu'à cause
de la portée des variables, main ne peut pas avoir accès à la variable resultat de la fonction
addition, c'est pourquoi il faut la récupérer dans une autre.
Les autres appels de la fonction montrent des méthodes différentes au niveau du passage
des paramètres.
Dans le 2ème appel, on passe directement des variables (ici x et y), mais de la même façon
leurs valeurs sont recopiées dans les variables a et b de la fonction.
Le 3ème appel est là pour te montrer que tu es assez libre dans ce passage d'argument et
que dans le même appel tu peux passer une variable et une valeur entière numérique.
La façon d'appeler ta fonction peut aussi être simplifiée. Dans la mesure où elle renvoie une
valeur, tu peux afficher directement celle-ci grâce à l'instruction cout.

Le programme te permet bien de comprendre qu'une fonction est réutilisable et qu'elle


t'évite ainsi d'écrire plusieurs fois le même code contenu dans la fonction. Ce principe
facilite aussi la maintenance de ton code. En effet, supposons que la façon de faire une
addition change demain, il te faudra juste modifier la méthode de calcul dans ta fonction, au
lieu de la modifier plusieurs fois dans ton programme… Mais bon c'est comme les dents des
poules !

Passage d'arguments par valeur et par référence

Le C++ te propose différentes techniques de passage d'arguments aux fonctions : le


passage par valeur et le passage par référence.

[note de la rédaction: Si tu décides de passer ce stade et que tu prends le temps de comprendre le


chapitre suivant, tu auras de ta propre volonté abandonné le piteuse état d'ignorance dans lequel tu te
trouves. Les auteurs de ce site ne pourront en aucun cas être tenu responsable des fléaux qui
peuvent s'en suivre. Dans l'éventualité d'une pluie de grenouilles ou d'une nuée de sauterelles,
veuillez contacter immédiatement l'exorciste le plus proche de votre domicile.]

Passage par valeur


Jusqu'à maintenant, dans toutes les fonctions que nous avons vues, les paramètres étaient
passés par valeur. Cela consiste à fournir à la fonction des copies des variables fournies en
argument et non les variables elles-mêmes. Le programme fournit à la fonction uniquement
la valeur de cette variable et non la case mémoire en elle-même.
Prenons l'exemple d'une fonction qui modifie la valeur d'un de ses paramètres :
#include <iostream.h>
void zorro(char lettre) // declaration de la
{ fonction
// zorro qui modifie
lettre = 'z' ; // le caractere passe
en
} // parametre

void main()
{
// programme
char x = 'a' ; principal
int buf ;
// declaration et
cout << "Avant, la variable x vaut " << initialisation
x << endl; // d'un caractere
zorro(x) ;
cout << "Après, la variable x vaut " <<
x << endl; //appels de la
fonction et affichage
cout << "Appuyer sur une touche pour //des resultats
quitter!";
cin>>buf; // pour ne pas que
l'application
} // quitte seule
fichier
>
Avant, la variable x vaut a
> Après, la variable x vaut a
> Appuyer sur une touche pour quitter!

Et non, ce n'est pas une erreur ! Tu remarques que la valeur de x n'a pas changé. C'est ce
que je t'explique depuis une heure ! C'est parce que tu as fait un passage par valeur. A
l'appel de la fonction zorro (désolé), la valeur de x ('a') a été recopiée dans la variable
lettre. La valeur de lettre a été modifiée en 'z', mais x reste inchangé !
Bon, mais comment faire alors pour modifier de cette façon une variable passée en
argument ? Et bien continue de lire, c'est écrit…

Passage par référence


Lors d'un passage par référence, tu peux manipuler à l'intérieur de la fonction la valeur
d'une variable externe passée en paramètre. Pour pouvoir passer une variable par
référence, rien de plus simple ! Il te suffit d'ajouter le symbole & devant un paramètre de ta
fonction à la suite du type. Ce symbole permet de passer la variable elle-même et non une
copie. Etudie l'exemple précédant modifié en conséquence :
#include <iostream.h>
void zorro(char &lettre) // declaration de la
{ fonction
// zorro qui modifie
lettre = 'z' ; // la caractere passe
en
} // parametre

void main()
{
// programme principal
char x = 'a' ;
int buf ; // declaration et
initialisation
cout << "Avant, la variable x vaut " // d'un caractere
<< x << endl;
zorro(x) ; //appels de la
cout << "Après, la variable x vaut " fonction et affichage
<< x << endl; //des resultats

cout << "Appuyer sur une touche pour // pour ne pas que
quitter!"; l'application
cin>>buf; // quitte seule

}
fichier
>
Avant, la variable x vaut a
> Après, la variable x vaut z
> Appuyer sur une touche pour quitter!

C'est donc ici la variable x qui a été modifiée comme le montre l'affichage.

En conclusion, dans le premier exemple on a substitué la valeur de a dans lettre


(passage par valeur), dans le deuxième exemple, on a remplacé la variable lettre par la
variable a (passage par référence).

Prototype

Derrière ce nom hightech, se cache quelque chose de très simple. Tu as sans doute
remarqué dans tous les exemples, que les fonctions étaient définies avant d'être appelées.
Le main est laissé à la fin. Ceci pour la simple et bonne raison qu'une fonction doit toujours
être "connue" par le programme avant d'être utilisée. Logique, me diras-tu! Sache en tout
cas que si tu ne respectes pas cet ordre (vas-y, essaie !), le compilateur génère une erreur.
Cependant, tu peux contourner ce problème et placer la définition de tes fonctions à la fin
du programme ou dans un autre fichier. Pour cela, il existe les prototypes de fonctions. Il
s'agit de donner une déclaration succincte de ta fonction, placée au début du programme,
avant d'être appelée pour la première fois. Ainsi le compilateur a suffisamment
d'informations (nombre et type des paramètres, de la variable de retour…) pour la
reconnaître et ne pas générer d'erreur.

La syntaxe est la même que la 1ère ligne de la déclaration de la fonction :

typeRetour NomFonction(type1 argument1, type2 argument2, …);


ou
typeRetour NomFonction(type1, type2, …) ;

Mais tu remarques bien :

• il n'y a pas de bloc d'instructions,


• le prototype se termine par un point virgule,
• le nom des arguments est optionnel, le type suffit au compilateur.

Tu pourras tester cet exemple :

#include <iostream.h>

double calculPerimetre(double rayon); //prototype de la


fonction
void main()
{ // programme principal

double r,p;
int buf;
cout << "Donner un rayon du cercle :
" << endl;
cin >> r ;
p = calculPerimetre(r);
cout << "Le perimetre est de : " << p //appels de la
<< endl; fonction et affichage
cout<<"Appuyer sur une touche pour //du resultat
quitter!"; // pour ne pas que
cin>>buf; l'application
// quitte seule
}

double calculPerimetre(double rayon)


{ //declaration de la
fonction
double Pi = 3.14;
double perimetre;
perimetre = 2*Pi*rayon;
return (perimetre);

}
fichier
>
Donner un rayon du cercle :
> 3 (valeur rentrée par l'utilisateur)
> Le perimetre est de : 18.84
> Appuyer sur une touche pour quitter!

Tu constates que tout se passe bien à la compilation et à l'exécution. Tu obtiendras le


même résultat en inversant main et calculPerimetre. Mais je devine ta question : à quoi
ça sert ? C'est vrai, on pourrait aussi bien laisser les fonctions au début. En fait, c'est
surtout une question de lisibilité de ton programme. Si tu places toutes tes fonctions au
début, il manquera de clarté et le main qui en est la partie principale sera repoussé tout en
bas. De plus, cela te permet d'avoir une vue d'ensemble rapide des fonctions utilisées dans
le programme.
Bon, je sens ton esprit un peu confus quant aux prototypes... allez, si tu veux, vas voir tout
de suite le bonus: comment découper son code en C++ (construction)

Concepts avancés

Valeur par défaut


Le C++ te permet de donner des valeurs par défaut aux arguments des fonctions. Cette
valeur par défaut est utilisée lorsque un paramètre n'est pas passé à la fonction lors de son
appel. Pour attribuer une valeur par défaut à un paramètre, il te suffit d'assigner une valeur
à l'argument lors de la déclaration de la fonction avec le symbole d'allocation =. Voici
quelques exemples explicatifs :

#include <iostream.h>

void affiche(int x=1) //declaration de la


{ fonction

cout << x << endl;

void main()
{
// programme principal
int y=5 ;
int buf ;
affiche(y);
affiche();
cout<<"Appuyer sur une touche pour
//appel avec argument
quitter!";
//appel sans argument
cin>>buf;
// pour ne pas que
l'application
} // quitte seule
fichier
> 5
> 1
> Appuyer sur une touche pour quitter!

Ici tu as deux façon d'appeler cette fonction :

• avec un argument (ici y), la valeur par défaut est ignorée et la fonction affiche utilise
la valeur de y (5).
• sans argument, dans ce cas, la fonction utilise la valeur par défaut 1 et l'affiche.

Mais, fais bien attention avec les valeurs par défaut ! A partir du moment où un argument en
possède une, tous les arguments suivants dans la déclaration doivent également en
posséder une. Voici le début d'une fonction qui provoque une erreur de compilation : void
fonction(int a, int b=0, int c).
La fonction correcte est : void fonction(int a, int b=0, int c=10).
A toi donc de réfléchir soigneusement à l'ordre de passage des arguments si tu souhaites
utiliser les valeurs par défaut.
Attention! Si tu écris le prototype d'une fonction ayant une valeur par défaut, tu ne dois
préciser la valeur par défaut que dans le prototype, une fois pour toute, et non plus dans la
déclaration. Sinon, le compilateur génère une erreur.

#include <iostream.h>

void affiche(int x=1); //prototype de la


fonction
void main()
{ // programme principal

int y=5 ;
int buf ;
affiche(y) ;
affiche() ;
cout<<"Appuyer sur une touche pour //appel avec argument
quitter!"; //appel sans argument
cin>>buf; // pour ne pas que
l'application
// quitte seule
}

void affiche(int x)
{
//on ne repete pas la
cout << x << endl; valeur
//par defaut
}
fichier
Surchar
ge de fonction
La surcharge de fonction consiste à définir des fonctions ayant le même nom, mais un
nombre d'arguments différents. Cette technique permet donc de définir des fonctions faisant
ou non le même traitement dans des contextes différents.
#include <iostream.h>

int division(int x) //declaration de la


{ fonction
//division avec 1
int y=1 ; argument
return (x/1) ;

}
int division(int x, int y)
{

return (x/y) ; //declaration de la


fonction
//division avec 2
} arguments
void main()
{

int buf ;
int a=10;
int b=5; // programme principal
cout <<division(b) << endl ;
cout << division(a,b) << endl ;
cout<<"Appuyer sur une touche pour
quitter!";
cin>>buf;
//appel avec 1
} argument
//appel avec 2
arguments
// pour ne pas que
l'application
// quitte seule
fichier
> 5
> 2
> Appuyer sur une touche pour quitter!

Tu as 2 fonctions portant le même nom. La première ne prend qu'un argument de type


entier et la deuxième deux arguments de type entier. Ne t'en fais pas: le compilateur sait
quelle fonction utiliser parmi les 2. Tu verras par la suite que cette notion est très souvent
utilisée dans la programmation objet.

Bonus

Bon, ouf ! On s'en est sorti ! Il est temps maintenant de passer aux exercices:

• Exercice n°1: Appeler une fonction


• Exercice n°2: Demandez le menu!
• Exercice n°3: Valeur des variables
• Exercice n°4: Corrige l'erreur!
• Exercice n°5: Valeur par défaut
• Exercice n°6: Programme récapitulatif (construction)
Et pour toi, un petit bonus level !

• Comment découper son code? (construction)

Enfin si tu désires continuer dans le monde magique du C++ avec la découverte des
boucles, des instructions conditionnelles, des elfes et autres farfadets, consulte le chapitre
suivant (construction). Tu deviendras un bof nul parmi les nuls!

You might also like