Professional Documents
Culture Documents
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.
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:
• 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.
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.
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.
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()
{
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:
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:
#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.
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:
#include <iostream.h>
}
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++ :
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()
{
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()
{
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()
{
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:
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()
{
}
fichier
>0 (saisie)
>Un gros nul vaut: 0 (sortie + retour à la ligne)
>Appuyer sur une touche pour quitter!
>
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!
• 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
/////////////
// Enoncé //
/////////////
------------------------------------------------------------------------------
////////////////
//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
http://www.cplusnul.com
exercice@cplusnul.com
/////////////
// Enoncé //
/////////////
------------------------------------------------------------------------------
#include <iostream.h>
void main()
{
/*Message de bienvenue
cout << " Bienvenue sur C++ pour les (gros) nuls!" << endl ;
*/
/*
/////////////
//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.
/////////////
// Enoncé //
/////////////
------------------------------------------------------------------------------
#include <iostream.h>
void main()
{
int a=4;
cout <<"a vaut: "<< a <<endl;
/////////////
//Solution //
/////////////
----------------------------------------------------------------------------*/
//Ce programme écrit à l'écran: "a vaut: 4", retourne à la ligne et écrit:
//"Appuyer sur une touche pour quitter!".
/*------------------------------ EOF ---------------------------------------*/
/////////////
// Enoncé //
/////////////
------------------------------------------------------------------------------
////////////////
//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;
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 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 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 !
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.
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:
void main()
{
>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()
{
}
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.
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()
{
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!
>
-- x--; x=x-1;
-- y=x--; y=x; puis x=x-1;
-- y=--x; x=x-1; puis y=x;
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:
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()
{
cout<<entier<<endl<<caractere<<endl
entier2<<endl<<decimal<<endl;
}
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()
{
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()
{
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.
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;
}
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>
cout<<"VariableGlobale:
"<<variableGlobale<<endl; //appel
}
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!
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 :
//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)
Le bloc d'instructions : délimité entre accolades, tu peux y inclure tout type d'instructions.
C'est le cœur de ta fonction.
}
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.
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…
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.
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.
#include <iostream.h>
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
}
}
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!
Concepts avancés
#include <iostream.h>
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!
• 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>
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, int y)
{
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!
Bonus
Bon, ouf ! On s'en est sorti ! Il est temps maintenant de passer aux exercices:
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!