Docstoc

basics

Document Sample
basics Powered By Docstoc
					Cours d’informatique                                                                    O. Marguin — 2003/2004




                           C++ : LES BASES



                                        SOMMAIRE :



                              e
               Chapitre 1 : Pr´sentation du C++                 .   .   .   .   .   .   .   1
               1.1 Qu’est-ce qu’un programme ?  . . . .                     .   .   .   .   1
                                      e              e e
               1.2 Environnement de d´veloppement int´gr´                   .   .   .   .   2

                              e
               Chapitre 2 : El´ments du langage (1)                 .   .   .   .   .   .   3
               2.1   Variables     . . . . .            .   .   .   .   .   .   .   .   . 3
               2.2   Expressions . . . . .              .   .   .   .   .   .   .   .   . 4
               2.3   Instructions     . . . .           .   .   .   .   .   .   .   .   . 6
               2.4   Fonctions     . . . . .            .   .   .   .   .   .   .   .   . 6
               2.5   Exemple de programme .             .   .   .   .   .   .   .   .   . 8
               2.6   Instructions conditionnelles       .   .   .   .   .   .   .   .   . 9
               2.7   Boucles . . . . . .                .   .   .   .   .   .   .   .   . 11
               2.8          e
                     Compl´ments      . . . .           .   .   .   .   .   .   .   .   . 13


                              e
               Chapitre 3 : El´ments du langage (2)                 .   .   .   .   .   . 15
               3.1         e
                     Enum´rations . . . .               .   .   .   .   .   .   .   .   .   15
               3.2   Tableaux      . . . . .            .   .   .   .   .   .   .   .   .   15
               3.3   Chaˆ              e
                         ınes de caract`res     .       .   .   .   .   .   .   .   .   .   17
               3.4               ee
                     Pointeurs, r´f´rences . .          .   .   .   .   .   .   .   .   .   18
               3.5    e                  e
                     R´capitulatif des op´rateurs       .   .   .   .   .   .   .   .   .   21




                                                    i
ii
Chapitre 1



                           PRESENTATION DU C++


             e            e                                                            e
Apparu au d´but des ann´es 90, le langage C++ est actuellement l’un des plus utilis´s dans le monde,
                                                           e                                       e
aussi bien pour les applications scientifiques que pour le d´veloppement des logiciels. En tant qu’h´ritier
                                                e                                   e
du langage C, le C++ est d’une grande efficacit´. Mais il a en plus des fonctionnalit´s puissantes, comme
par exemple la notion de classe, qui permet d’appliquer les techniques de la programmation-objet.
                              e
Le but de ce cours est de pr´senter la syntaxe de base du langage C++. Certains traits propres au C,
                 e    e                  e                                              a                 e
dont l’usage s’av`re p´rilleux, sont pass´s sous silence. La programmation-objet, quant ` elle, sera abord´e
dans un autre cours.




1.1 Qu’est-ce qu’un programme ?


                                                           e                                 e
(1.1.1) Programmer un ordinateur, c’est lui fournir une s´rie d’instructions qu’il doit ex´cuter. Ces in-
                 e e         e                           e    e                e      e e
structions sont g´n´ralement ´crites dans un langage dit ´volu´, puis, avant d’ˆtre ex´cut´es, sont traduites
en langage machine (qui est le langage du microprocesseur). Cette traduction s’appelle compilation et
               e                                              e
elle est effectu´e automatiquement par un programme appel´ compilateur.
Pour le programmeur, cette traduction automatique implique certaines contraintes :
             e
   – il doit ´crire les instructions selon une syntaxe rigoureuse,
               e                e                                                              e
   – il doit d´clarer les donn´es et fonctions qu’il va utiliser (ainsi le compilateur pourra r´server aux
           e                  e            e                   e
      donn´es une zone ad´quate en m´moire et pourra v´rifier que les fonctions sont correctement
             e
      employ´es).


                        e                          e e
(1.1.2) Un programme ´crit en C++ se compose g´n´ralement de plusieurs fichiers-sources. Il y a deux
sortes de fichiers-sources :
                                                                          e
     – ceux qui contiennent effectivement des instructions ; leur nom poss`de l’extension .cpp,
                                        e                          e
     – ceux qui ne contiennent que des d´clarations ; leur nom poss`de l’extension .h (signifiant“header”
              e
       ou en-tˆte).


                           `                  e                             a
(1.1.3) Un fichier .h sert a regrouper des d´clarations qui sont communes ` plusieurs fichiers .cpp, et
                                                                                         e
permet une compilation correcte de ceux-ci. Pour ce faire, dans un fichier .cpp on pr´voit l’inclusion
                                            e           a
automatique des fichiers .h qui lui sont n´cessaires, grˆce aux directives de compilation #include. En
                        `                               e
supposant que le fichier a inclure s’appelle untel.h, on ´crira #include <untel.h> s’il s’agit d’un fichier
              e                                                                   e                e
de la biblioth`que standard du C++, ou #include "untel.h" s’il s’agit d’un fichier ´crit par nous-mˆmes.


(1.1.4) Le lecteur peut d`s ` pr´sent se reporter au § 2.5 (page 8) pour voir un exemple de programme
                         e a e
e
´crit en C++. Il convient de noter que :
    • contrairement au Pascal, le C++ fait la diff´rence entre lettres minuscules et majuscules : par
                                                  e
                                                 e                         e
      exemple, les mots toto et Toto peuvent repr´senter deux variables diff´rentes.
    • pour rendre un programme plus lisible, il est conseill´ d’y mettre des commentaires ; en C++, tout
                                                            e
                              a
      texte qui suit // jusqu’` la fin de la ligne est un commentaire,
    • tout programme comporte une fonction (et une seule) appel´e main() : c’est par elle que com-
                                                               e
                  e
      mencera l’ex´cution.

                                                     1
                      e               e e
1.2 Environnement de d´veloppement int´gr´

             e
(1.2.1) Le d´veloppement d’un programme passe par trois phases successives :
            e                                 e
        1) ´criture et enregistrement des diff´rents fichiers-source,
                         e e
        2) compilation s´par´e des fichiers .cpp, chacun d’eux donnant un fichier-objet portant le mˆme e
            nom, mais avec l’extension .obj,
                                          e                           e
        3) lien des fichiers-objets (assur´e par un programme appel´ linker) pour produire un unique
                     e                                                      e        e      e e
            fichier-ex´cutable, portant l’extension .exe ; ce dernier pourra ˆtre lanc´ et ex´cut´ directe-
                               e
            ment depuis le syst`me d’exploitation.

            e                                    e                                                 e
(1.2.2) Ce d´veloppement est grandement facilit´ lorsqu’on travaille dans un environnement de d´velop-
           e e          e e             e                             a     a
pement int´gr´ (en abr´g´ : EDI), qui g`re l’ensemble des fichiers et tˆches ` effectuer sous la forme d’un
                              e
projet. Ce qui suit est une br`ve description de l’EDI Visual C++ (version 6.0) de Microsoft.
          e         a              e
La premi`re chose ` faire est de cr´er un nouveau projet, qu’on nomme par exemple monproj. On pr´cisee
ensuite le type de projet. Pour l’instant nous nous contenterons de “Win 32 Console Application” (`      a
    e                 e          e                                                          e
l’ex´cution, les entr´es de donn´es se feront depuis le clavier et les affichages dans une fenˆtre-texte de
                                                            e
type DOS). Il faut savoir que Visual C++ permet de cr´er d’autres types de projets et propose tous
            e           a                     e                                                     e
les outils n´cessaires ` la construction de v´ritables applications Windows, avec gestion des fenˆtres,
                                            e                  e
menus, dialogues etc. (c’est un outil de d´veloppement extrˆmement efficace pour qui maˆ      ıtrise bien la
programmation-objet).
          e                                  e              e               e a
L’EDI cr´e automatiquement sur le disque un r´pertoire appel´ monproj destin´ ` regrouper tous les
fichiers relatifs au projet.
                                                          e                  a              e      e
L’espace de travail (Workspace) de Visual C++ est divis´ en trois zones : ` droite, la fenˆtre d’´dition
                                         `
permettant de taper les fichiers-source ; a gauche, la liste des fichiers-sources inclus dans le projet ; en
           e     u
bas, la fenˆtre o` s’affichent les messages du compilateur et du linker.
    e         ee
Apr`s avoir cr´´ les fichiers-source, on construit le projet (menu build, commande build monproj.exe),
        e e                      e              e
ce qui g´n`re un programme ex´cutable appel´ monproj.exe.
                           e
On peut alors demander l’ex´cution du programme (menu build, commande execute monproj.exe).

                                      e               ea
Remarque : l’espace de travail peut ˆtre sauvegard´ ` tout instant (dans un fichier dont l’extension est
                            e                                    e
.dsw), ce qui permet de le r´ouvrir plus tard, lors d’une autre s´ance de travail.




                                                    2
Chapitre 2



                     ELEMENTS DU LANGAGE (1)



2.1 Variables

(2.1.1) Terminologie
                       e e
Une variable est caract´ris´e par :
                              e                            c
   – son nom : mot compos´ de lettres ou chiffres, commen¸ant par une lettre (le caract`re  e    tient lieu
      de lettre),
                  e                                                       e
   – son type pr´cisant la nature de cette variable (nombre entier, caract`re, objet etc.),
                         e          e a
   – sa valeur qui peut ˆtre modifi´e ` tout instant.
           e                        `                         e
Durant l’ex´cution d’un programme, a toute variable est attach´e une adresse : nombre entier qui indique
 u                e       e
o` se trouve stock´e en m´moire la valeur de cette variable.

(2.1.2) Types de base
                                            e
   a) vide : void . Aucune variable ne peut ˆtre de ce type. On en verra l’usage au paragraphe (2.4.2).
                             e
   b) entiers, par taille-m´moire croissante :
          • char, stock´ sur un octet ; valeurs : de −27 ` 27 − 1 (−128 ` 127),
                         e                                a             a
          • short, stock´ sur 2 octets ; valeurs : de −215 ` 215 − 1 (−32768 ` 32767),
                           e                                a                a
          • long, stock´ sur 4 octets ; valeurs : de −231 ` 231 − 1,
                         e                                a
          • int, co¨ıncide avec short ou long, selon l’installation.
       e                 e
   c) r´els, par taille-m´moire croissante :
          • float, stock´ sur 4 octets ; pr´cision : environ 7 chiffres,
                          e                 e
          • double, stock´ sur 8 octets ; pr´cision : environ 15 chiffres,
                            e                 e
          • long double, stock´ sur 10 octets ; pr´cision : environ 18 chiffres.
                                 e                  e
                                     e e                                                             e
On trouve parfois le mot unsigned pr´c´dant le nom d’un type entier (on parle alors d’entier non sign´ ;
un tel entier est toujours positif).

                    e
(2.1.3) Valeurs litt´rales (ou explicites)
            e                                            `
   a) caract`res usuels entre apostrophes, correspondant a des entiers de type char. Par exemple : ’A’
      (= 65), ’a’ (= 97), ’0’ (= 48), ’ ’ (= 32). La correspondance caract`res usuels ↔ entiers de
                                                                               e
                          e
      type char est donn´e par la table des codes ASCII.
              ıtre            e    e
      A connaˆ les caract`res sp´ciaux suivants :
                            `
            ’\n’ : retour a la ligne,
            ’\t’ : tabulation.
         ınes de caract`res entre guillemets, pour les affichages.
   b) chaˆ             e
      Par exemple : "Au revoir!\n".
      On reviendra plus tard sur le type chaˆ de caract`res (cf § 3.3).
                                             ıne          e
                  e
   c) valeurs enti`res, par exemple : 123 , -25000 , 133000000 (ici respectivement de type char, short,
      long).
   d) valeurs r´elles, qui comportent une virgule, par exemple : 3.14, -1.0, 4.21E2 (signifiant 4,21 102 ).
               e




                                                    3
         e
(2.1.4) D´claration des variables

                                                     e     e    e          e          e
                         En C++, toute variable doit ˆtre d´clar´e avant d’ˆtre utilis´e.

Forme g´n´rale d’une d´claration : <type> <liste de variables>;
       e e            e
 u
o` :
   <type> est un nom de type ou de classe,
   <liste de variables> est un ou plusieurs noms de variables, s´par´s par des virgules.
                                                                e e
Exemples :
                 int i, j, k;         e
                                  // d´clare trois entiers i, j, k
                 float x, y;          e            e
                                  // d´clare deux r´els x, y



         e
(2.1.5) D´claration + initialisation
      e              e
En mˆme temps qu’on d´clare une variable, il est possible de lui attribuer une valeur initiale. On pourra
e
´crire par exemple :
                 int i, j = 0, k;
                 float x, y = 1.0;

                         e
En particulier, on peut d´clarer une constante en ajoutant const devant le nom du type, par exemple :
                 const double PI = 3.14159265358979323846;
                 const int MAX = 100;

                                          e         e
Les valeurs des constantes ne peuvent pas ˆtre modifi´es.




2.2 Expressions

         e
(2.2.1) D´finition
                                          e                    e
En combinant des noms de variables, des op´rateurs, des parenth`ses et des appels de fonctions (voir
(2.4)), on obtient des expressions.
     e           a
Une r`gle simple ` retenir :
                                En C++, on appelle expression tout ce qui a une valeur.

          e              e
(2.2.2) Op´rateurs arithm´tiques
      +   :   addition,
      -   :   soustraction,
      *   :   multiplication,
      /   :   division. Attention : entre deux entiers, donne le quotient entier,
      %   :   entre deux entiers, donne le reste modulo.
Exemples :
                 19.0 / 5.0 vaut 3.8,
                 19 / 5     vaut 3,
                 19 % 5     vaut 4.

                           e               e           e                      e
Dans les expressions, les r`gles de priorit´ sont les r`gles usuelles des math´maticiens. Par exemple,
                                                                                     e     a
l’expression 5 + 3 * 2 a pour valeur 11 et non 16. En cas de doute, il ne faut pas h´siter ` mettre des
        e
parenth`ses.
             e
    ++ : incr´mentation. Si i est de type entier, les expressions i++ et ++i ont toutes deux pour valeur
                                        e
         la valeur de i. Mais elles ont ´galement un effet de bord qui est :
                         e                       `                           e
         – pour la premi`re, d’ajouter ensuite 1 a la valeur de i (post-incr´mentation),
                                                 `                   e     e
         – pour la seconde, d’ajouter d’abord 1 a la valeur de i (pr´-incr´mentation).
          e e                                                                         a
    -- : d´cr´mentation. i-- et --i fonctionnent comme i++ et ++i, mais retranchent 1 ` la valeur de
         i au lieu d’ajouter 1.

                                                                4
          e
(2.2.3) Op´rateurs d’affectation
         e
      = (´gal)
         Forme g´n´rale de l’expression d’affectation :
                e e                                               <variable> = <expression>
         Fonctionnement :
                                               e     e
                1. l’<expression> est d’abord ´valu´e ; cette valeur donne la valeur de l’expression
                   d’affectation,
                2. effet de bord : la <variable> re¸oit ensuite cette valeur.
                                                  c
         Exemples :
                 i = 1
                                                `
                 i = j = k = 1 (vaut 1 et donne a i, j et k la valeur 1)

    +=, -=, *=, /=, %=
         Forme g´n´rale :
                e e             <variable> <op´rateur>= < expression>
                                              e
                          e           `
         L’expression est ´quivalente a :
                   <variable> = <variable> <op´rateur> <expression>
                                              e
                                          e        a
         Par exemple, l’expression i += 3 ´quivaut ` i = i + 3.

(2.2.4) Conversion de type

                                                                                         e    e
L’expression d’affectation peut provoquer une conversion de type. Par exemple, supposons d´clar´s :
             int i;
             float x;
Alors, si i vaut 3, l’expression x = i donne a x la valeur 3.0 (conversion entier → r´el). Inversement, si
                                             `                                        e
x vaut 4.21, l’expression i = x donne a i la valeur 4, partie enti`re de x (conversion r´el → entier).
                                       `                          e                     e
         e                                              a a       e
On peut ´galement provoquer une conversion de type grˆce ` l’op´rateur () (type casting). Avec x comme
                                                                              e
ci-dessus, l’expression (int)x est de type int et sa valeur est la partie enti`re de x.

          e              e
(2.2.5) Op´rateurs d’entr´es-sorties

              e                        e                                   e e                  e    e
Ce sont les op´rateurs << et >>, utilis´s en conjonction avec des objets pr´d´finis cout et cin d´clar´s
                                                                              e
dans <iostream.h> (ne pas oublier la directive #include <iostream.h> en d´but de fichier).
Formes :
     cout << <expression> : affichage ` l’´cran de la valeur de <expression>,
                                       a e
     cin >> <variable> : lecture au clavier de la valeur de <variable>

                                 e
(2.2.6) Formatage des sorties num´riques

                                          a
On peut modifier l’apparence des sorties grˆce aux expressions suivantes :
     endl                                     a
                        provoque un passage ` la ligne
     setfill(c)                      e
                        fixe le caract`re de remplissage (si ce n’est pas un blanc)
     setprecision(p) fixe le nombre de chiffres affich´s   e
     setw(n)            fixe la largeur de l’affichage
     setbase(b)                             e
                        fixe la base de num´ration
Les quatre manipulateurs ci-dessus, sauf setprecision(), n’agissent que sur la prochaine sortie. Pour
les utiliser, inclure la librairie <iomanip.h>.

Exemple :
      cout << setbase(16) << 256 << endl;                                                             `
                                                                              // affiche 100 et passe a la ligne
      cout << setprecision(5) << setfill(’*’) << setw(10) << 123.45678;       // affiche ****123.46




                                                           5
2.3 Instructions

(2.3.1) Instruction-expression
Forme :     <expression>;
Cette instruction n’est utile que si l’<expression> a un effet de bord.
Exemples :
              i++;
              5;                                     e e
                            // correct, mais sans int´r^t !
              ;             // instruction vide
              i += j = 3;                                 ` ´
                            // ce genre d’instruction est a eviter !



(2.3.2) Instruction-bloc
Forme :       {
                     <d´clarations et instructions>
                       e
              }

Exemple :     {
                     int i = 3, j;
                     double x = 2.2, y = 3.3;
                     y = 0.5 * (x + y);
                     int k = 1 - (j = i);
              }



                           o
(2.3.3) Structures de contrˆle

                                                   o     e                e              e
Ce sont des instructions qui permettent de contrˆler le d´roulement des op´rations effectu´es par le
programme : instructions if et switch (branchements conditionnels), instructions while, do et for
(boucles). Se reporter aux paragraphes (2.6) et (2.7).

                 e
(2.3.4) Visibilit´ d’une variable

                       e                         e          u                     e    e         e
Le domaine de visibilit´ d’une variable est limit´ au bloc o` cette variable est d´clar´e, et apr`s sa
 e
d´claration.
                                e    e                             a
On dit aussi que les variables d´clar´es dans un bloc sont locales ` ce bloc.
Si une variable est locale ` un bloc B, on ne peut y faire r´f´rence en dehors de ce bloc, mais on peut
                             a                                ee
l’utiliser a l’int´rieur de B et dans tout bloc inclus lui-mˆme dans B.
           `      e                                         e
          e                             e                                e
Dans un mˆme bloc, il est interdit de d´clarer deux variables avec le mˆme nom. Mais cela est possible
                            e
dans deux blocs distincts, mˆme si l’un des blocs est inclus dans l’autre.
                                              e     e                                a
Lorsque dans un fichier, une variable est d´clar´e en dehors de tout bloc (c’est-`-dire au niveau principal),
                                                                       a                      u           e    e
on dit qu’elle est globale ; elle est alors visible de tout le fichier, ` partir de l’endroit o` elle est d´clar´e.
       e                e                e
Cette r`gle de visibilit´ s’appliquera ´galement aux fonctions.




2.4 Fonctions

(2.4.1) Terminologie
                      e                               a
En C++, la partie ex´cutable d’un programme (c’est-`-dire celle qui comporte des instructions) n’est
       e                                                      e a                a      e
compos´e que de fonctions. Chacune de ces fonctions est destin´e ` effectuer une tˆche pr´cise et renvoie
 e e                      e
g´n´ralement une valeur, r´sultat d’un calcul.




                                                          6
                       e e
Une fonction est caract´ris´e par :
  1) son nom,
  2) le type de valeur qu’elle renvoie,
                              c                                 e
  3) l’information qu’elle re¸oit pour faire son travail (param`tres),
  4) l’instruction-bloc qui effectue le travail (corps de la fonction).
Les trois premiers ´l´ments sont d´crits dans la d´claration de la fonction. L’´l´ment n◦ 4 figure dans la
                   ee             e               e                            ee
 e
d´finition de la fonction.
                                                 e     e             e          e
                             Toute fonction doit ˆtre d´finie avant d’ˆtre utilis´e.

                                                                                    e
Dans un fichier-source untel.cpp, il est possible d’utiliser une fonction qui est d´finie dans un autre
fichier. Mais, pour que la compilation s’effectue sans encombre, il faut en principe que cette fonction soit
 e    e                                                                        `     e
d´clar´e dans untel.cpp (en usant au besoin de la directive #include) : voir a cet ´gard (2.5.2).
     e
La d´finition d’une fonction se fait toujours au niveau principal. On ne peut donc pas imbriquer les
fonctions les unes dans les autres, comme on le fait en Pascal.

         e
(2.4.2) D´claration d’une fonction
               a a
Elle se fait grˆce ` un prototype de la forme suivante :
                              <type> <nom>(<liste de param`tres formels>);
                                                          e

o` <type> est le type du r´sultat, <nom> est le nom de la fonction et <liste de param`tres formels> est
 u                        e                                                             e
       e    e                       e                         e e
compos´ de z´ro, une ou plusieurs d´clarations de variables, s´par´es par des virgules.
Exemples :
              double Moyenne(double x, double y);
              char LireCaractere();
              void AfficherValeurs(int nombre, double valeur);


                     e                              e a
Remarque : la derni`re fonction n’est pas destin´e ` renvoyer une valeur ; c’est pourquoi le type du
 e                                                     e      e
r´sultat est void (une telle fonction est parfois appel´e proc´dure).

         e
(2.4.3) D´finition d’une fonction
Elle est de la forme suivante :
              <type> <nom>(<liste de param`tres formels>)
                                          e
              <instruction-bloc>

                         e                              e    e
Donnons par exemple les d´finitions des trois fonctions d´clar´es ci-dessus :
              double Moyenne(double x, double y)
              {
                      return (x + y) / 2.0;
              }

              char LireCaractere()
              {
                      char c;
                      cin >> c;
                      return c;
              }

              void AfficherValeurs(int nombre, double valeur)
              {
                      cout << ’\t’ << nombre << ’\t’ << valeur << ’\n’;
              }

A retenir :
L’instruction return <expression>; interrompt l’ex´cution de la fonction. La valeur de l’<expression>
                                                  e
est la valeur que renvoie la fonction.

(2.4.4) Utilisation d’une fonction
Elle se fait grˆce ` l’appel de la fonction. Cet appel est une expression de la forme : <nom>(<liste
               a a
d’expressions>).

                                                           7
 e
M´canisme de l’appel :
   – chaque expression de la <liste d’expressions> est ´valu´e,
                                                        e     e
                                                                      e
   – les valeurs ainsi obtenues sont transmises dans l’ordre aux param`tres formels,
                                           e e
   – le corps de la fonction est ensuite ex´cut´,
                      e                           e
   – la valeur renvoy´e par la fonction donne le r´sultat de l’appel.
                                             e
Si la fonction ne renvoie pas de valeur, le r´sultat de l’appel est de type void.
                                                            e e
Voici un bout de programme avec appel des trois fonctions pr´c´dentes :
             double u, v;
             cout << "\nEntrez les valeurs de u et v :";
             cin >> u >> v;
             double m = Moyenne(u, v);
             cout << "\nVoulez-vous afficher la moyenne ?   ";
             char reponse = LireCaractere();
             if (reponse == ’o’)
                     AfficherValeurs(2, m);



                       e
(2.4.5) Arguments par d´faut
                     e                                                   e                     e
On peut, lors de la d´claration d’une fonction, choisir pour les param`tres des valeurs par d´faut (sous
          e                                   `                            e
forme de d´clarations-initialisations figurant a la fin de la liste des param`tres formels). Par exemple :
             void AfficherValeurs(int nombre, double valeur = 0.0);


Les deux appels suivants sont alors corrects :
             AfficherValeurs(n, x);
                                    ´        `
             AfficherValeurs(n); // equivaut a : AfficherValeurs(n, 0.0);




2.5 Exemple de programme

                                         e
(2.5.1) Voici un petit programme complet ´crit en C++ :

      // ------------------- fichier gazole.cpp ---------------------

      #include <iostream.h>                                 e
                                            // pour les entr´es-sorties

      const double prix du litre = 0.89;        e
                                            // d´claration du prix du litre de gazole (en euros) comme constante (hum!)
      int reserve = 10000;                      e                 e
                                            // d´claration de la r´serve de la pompe, en litres

      double prix(int nb)                       e                             e
                                            // d´finition d’une fonction appel´e "prix" :
                                            // cette fonction renvoie le prix de nb litres de gazole
      {
             return nb * prix du litre;
      }

      int delivre(int nb)                       e                             e
                                            // d´finition d’une fonction appel´e "delivre": cette fonction renvoie 0
                                                      e                                    e
                                            // si la r´serve est insuffisante, 1 sinon et d´livre alors nb litres
      {
             if (nb > reserve)              // instruction if :   voir paragraphe 2.6.1
                     return 0;
             reserve -= nb;
             return 1;
      }

      int main()                                 e
                                             // d´finition de la fonction principale
      {
              int possible;
              do                             // instruction do : voir paragraphe 2.7.2
              {
                      int quantite;
                      cout << "Bonjour. Combien voulez-vous de litres de gazole ? ";
                      cin >> quantite;
                      possible = delivre(quantite);
                      if (possible)
                              cout << "Cela fait " << prix(quantite) << " euros.\n";
              }


                                                            8
             while (possible);
             cout << "Plus assez de carburant.\n";
             return 0;                      // la fonction main renvoie traditionnellement un entier
      }



                                           e e               a                   e
(2.5.2) Comme le montre le programme pr´c´dent, il est tout-`-fait possible de n’´crire qu’un seul fichier-
                                     e
source .cpp contenant toutes les d´clarations et instructions. Cependant, pour un gros programme, il
                e e                                        e        e     e               e
est recommand´ d’´crire plusieurs fichiers-source, chacun ´tant sp´cialis´ dans une cat´gorie d’actions
  e
pr´cise. Cette technique sera d’ailleurs de rigueur quand nous ferons de la programmation-objet.
                             e                              e
A titre d’exemple, voici le mˆme programme, mais compos´ de trois fichiers-sources distincts. On remar-
                           e
quera que le fichier d’en-tˆte est inclus dans les deux autres fichiers (voir (1.1.3)) :

      // ------------------- fichier pompe.h ----------------------

      const double prix du litre = 0.89;          e
                                              // d´claration du prix du litre de gazole (en euros)

      double prix(int nb);                        e
                                              // d´claration de la fonction prix
      int delivre(int nb);                        e
                                              // d´claration de la fonction delivre


      // ------------------- fichier pompe.cpp --------------------

      #include "pompe.h"                                           e             e e
                                              // pour inclure les d´clarations pr´c´dentes

      int reserve = 10000;                        e                 e
                                              // d´claration de la r´serve de la pompe, en litres

      double prix(int nb)                         e
                                              // d´finition de la fonction prix
      {
              ....... // comme en (2.5.1)
      }

      int delivre(int nb)                         e
                                              // d´finition de la fonction delivre
      {
              ....... // comme en (2.5.1)
      }


      // ------------------- fichier clients.cpp ------------------

      #include <iostream.h>                                   e
                                              // pour les entr´es-sorties
      #include "pompe.h"                                   e
                                              // pour les d´clarations communes

      int main()                                  e
                                              // d´finition de la fonction principale
      {
              .......   // comme en (2.5.1)
      }




2.6 Instructions conditionnelles

(2.6.1) L’instruction if
Forme :                          e
             if (<expression enti`re>)
                  <instruction1>
             else
                  <instruction2>

 e                              e         e   e
M´canisme : l’<expression enti`re> est ´valu´e.
                                                       e
   – si sa valeur est = 0, l’<instruction1> est effectu´e,
                                                         e
   – si sa valeur est nulle, l’<instruction2> est effectu´e.
                                 e          a
En C++, il n’y a pas de type bool´en (c’est-`-dire logique). On retiendra que :

                     e              e     `              e e
Toute expression enti`re = 0 (resp. ´gale a 0) est consid´r´e comme vraie (resp. fausse).

Remarque 1.— La partie else <instruction2> est facultative.

                                                            9
Remarque 2.— <instruction1> et <instruction2> sont en g´n´ral des instructions-blocs pour permettre
                                                       e e
d’effectuer plusieurs actions.


          e            e
(2.6.2) Op´rateurs bool´ens
           ! : non,
          && : et,
          || : ou.
  e                               e                e
L’´valuation des expressions bool´ennes est une ´valuation courte. Par exemple, l’expression u && v
                   e            e    ea                        e    e
prend la valeur 0 d`s que u est ´valu´ ` 0, sans que v ne soit ´valu´.


          e
(2.6.3) Op´rateurs de comparaison
          ==   :   e
                   ´gal,
          !=   :       e
                   diff´rent,
           <   :                   e
                   strictement inf´rieur,
           >   :                    e
                   strictement sup´rieur,
          <=   :      e         e
                   inf´rieur ou ´gal,
          >=   :       e         e
                   sup´rieur ou ´gal.


(2.6.4) Exemple
         e
On veut d´finir une fonction calculant le maximum de trois entiers.
     e
Premi`re solution :
                   int Max(int x, int y, int z)   // calcule le maximum de trois entiers
                   {
                           if ((x <= z) && (y <= z))
                                   return z;
                           if ((x <= y) && (z <= y))
                                   return y;
                           return x;
                   }



     e
Deuxi`me solution, avec une fonction auxiliaire calculant le maximum de deux entiers :
                   int Max(int x, int y)         // calcule le maximum de deux entiers
                   {
                           if (x < y)
                                   return y;
                           return x;
                   }

                   int Max(int x, int y, int z)   // calcule le maximum de trois entiers
                   {
                           return Max(Max(x, y), z);
                   }


                                                                   e         e                   e
Comme on le voit sur cet exemple, deux fonctions peuvent avoir le mˆme nom, d`s lors qu’elles diff`rent
                                  e
par le nombre ou le type des param`tres.


(2.6.5) L’instruction switch
Cette instruction permet un branchement conditionnel multiple.
Forme :            switch (<expression>)
                   {
                        case <valeur1> :
                              <instructions>
                        case <valeur2> :
                              <instructions>
                          .
                          .
                          .
                          case <valeurn> :
                               <instructions>

                                                                10
                    default :
                         <instructions>
             }

  e                                   e     e                                        e  `
M´canisme : L’<expression> est ´valu´e. S’il y a un case avec une valeur ´gale a la valeur de
                     e                   e e a           e
l’<expression>, l’ex´cution est transf´r´e ` la premi`re instruction qui suit ce case ; si un tel case
                  e                 e e a          e
n’existe pas, l’ex´cution est transf´r´e ` la premi`re instruction qui suit default :.
Remarque 1.— La partie default : <instructions> est facultative.
                                          e e          e
Remarque 2.— L’instruction switch est en g´n´ral utilis´e en conjonction avec l’instruction break; qui
                    e
permet de sortir imm´diatement du switch.
Exemple :
             switch (note   / 2)                // on suppose note entier entre 0 et 20
             {
                     case10 :
                     case9 :
                     case8 :
                            mention   = "TB";
                            break;
                    case 7 :
                            mention   = "B";
                            break;
                    case 6 :
                            mention   = "AB";
                            break;
                    case 5 :
                            mention   = "P";
                            break;
                    default :
                            mention   = "AJOURNE";
             }




2.7 Boucles

(2.7.1) L’instruction while
Forme :                             e
             while (<expression enti`re>)
                  <instruction>

  e                           e                e    e                                 a
M´canisme : l’<expression enti`re> est d’abord ´valu´e. Tant qu’elle est vraie (c’est-`-dire = 0),
                          e
l’<instruction> est effectu´e.
   e
Sch´matiquement :


                                                                expression
                                                         faux
                                                                      vrai


                                                                instruction




                                  e
On remarque que le test est effectu´ avant la boucle.

(2.7.2) L’instruction do
Forme :      do
                  <instruction>
                                    e
             while (<expression enti`re>);

  e                                      e                       e        e    e
M´canisme : l’<instruction> est effectu´e, puis l’<expression enti`re> est ´valu´e. Tant qu’elle est vraie
       a                                      e
(c’est-`-dire = 0), l’<instruction> est effectu´e.

                                                                  11
   e
Sch´matiquement :

                                                       instruction




                                                       expression
                                                                     vrai
                                                       faux




                                  e    e
On remarque que le test est effectu´ apr`s la boucle.

(2.7.3) L’instruction for
Forme :      for (<expression1>; <expression2>; <expression3>)
                  <instruction>

    e            e          `
Le m´canisme est ´quivalent a :
      <expression1>;        // initialisation de la boucle
      while (<expression2>) // test de continuation de la boucle
      {
            <instruction>
            <expression3>; // ´valu´e ` la fin de chaque boucle
                               e    e a
      }
Remarque 1.— Une boucle infinie peut se programmer ainsi :
                    for (;;)
                         <instruction>
Remarque 2.— Dans une boucle, on peut utiliser les instructions :
                                      e                              a
       break; pour abandonner imm´diatement la boucle et passer ` la suite,
                                        e                         `
       continue; pour abandonner l’it´ration en cours et passer a la suivante,
                                                          e                   e
mais l’usage de ces deux instructions se fait souvent au d´triment de la clart´.

(2.7.4) Exemple
Ecrivons un bout de programme permettant d’entrer au clavier dix nombres entiers et qui affiche ensuite
                  e
la moyenne arithm´tique de ces dix nombres.
             int n, somme = 0;
             int i = 0;
                                                                         e
             cout << "Quand on le demande, tapez un entier suivi de <entr´e>\n";
             while (i < 10)         // boucle version while
             {
                                  e
                     cout << "Entr´e ? ";
                     cin >> n;
                     somme += n;
                     i++;
             }
             cout << "La moyenne est " << somme / 10.0;


             e
Ecrivons la mˆme boucle avec un do :
             do     // boucle version do
             {
                                 e
                    cout << "Entr´e ? ";
                    cin >> n;
                    somme += n;
                    i++;
             }
             while (i < 10);


Avec un for :
             for (i = 0; i < 10; i++)       // boucle version for
             {
                                  e
                     cout << "Entr´e ? ";
                     cin >> n;
                     somme += n;
             }


                                                              12
(2.7.5) Du bon choix d’une boucle
Voici quelques principes qui pourront nous guider dans le choix d’une boucle :
    – Si l’on sait combien de fois effectuer la boucle : utiliser for.
    – Sinon, utiliser while ou do :
                                u
            - s’il y a des cas o` l’on ne passe pas dans la boucle : utiliser while,
            - sinon, utiliser do.
Exemple : nous voulons d´finir une fonction calculant le pgcd de deux entiers > 0 en n’effectuant que des
                            e
                                                                                                   a
soustractions. Principe : soustraire le plus petit nombre du plus grand, et recommencer jusqu’` ce que
                          e
les deux nombres soient ´gaux ; on obtient alors le pgcd. Par exemple, partant de 15 et 24, on obtient :
(15, 24) → (15, 9) → (6, 9) → (6, 3) → (3, 3) et le pgcd est 3. Connaissant les nombres a et b de d´part,
                                                                                                      e
on ne peut pas savoir a priori combien d’it´rations seront n´cessaires. De plus si a = b, on a tout de suite
                                           e                 e
    e               e                                                    u
le r´sultat, sans op´ration. Nous choisirons donc une boucle while, d’o` :
             int Pgcd(int a, int b)          // calcule le pgcd de a et b entiers positifs
             {
                     while (a != b)
                             if (a > b)
                                     a -= b;
                             else
                                     b -= a;
                     return a;
             }




         e
2.8 Compl´ments

(2.8.1) Expression virgule
Forme :      <expression1> , <expression2>
Fonctionnement :
   • <expression1> est ´valu´e, sa valeur est oubli´e
                       e    e                      e
   • <expression2> est ensuite ´valu´e et donne sa valeur a l’expression virgule.
                               e    e                     `
Cette expression n’est int´ressante que si <expression1> a un effet de bord.
                          e

(2.8.2) Expression conditionnelle
Forme :      <expression0> ? <expression1> : <expression2>
Fonctionnement : <expression0> est d’abord ´valu´e.
                                              e     e
   • si elle est non nulle, <expression1> est ´valu´e et donne sa valeur a l’expression conditionnelle,
                                              e     e                     `
   • si elle est nulle, <expression2> est ´valu´e et donne sa valeur a l’expression conditionnelle.
                                          e    e                     `

Exemple :
             int Pgcd(int a, int b) // calcule le pgcd de deux entiers positifs
                                    // variante de (2.7.5) dans le style fonctionnel
             {
                     if (a == b) return a;
                     return a > b ? Pgcd(a - b, b) : Pgcd(b - a, a);
             }



(2.8.3) Fonctions utiles

                                                           e
Nous terminons en donnant quelques fonctions de la biblioth`que standard.
               e                        e   e
Fonctions math´matiques : elles sont d´clar´es dans math.h. Il y a notamment les fonctions suivantes,
         e                   e
de param`tre double et de r´sultat double :
                                      e        e                   e
    - floor (resp. ceil) : partie enti`re par d´faut (resp. par exc`s),
    - fabs : valeur absolue,
                        e
    - sqrt : racine carr´e,
    - pow : puissance (pow(x,y) renvoie xy ),

                                                          13
    - exp, log, log10,
                                                                            e
    - sin, cos, tan, asin, acos, atan, sinh, cosh, tanh : fonctions trigonom´triques.
          e
Nombres al´atoires : il faut inclure stdlib.h et time.h. Alors :
                       e e                    e              ee                         a a
   - on initialise le g´n´rateur de nombres al´atoires (de pr´f´rence une seule fois) grˆce ` l’instruction
     srand((unsigned) time(NULL));
                                                                     e
   - ensuite, chaque appel de la fonction rand() donne un entier al´atoire compris entre 0 et RAND MAX
                   e
     (constante d´finie dans stdlib.h).
               e                                                             e    e
Effacement de l’´cran : instruction system("cls"); (la fonction system() est d´clar´e dans stdlib.h).
   e                                                      e     e
Arrˆt du programme : l’instruction exit(1); provoque l’arrˆt imm´diat du programme (la fonction
            e    e
exit() est d´clar´e dans stdlib.h).




                                                    14
Chapitre 3



                       ELEMENTS DU LANGAGE (2)




        e
3.1 Enum´rations

(3.1.1) Les ´num´rations sont des listes de noms repr´sentant les valeurs enti`res successives 0, 1, 2, . . .
            e   e                                    e                        e
    e   e           e            e    e
Une ´num´ration se d´finit par un ´nonc´ de la forme :
             enum <nom> { <liste de noms> };
Exemples :
             enum Jour {dimanche, lundi, mardi, mercredi, jeudi, vendredi, samedi};
             enum Couleur {coeur, pique, carreau, trefle};
             enum Vache {blanchette, noiraude, gertrude};

           e    ee         a     e                             e
Le premier ´nonc´ ´quivaut ` la d´claration des constantes enti`res :
             const int dimanche = 0;
             const int lundi = 1;
             const int mardi = 2;
             etc . . .

            `                             e
et attribue a ces constantes un type appel´ Jour.

                               e   e              e
(3.1.2) On pourra utiliser les ´num´rations pour d´clarer des variables, comme par exemple :
             Jour fatal;
             Couleur c;
             Vache folle = gertrude;




3.2 Tableaux

                                           e                   e
(3.2.1) Un tableau est une collection indic´e de variables de mˆme type.
             e
Forme de la d´claration :
             <type> <nom> [<taille>];
o` : <type> est le type des ´l´ments du tableau,
 u                          ee
     <nom> est le nom du tableau,
     <taille> est une constante enti`re ´gale au nombre d’´l´ments du tableau.
                                    e e                   ee
Exemples :
             int fraction[2];              //   tableau de deux entiers
             char mot[10], s[256];         //                                              e
                                                tableaux de respectivement 10 et 256 caract`res
             double tab[3];                //                             e
                                                tableau de trois nombres r´els
             Vache troupeau[1000];         //   tableau de mille vaches



                                                    e                   ee
(3.2.2) Si t est un tableau et i une expression enti`re, on note t[i] l’´l´ment d’indice i du tableau. Les
´l´ments d’un tableau sont indic´s de 0 ` taille − 1.
ee                                e        a

                                                           15
                                  e     e              e                           e
Par exemple, le tableau fraction d´clar´ ci-dessus repr´sente deux variables enti`res qui sont frac-
tion[0] et fraction[1]. Ces variables se traitent comme des variables ordinaires ; on peut par exemple
e
´crire :
             fraction[0] = 1;
             fraction[1] = 2;   etc.

               ee                              e      e           c          e
Remarque.— Les ´l´ments d’un tableau sont stock´s en m´moire de fa¸on contigu¨, dans l’ordre des
indices.

                            e                    a                                         e
(3.2.3) Il est possible de d´clarer des tableaux ` deux indices (ou plus). Par exemple, en ´crivant :
             int M[2][3];
     e                            a
on d´clare un tableau d’entiers M ` deux indices, le premier indice variant entre 0 et 1, le second entre 0
                                                    a                             ee
et 2. On peut voir M comme une matrice d’entiers ` 2 lignes et 3 colonnes. Les ´l´ments de M se notent
M[i][j].

                                                                             e
(3.2.4) Comme pour les variables ordinaires (cf (2.1.5)), on peut faire des d´clarations-initialisations de
tableaux. En voici trois exemples :
             int T[3] = {5, 10, 15};
             char voyelle[6] = {’a’, ’e’, ’i’, ’o’, ’u’, ’y’};
             int M[2][3] = {{1, 2, 3}, {3, 4, 5}};    // ou : int M[2][3] = {1, 2, 3, 3, 4, 5};



         e
(3.2.5) D´claration typedef
                               `
Elle permet d’attribuer un nom a un type.
Forme g´n´rale :
       e e                  typedef <d´claration>
                                      e
o` <d´claration> est identique ` une d´claration de variable, dans laquelle le rˆle du nom de la variable
 u     e                       a       e                                        o
        e                                  e
est jou´ par le nom du type que l’on veut d´finir.
        e
C’est tr`s pratique pour nommer certains types de tableaux. Exemples :
             const int DIM = 3;
             typedef float Vecteur[DIM];         e                                           e
                                             // d´finit un type Vecteur (= tableau de trois r´els)
             typedef int Matrice[2][3];          e
                                             // d´finit un type Matrice
             typedef char Phrase[256];           e
                                             // d´finit un type Phrase

                e
Cela permet de d´clarer ensuite, par exemple :
             Vecteur U, V = {0.0, 0.0, 0.0}, W;
             Matrice M;         e          ´           `
                            // d´claration equivalente a celle de (3.2.3)
             Phrase s;



(3.2.6) Utilisation des tableaux
                        e
On retiendra les trois r`gles suivantes :
    • Les tableaux peuvent ˆtre pass´s en param`tres dans les fonctions,
                            e        e           e
    • les tableaux ne peuvent ˆtre renvoy´s (avec return) comme r´sultats de fonctions,
                               e          e                        e
    • l’affectation entre tableaux est interdite.

Exemple 1.— Instruction qui copie le vecteur U dans V :
             for (int i = 0; i < DIM; i++)
                     V[i] = U[i];


Exemple 2.— Fonction qui affiche un vecteur :
             void Affiche(Vecteur V)        // affiche les composantes du vecteur V
             {
                     for (int i = 0; i < DIM; i++)
                             cout << V[i] << " ";
             }


Exemple 3.— Fonction renvoyant un vecteur nul :

                                                           16
                                                           
             Vecteur Zero()
                                                           
                                                           
             {                                             
                                                           
                     Vecteur Z;
                                                           
                                                           
                     for (int i = 0; i < DIM; i++)              ILLEGAL !
                                                           
                                                           
                             Z[i] = 0.0;                   
                                                           
                     return Z;                             
                                                           
             }




       ınes de caract`res
3.3 Chaˆ             e

                       ı            e                                              e                   e
(3.3.1) En C++, une chaˆne de caract`res n’est rien d’autre qu’un tableau de caract`res, avec un caract`re
                                 ı
nul ’\0’ marquant la fin de la chaˆne.
             e
Exemples de d´clarations :
             char nom[20], prenom[20];                  e
                                            // 19 caract`res utiles
             char adresse[3][40];                                       e
                                            // trois lignes de 39 caract`res utiles
             char turlu[10] = {’t’, ’u’, ’t’, ’u’, ’\0’}; // ou : char turlu[10] = "tutu";



                    ee                                                   ıne        e         e
(3.3.2) Comme il a ´t´ dit en (2.1.3), les valeurs explicites de type chaˆ de caract`res sont ´crites avec
des guillemets. Par exemple :
             prenom = "Antoine";                    e         e
                                              // ill´gal d’apr`s (3.2.6)
             strcpy(prenom, "Antoine");       // correct : voir ci-dessous (3.3.3)

            e                                   e
On peut repr´senter le tableau prenom par le sch´ma suivant :


                                          ’A’ ’n’ ’t’ ’o’ ’i’ ’n’ ’e’ ’\0’
                                          0    1   2   3   4   5    6   7    19

                   e      e e                                         ıne.
Le nombre de caract`res pr´c´dant ’\0’ s’appelle la longueur de la chaˆ
Les chaˆ              e           e                              e a e           a
        ınes de caract`re peuvent ˆtre saisies au clavier et affich´es ` l’´cran grˆce aux objets habituels
cin et cout.

                        e                                                                           ınes
(3.3.3) Dans la biblioth`que standard du C++, il y a de nombreuses fonctions utilitaires sur les chaˆ
         e
de caract`res. Parmi elles :
                                                               ıne
      strlen(s) (dans string.h) : donne la longueur de la chaˆ s
                                                              ıne
      strcpy(dest, source) (dans string.h) : recopie la chaˆ source dans dest
      strcmp(s1,s2) (dans string.h) : compare les chaˆ  ınes s1 et s2 :
           renvoie une valeur < 0, nulle ou > 0 selon que s1 est inf´rieure, ´gale ou sup´rieure a s2
                                                                      e       e            e        `
                               e
           pour l’ordre alphab´tique.
      gets(s) (dans stdio.h) :
                      ıne          e      e                                      `
           lit une chaˆ de caract`res tap´e au clavier, jusqu’au premier retour a la ligne (inclus) ; les
                  e                e             ıne                  `                            e
           caract`res lus sont rang´s dans la chaˆ s, sauf le retour a la ligne qui y est remplac´ par
           ’\0’.

                           ınes de caract`res
(3.3.4) Utilisation des chaˆ             e
Nous en donnerons deux exemples.
                                                                        a
Exemple 1.— Fonction qui indique si une phrase est un palindrome (c’est-`-dire qu’on peut la lire aussi
     `              a
bien a l’endroit qu’` l’envers) :
             int Palindrome(Phrase s)       // teste si s est un palindrome
             {
                     int i = 0, j = strlen(s) - 1;
                     while (s[i] == s[j] && i < j)
                             i++, j--;
                     return i >= j;
             }


                                                               17
                              `                 ıne                 ıne
Exemple 2.— Instructions qui, a partir d’une chaˆ s, fabrique la chaˆ t obtenue en renversant s :
             for (int i = 0, j = strlen(s) - 1; i < strlen(s); i++, j--)
                     t[i] = s[j];
             t[strlen(s)] = ’\0’;



                                                                              e
Remarque.— Il y a dans ctype.h quelques fonctions utiles concernant les caract`res, entre autres :
      tolower()             convertit une lettre majuscule en minuscule
      toupper()             convertit une lettre minuscule en majuscule




                ee
3.4 Pointeurs, r´f´rences

(3.4.1) Adresses
       e                           e          e e                               e
La m´moire d’un ordinateur peut ˆtre consid´r´e comme un empilement de cases-m´moire. Chaque case-
   e             e e               e                                e e
m´moire est rep´r´e par un num´ro qu’on appelle son adresse (en g´n´ral un entier long). Si ma var
                                                     u       e
est une variable d’un type quelconque, l’adresse o` est stock´e la valeur de ma var s’obtient grˆce `
                                                                                                a a
     e
l’op´rateur d’adresse & : cette adresse se note &ma var :
                                                    memoire       adresses
                                                                  0
                                                                  1
                                                                  2



                                           ma_var     12          66844 (= &ma_var)




(3.4.2) Pointeurs
Un pointeur est une variable qui contient l’adresse d’une autre variable.
    e
La d´claration d’un pointeur est de la forme suivante :
             <type> *<nom>;
Par exemple :
             int *p;
                                                                 e
La variable p est alors un pointeur sur un int ; la variable enti`re dont p contient l’adresse est dite
     e                          e
point´e par p et se note *p. Sch´matiquement :

                                                     p     36758       18424




                                                    *p        0        36758




                  e
Une variable point´e s’utilise comme un variable ordinaire. Exemple :
             int *p, *q, n;
             n = -16;
             *p = 101;
             *q = n + *p;            `
                            // donne a *q la valeur 85



                                   ea
(3.4.3) Un pointeur est toujours li´ ` un type (sur lequel il pointe). Exemple :
             int *ip;
             double *dp;
             dp = ip;             e                                 e
                            // ill´gal car ip et dp ne sont pas de m^me type
             *dp = *ip;     // correct (conversion implicite de type)



                                                              18
                                                         e     `
Remarque.— Il y a dans stdlib.h la valeur pointeur NULL (´gale a 0) qui est compatible avec tout type
de pointeur. Ainsi :
              dp = NULL;           e
                               // l´gal
              ip = NULL;           e
                               // l´gal



         ee
(3.4.4) R´f´rences
     ee                              ı
Une r´f´rence est une variable qui co¨ncide avec une autre variable.
    e                 ee
La d´claration d’une r´f´rence est de la forme suivante :
              <type> &<nom> = <nom var>;
Par exemple :
              int n = 10;
              int &r = n;                    e e
                               // r est une r´f´rence sur n

                              e           e                                          e
Cela signifie que r et n repr´sentent la mˆme variable (en particulier, elles ont la mˆme adresse). Si on
e                                    e
´crit par la suite : r = 20, n prend ´galement la valeur 20.
Attention :
              double   somme, moyenne;
              double   &total = somme;        // correct :                   e e
                                                              total est une r´f´rence sur somme
              double   &valeur;                     e
                                              // ill´gal :                    `              e e
                                                              pas de variable a laquelle se r´f´rer
              double   &total = moyenne;            e
                                              // ill´gal :                  e           e e
                                                              on ne peut red´finir une r´f´rence



                         e
(3.4.5) Passage des param`tres dans une fonction
                             e                                       e
Supposons que nous voulions d´finir une fonction echange permettant d’´changer les valeurs de deux
              e
variables enti`res.
• Premi`re version, na¨ :
       e              ıve
              void echange(int a, int b)                     e
                                             // version erron´e
              {
                      int aux;                                                     e
                                             // variable auxiliaire servant pour l’´change
                      aux = a; a = b; b = aux;
              }

                                      u
Ici l’expression echange(x, y) (o` x et y sont de type int) n’a aucun effet sur x et y. En effet, comme
     ee                                                                                   e
il a ´t´ dit en (2.4.4), lors de l’appel de la fonction, les valeurs de x et y sont recopi´es dans les variables
locales a et b (on parle de passage par valeur) et ce sont les valeurs de ces variables a et b qui sont
e       e
´chang´es.
• Deuxi`me version, avec des r´f´rences :
       e                      ee
              void echange(int &a, int &b)   // version correcte, style C++
              {
                      int aux;
                      aux = a; a = b; b = aux;
              }

                                            e                    e
Cette fois, l’expression echange(x, y) r´alise correctement l’´change des valeurs de x et y, car les vari-
ables a et b co¨                                                             ee
                ıncident avec les variables x et y (on parle de passage par r´f´rence).
• Troisi`me version moins pratique, avec des pointeurs :
        e
              void echange(int *a, int *b)   // version correcte, style C
              {
                      int aux;
                      aux = *a; *a = *b; *b = aux;
              }

      e                                            e                             a             a
Pour ´changer les valeurs de x et y, il faut alors ´crire echange(&x, &y), c’est-`-dire passer ` la fonction
les adresses de x et y (on parle de passage par adresse).


(3.4.6) Pointeurs et tableaux
      e         e
Consid´rons la d´claration suivante :
              int T[5];        // T est un tableau de 5 entiers


                                                              19
          e e                                                                     ee
T est en r´alit´ un pointeur constant sur un int et contient l’adresse du premier ´l´ment du tableau.
                                                 e
Donc T et &T[0] sont synonymes. On a le droit d’´crire par exemple :
             int *p = T;
             p[2];          // = T[2]

A noter :
             int U[5];
             U = T;               e
                            // ill´gal :              ^          e
                                            U ne peut etre modifi´ (pointeur constant) :   voir (3.2.6)


                     e                                            e
(3.4.7) Comme cons´quence de (3.4.6), on voit que, comme param`tres de fonctions, les tableaux passent
par adresse. Donc :
                                                         u
     - il n’y a pas de recopie du contenu du tableau (d’o` gain de temps),
     - la fonction peut modifier le contenu du tableau.
                 e
Par exemple, en d´finissant :
             void annule(int V[])                    e
                                     // pour un param`tre tableau : inutile d’indiquer la taille
             {
                     for (int i = 0; i < 5; i++)
                             V[i] = 0;
             }

               a e                                    e
on peut mettre ` z´ro un tableau de cinq entiers T en ´crivant annule(T).

                   ınes de caract`res
(3.4.8) Cas des chaˆ             e
        ıne        e                         e   e
Une chaˆ de caract`res est habituellement d´clar´e :
                                  e
    - soit comme tableau de caract`res, comme en (3.3) ; exemple : char nom[10];
                                        e
    - soit comme pointeur sur un caract`re ; exemple : char *nom;
             e    e                     e                               e    e                      e
Avec la premi`re d´claration, l’espace-m´moire est automatiquement r´serv´ pour recevoir 10 caract`res.
             e                                 e    e                          e                e
Avec la deuxi`me, aucun espace n’est a priori r´serv´ : il faudra faire cette r´servation nous-mˆme (voir
paragraphe suivant).
                           e    e                                e         e               e
D’autre part, avec la deuxi`me d´claration, le pointeur nom peut ˆtre modifi´. Avec la premi`re, il ne le
peut pas.
                               e         e                                          e
A titre d’exemple, voici deux d´finitions ´quivalentes de la fonction strcpy mentionn´e au paragraphe
                                         ıne           e                        ıne
(3.3.3). Cette fonction recopie une chaˆ de caract`res source dans une chaˆ dest (attention :
                                                                   ıne
l’expression dest = source recopierait le pointeur mais pas la chaˆ !) :
             char *strcpy(char *dest, char *source)                // copie source dans dest
             {
                     for (int i = 0; source[i] != ’\0’; i++)
                             dest[i] = source[i];
                     dest[i] = source[i];           // copie le terminateur ’\0’
                     return dest;
             }
             char *strcpy(char *dest, char *source)                // copie source dans dest
             {
                     char *temp = dest;
                     while (*source)
                             *dest++ = *source++;
                     *dest = *source;               // copie le terminateur ’\0’
                     return temp;
             }


                       e
(3.4.9) Gestion de la m´moire — variables dynamiques
              e    e
a) Supposons d´clar´ :
             int *p;        // p :     pointeur sur int

                                               e                 e       e         a
Pour l’instant, p ne pointe sur rien. Il faut r´server l’espace-m´moire n´cessaire ` un int par l’instruction :
             p = new int;   // new :      e                     e
                                        op´rateur d’allocation m´moire

                               e                                                 e
Cette fois, p contient une v´ritable adresse (ou NULL s’il n’y a plus assez de m´moire). On peut alors
                          e
utiliser la variable point´e par p (qu’on nomme variable dynamique par opposition aux variables ordinaires
       e
qualifi´es de statiques). Par exemple :
             *p = 12;       // ou tout autre traitement...


                                                           20
                                                        e              e
Lorsqu’on n’a plus besoin de la variable *p, il faut lib´rer l’espace-m´moire qu’elle occupe par l’instruc-
tion :
              delete p;      // delete :     e           e             e
                                           op´rateur de d´sallocation m´moire

                     e          e            a
L’expression *p est d`s lors ill´gale, jusqu’` une prochaine allocation par : p = new int;
                                           e    e
b) (cas d’un tableau dynamique) Supposons d´clar´ :
              int *T;

L’allocation-m´moire n´cessaire pour recevoir n entiers s’´crira :
              e       e                                   e
              T = new int [n];      // T est maintenant un tableau de n entiers

          e e                 e                                    e
Ici, l’int´rˆt est que n peut ˆtre n’importe quelle expression enti`re, et pas seulement une constante comme
            e                                                                                  e    e e
dans la d´claration d’un tableau statique (voir (3.2.1)). La taille du tableau peut donc ˆtre d´cid´e au
                   e
moment de l’ex´cution, en fonction des besoins.
                           e                    e           e         e
En fin de traitement, la lib´ration de l’espace-m´moire occup´ par T s’´crit :
              delete [] T;              e             e
                                    // d´sallocation m´moire d’un tableau dynamique

A retenir :
  a                                                          e                                    e
Grˆce aux pointeurs, on peut manipuler des structures de donn´es dynamiques dont la taille n’est d´ter-
   e                       e
min´e qu’au moment de l’ex´cution.

              e                            e
c) L’espace-m´moire (nombre d’octets) occup´ par une valeur de type un type est donn´ par l’op´rateur
                                                                                    e         e
            e
sizeof : on ´crira sizeof un type ou encore sizeof une expr, o` une expr est une expression de type
                                                                u
un type.




     e                  e
3.5 R´capitulatif des op´rateurs

                       e                                e                         e e
Voici un tableau des op´rateurs du langage C++, class´s par niveaux de priorit´ d´croissante. Pour un
 e             e                            `                     `                                       e
mˆme niveau, l’´valuation se fait de gauche a droite ou de droite a gauche selon le sens de l’associativit´.
                  e
Certains de ces op´rateurs concerneront la programmation-objet.

                 e
          Priorit´                               e
                                               Op´rateurs                             Associativit´e
             1     () (appel de fonction) [] -> :: .                                          a
                                                                                      gauche ` droite
             2     ! ~(n´gation bit ` bit) + - ++ -- & * (op´rateurs unaires)
                           e           a                        e                            `
                                                                                      droite a gauche
                   sizeof new delete () (conversion de type)
             3     .* ->*                                                                     a
                                                                                      gauche ` droite
             4     * (op´rateur binaire) / %
                        e                                                                     a
                                                                                      gauche ` droite
             5     + - (op´rateurs binaires)
                               e                                                              a
                                                                                      gauche ` droite
             6     << >> (d´calages de bits ou entr´es/sorties)
                                  e                e                                          a
                                                                                      gauche ` droite
             7     < <= > >=                                                                  a
                                                                                      gauche ` droite
             8     == !=                                                                      a
                                                                                      gauche ` droite
             9     & (“et” bit ` bit)
                                a                                                             a
                                                                                      gauche ` droite
            10     ^ (“ou” exclusif bit a bit)
                                         `                                                    a
                                                                                      gauche ` droite
            11     | (“ou” bit a bit)
                                 `                                                            a
                                                                                      gauche ` droite
            12     &&                                                                         a
                                                                                      gauche ` droite
            13     ||                                                                         a
                                                                                      gauche ` droite
            14     ?:                                                                        `
                                                                                      droite a gauche
            15     = *= /= %= += -= &= ^= |= <<= >>=                                         `
                                                                                      droite a gauche
            16     ,                                                                          a
                                                                                      gauche ` droite


                                                           21

				
DOCUMENT INFO
Tags:
Stats:
views:1
posted:3/11/2013
language:
pages:23