You are on page 1of 115

Formation C / C++

Gilles Maire
Gilles@gillesmaire.com

Prsentation de la formation

Prsentation des langages C et C++


Environnement de dveloppement
Rappel du langage C
Le langage C++

2
Prsentation du langage C

C est un langage de bas niveau dans la mesure o il n'est


pas trs diffrent des instructions gnres par un macro
assembleur. En d'autres termes lorsqu'il est sorti en
1972, les personnes qui programmaient en assembleur
l'on trs vite adopt et il est toujours couramment utilis
Ses inventeurs furent Dennis Ritchie ( 12 oct 2011) et
Ken Thompson et il vit le jour en mme temps que Unix
dans les laboratoires de Bell.
+ : ouverts, standardis, thoriquement portable, simple
- : pas objet, pas de gestion des exceptions, piges de
portabilit, gestion mmoire primitive et source de bug ou
de faille scurit.
3

Prsentation du langage C++

Langage des annes 1980 toujours issu des laboratoires


de Bell invent par Bjarne Stroustrup qui a ajout la notion
de classes au C ce qui en fait un langage objet. Il a t
normalis le 14 novembre 1997.
Un programme crit en C peut tre compil en C++,
l'inverse n'est pas vrai car le C++ offre plus de
fonctionnalits.
Il est prsent sur toutes les architectures.
- : on perd la proximit avec le macro assembleur des
annes 1970, la portabilit n'est toujours que thorique
+ : on gagne en clart, le langage est trs moderne
4
volution du C et du C++

Compilation des programmes

Fichier Makefile : organise la compilation des sources

Fichiers.h des Programme h Utilitaire.h


librairies externes

Programme C utilitaire.c

make => gcc binutils etc ..

Librairie Glibc
et autres Programme

6
Fabrication d'un programme

Un programme C ou C++ est crit en langage humain


On l'dite en format ASCII dans un diteur de texte qui
sont plus adapts que Word ou Open Office
On peut galement l'diter dans un diteur de haut niveau
qui lance de faon transparente la compilation, l'excution
et le dbogage (c'est dire l'aide la rsolution de
problmes)
Mais on peut aussi lancer la main la compilation dans
une console.

Environnements de dveloppement

Il existe beaucoup d'environnements de dveloppement,


ceux des socit Borland, Microsoft, le produit Eclipse
d'Oracle, QtCreator de Nokia. On trouve beaucoup de
produits Open Source qui tournent sur MacOSX Windows
et Unix ainsi que sur le compilateur open source GCC
Nous allons utiliser l'un d'entre eux Code::blocks.
Avant d'apprendre C ou C++ nous allons apprendre
utiliser Code::blocks dans les axes suivants :
diteur de code ;
lancement de la compilation ;
lancement du programme.
8
Installation de Code::Block

Allez sur le site http://www.codeblocks.org/


Dans la partie Download/Binaries on charge
codeblocks-10.05mingw-setup.exe
Codeblock est livr avec
l'environnement lui mme
un compilateur C et un compilateur C++ qui sont
ncessaires pour compiler les programmes C et C++

Cration d'un nouveau projet

10
Ouvrir un projet C

11

Le premier programme

On crit le programme
On
compile !

12
On lance le programme Le programme s'excute
Introduction : Langage C ANSI

Plate-formes
Environnement de dveloppement
Formats de prsentation des informations
Types et oprateurs ANSI
Entres/Sorties standards
Instructions et branchements conditionnels

13

Langage C : plate-forme

Le langage C est trs portable et on le trouve sur tous les


systmes d'exploitation Windows, Linux, Unix, MacOSX
On le trouve partout o l'on trouve un microprocesseur en
effet il reste une abstraction peu lev par rapport un
Macro Assembleur
avec un peu d'habitude, un programmeur assembleur qui
passe en C peut reconnatre les squences d'instruction
gnr par le C
Il est trs rapide et ne manipule pas de notion d'objet
comme son cousin le C++
Il est trs utilis ds que les temps de rponse demands
sont le plus rduit possible
14
Langage C - Prsentation

Le C permet la programmation structure. Il possde un


environnement constitu de nombreuses librairies de
fonctions permettant d'effectuer des oprations de haut
niveau.
Dans ce cours, nous tudierons un C standard c'est--dire
portable et donc utilisable sur n'importe quel systme.
A quoi ressemble un programme C ?
#include <stdio.h>
void main() {
printf("\nExemple de programme c\n");
}

15

Langage C : caractres autoriss

Lettres majuscules
Lettres minuscules sans accent
Chiffres
Caractres de soulignement _
Caractre d'espace, de tabulation, de retour arrire, de
nouvelle ligne, de saut de page
Caractres spciaux et de ponctuation :, ! |; / :
\ ? ~ ' + " # ( % ) &[ ^ ] * {
- } = < > qui ont tous une signification
particulire

16
Langage C : fonction main

C'est une fonction comme toute autre, elle a donc la mme


structure :
void main() {
dclarations ;
instruction ;
}
Le mot void indique que la fonction ne retourne pas de
valeur mais elle peut retourner un code d'excution.
Nous verrons ultrieurement les passages de paramtres
la fonction main.

17

Exercice 1

reprendre le thme du premier exemple, c'est dire crire


un programme qui affiche une chane de caractres
l'cran
Le compiler et l'excuter.

18
Langage C : bloc et instructions

Blocs d'un programme


Un bloc est une suite d'instructions lmentaires dlimites par des accolades. Un programme C peut
contenir un nombre quelconque de blocs. Ces blocs peuvent tre inclus les uns dans les autres. Un
bloc peut contenir des dclarations et des dfinitions.
On peut dfinir un bloc tout moment pour y dclarer des variables qui auront une dure de vie limite
au bloc

Instructions
Une instruction lmentaire est une expression termine par un point virgule (seules les instructions du
prprocesseur C ne devront pas tre suivies d'un point virgule).

Dans le programme gnr par code::blocks on ne trouve qu'un seul bloc qui contient une seule
instruction. Cette instruction appele "printf" est une fonction spcifique du C . Elle permet
d'afficher des donnes.

La phrase "\nExemple de programme c" place entre parenthses sert de paramtre la fonction
printf. Le fait de donner le nom d'une fonction dans une instruction active cette fonction : on appelle
la fonction.

La fonction excute sa mission, puis le programme continue l'instruction suivante. Dans notre
exemple, le programme se termine car il n'y a pas d'autres instructions.

La fonction printf est une fonction prdfinie fournie avec le compilateur. Son code se trouve dans
un fichier spcial appel bibliothque.
19

Les commentaires

Le C donne la possibilit de placer des explications dans


le texte d'un programme. Cela se fait au moyen de
commentaires.
Un commentaire est une suite de caractres placs entre
les dlimiteurs : /* et */
Exemple :
/* ce programme affiche du texte l'cran */
Dans certains cas on trouve des commentaires sous la
forme /** */ qui sont toujours des commentaires mais qui
sont lus par des programmes de documentation pour faire
la documentation de programmation - voir Doxygen
20
Types de donnes lmentaires

Type char
Le type char est utilis pour reprsenter un caractre, plus
prcisment la valeur entire d'un lment de l'ensemble
des caractres reprsentables. Ce nombre entier est le code
ASCII (American Standard for Information Interchange ) du
caractre . Un caractre unique occupe un octet. A est le
caractre 65, a est 97.
Type int entier standard.
Le type int a une taille de reprsentation qui dpend du
systme sur lequel on travaille. Par exemple, sur pc un
lment de type int est stock sur 2 octets alors que sur la
machine Alpha ou sur Vax, il occupe 4 octets.

22

Types de donnes lmentaires suite

Type short entier court.


Le type short permet de stocker des donnes sur 2 octets. Il
permet donc de coder les nombres signs entre -32768 et 32767.
Type long entier long.
Le type long permet de stocker des donnes sur 4 octets. Il
permet donc de coder les nombres signs entre -2.147.843.648
2.147.843.647 .
La clause signed/unsigned
Si on ajoute le prfixe unsigned la dfinition d'un type de
variable entire, le bit de poids fort ne sert plus au signe mais
augmente la porte d'une unit ( ex : unsigned short : 0 ->
65532)

23
Les rels

Type float
Un nombre du type float est habituellement rang en
mmoire sous la forme suivante : mantisse sur 23 bits,
exposant sur 8 bits et signe sur 1 bit .3,4 * 10-38 3,4 * 10 38
Type double
Le type double est stock sur 8 octets. Il est cod comme le
type float, ceci prs que sa mantisse est sur 52 bits et son
exposant sur 11 bits. 1,7*10-308 3,4 * 10 308
long double
mantisse de 64 bits et un exposant de 15 bits 3,4 * 10 -4932
3,4 * 10 4932

24

Constantes

Entire 12 , -3 ,06 (octal) 0xFF (hexadcimal), 12L (type long)


Rel : 2.897,15.1E-2, .0089e2,-4005 E3
Caractres : 'a', 'Z', '\''
\n : nouvelle ligne \t : tabulation \b : retour arrire
\r retour chariot \f saut de page \a signal sonore
\" :quillemet
\\ : \
\ddd code ASCII en notation dcimale
\xddd code ASCII en hexadcimal
Chanes de caractres : "\nCeci est une chaine "
25
Exercice 2

Reprenez l'exercice prcdent sur plusieurs lignes et


ajouter des tabulations dans votre chane de caractres
ainsi qu'un caractre bip.

26

Variables

Type varnom1,varnom2, ;
Une variable est un donne qui peut avoir plusieurs valeurs
int x=3 ; veut dire que x prend la valeur 3
x=x+1 ; veut dire que x prend comme nouvelle valeur, sa valeur
incrment d'une unit
Exemple :
int i,j ;
int u=3 ;
char c='\n' ;
Attention ne pas utiliser les mots rservs : auto double int struct break
else long switch case enum register typedef char extern return union
const float short unsigned continue for signed void default goto sizeof
volatile do if static while
27
Porte et initialisation des variables

La variable n'est connue que dans le bloc o elle est dclare


(c'est dire entre les accolades)
les variables globales sont dclares en dehors du bloc main
On initialise une variable par une constante, une variable dj
initialise, le retour d'une fonction
int i=1 ;
int j=i ;
int k=carre(i) ;
Syntaxe composite :
int i=j=k=1 ; est quivalent
int k=1 ; int j=k ; int i=j ;
28

Sorties formates

Format signifie que l'on peut contrler la forme et le format des


donnes affiches.
La fonction printf permet ainsi d'afficher du texte (chane de caractres)
ou bien des valeurs numriques ou bien les deux.
printf ("chane de contrle ",[argument 1, argument 2, ]);
Ce qui est plac entre crochets est optionnel. La chane de contrle
indique sous quelle forme doit s'effectuer l'affichage. Elle peut contenir
des spcifications de format aussi bien que des caractres usuels.
Les spcifications de format contrlent le formatage et l'affichage des
arguments dont le nombre est variable(il doit y avoir autant de
spcifications de format que darguments afficher).
On ajoutera la directive #include <stdio.h> dans le fichier pour permettre
l'utilisation de la commande printf

29
Formatage numrique

printf("\n la somme de %d et de %d est : %d",a,b,c); => affichage


dcimal
%u pour les unsigned
%o : affichage en octal
%x %X: affichage en hexadcimal
printf("\nvaleur dcimale : %d \nvaleur en octal : %o \nvaleur en
hexadcimal : %x ou %X",a,a,a,a);
Sur des caractres on affiche ainsi les code ASCII
%f : affichage rel 6 chiffres aprs la virgule
%e : affichage exponentiel
On peut ajouter l, u ou L pour modifier la porte %Lf
30

Formatage entier avec largeur

en plaant un nombre entre le % et le type on formate la


largeur de sortie en ajoutant des blancs
printf(" %f\n%4f\n%16f\n\n ",3.141593,3.141593) ;
3.141593
3.14159
3.141593
Si on ajoute un 0 devant ce nombre le remplissage ne se
fera plus avec des blancs mais des zros
printf ("%04",5) => 0005
si on ajoute un point devant le type on force le nombre de
dcimales printf("%5.3f\n",3,1415)=>3,141
31
Formatage caractres

Formatage caractre :
printf("%c", a) ;
Formatage chanes de caractres
prinf ("%s",chaine) ;

32

Exercice 3

crire un programme qui affiche votre nom, votre prnom


et votre date de naissance en donnant les jours mois et
annes sous forme entiers formats. En deuxime ligne
vous afficherez les informations concernant votre voisin.

33
Exercice 4

crire un programme qui comprend une dclaration et


initialisation de deux variables i et, les afficher , puis un
bloc supplmentaire avec de nouveau la dclaration,
initialisation de la variable i, afficher i et j.
L'afficher nouveau i aprs le fermeture du bloc.
Que se passe-t-il ?

34

Entre formate

Syntaxe : scanf("chane de format ",[argument1,...]);


scanf manipule les mmes types d'arguments, par contre les
arguments pour tre modifis doivent comporter le caractre & (nous
verrons pourquoi plus loin)
scanf("%d",&x) permet d'affecter x une valeur entire lue sur l'entre
standard
On peut avoir plusieurs arguments :
scanf("%d:%d:%d",&h,&m,&s);
les types de formatage sont les mmes que ceux vus prcdemment
on doit galement utiliser #include <stdio.h>
la fonction sscanf permet de faire des conversions de chanes chane

35
Entres Sorties non formates

char c ;
c = getchar() ; /* lecture sur l'entre standard qui est le
clavier par dfaut */

putchar('a') : affiche a
putchar(12) affiche 12
Ncessite #include <stdio.h>

36

Exercice 5

Afficher l'invite de saisie d'un de caractre


Saisir le caractre ;
L'afficher

37
Les oprateurs

Sur les entiers ou rels


+ addition , - soustraction , * multiplication , / division , %
modulo (reste de la division entire)
la division de deux entiers donne un nombre entier
ordre de priorit : - (signe) puis */% puis + et - (moins)
en cas de priorit identique les calculs se font de gauche
droite
dans le doute on utilise des parenthses : (3+4)/2

38

Exercice 6

Demandez la saisie de deux nombres et en afficher la


somme.

39
Exercice 6

Demandez la saisie de deux nombre et en afficher la


somme.

40

Oprateur conditionnel

Pour affecter la variable max le plus grand des deux nombres a et b, on


peut crire :
max = a>b?a:b
L'expression figurant droite de l'oprateur d'affectation est en fait
constitue de trois expressions (a>b,a et b) qui sont les trois oprandes de
l'oprateur conditionnel, lequel se matrialise par 2 symboles spars : ? et
:.
D'une manire gnrale, cet oprateur value la premire expression qui
joue le rle d'une condition. Comme toujours en C, celle-ci peut tre en fait
de n'importe quel type. Si sa valeur est diffrente de zro, il y a valuation
du seconde oprande, ce qui fournit le rsultat ; si sa valeur est nulle, en
revanche, il y a valuation du troisime oprande, ce qui fournit le rsultat.
Rien n'empche que l'expression conditionnelle soit value sans que sa
valeur soit utilise.

41
Le conversions de type (cast)

int i =2; float x=3.5 ; x+i => 5.5 i a t converti en float


float x=2 ; idem
le type char peut tre converti en int (valeur ASCII)
c='a' ;
(int)c => 97
c+1 => 98
On peut forcer une conversion en un type en mettant le
type entre parenthses
exemple : (double) (n/p)= convertit n / p en double
(double) n /p : convertit n en double puis divise par p
42

Oprateur relationnel

On retrouvera ses oprateurs dans les instructions de test


le rsultat d'une comparaison est un entier 1 pour vrai et 0
pour faux
< infrieur , >, <=, >=,!=, ==
Priorit : les quatre premiers oprateurs (<,<=,>,>=) sont
de mme priorit. Les deux derniers (==,!=) possdent
galement la mme priorit, mais celle-ci est infrieure
celle des prcdents
a<b == c<d est quivalent (a<b)==(c>d) ce qui veut dire
1==0 ce qui est faux

43
Oprateurs logiques

On dispose de trois oprateurs logiques classiques : et (not &&), ou (not ||)


et non (not !).
Par exemple
(a<b)&&(c<d)
prend la valeur 1 (vrai) si les deux expressions a<b et c<d sont toutes les deux
vraies (de valeur 1)
l'oprateur ! a une priorit suprieure celle de tous les oprateurs
arithmtiques binaires et aux oprateurs relationnels. Donc, pour crire la
ngation de : a==b, ont doit utiliser des parenthses : !(a==b).
l'oprateur || est moins prioritaire que &&. Tous deux sont de priorit infrieur
aux oprateurs arithmtiques ou relationnels.
Enfin, les oprateurs && et || jouissent en C d'une proprit intressante : leur
second oprande (celui qui figure droite de l'oprateur) n'est valu que si la
connaissance de sa valeur est indispensable pour dcider si l'expression
correspondante est vraie ou fausse.
44

Oprateur d'incrmentation

Les actions d'incrmentation et de dcrmentation d'une variable peuvent tre


ralises, en C, par des oprateurs unaires portant sur cette variable.
L'expression
++i;
a pour effet d'incrmenter de 1 la valeur de i et sa valeur est celle de i aprs
incrmentation.
i=0 ; printf ("%d",i++) ; => 0

Par contre, si l'oprateur est plac aprs la variable, la valeur de l'expression


correspondante est celle de la variable avant l'incrmentation
i++;
a pour effet d'incrmenter de 1 la valeur de i mais la valeur de cette expression est celle
de i avant incrmentation.
i=0 ; printf("%d",++i) ; => 1
La priorit de ces oprateurs est assez leve ce qui permet d'crire des expressions
assez compliques sans qu'il soit ncessaire de placer des parenthses.

45
Oprateur d'affectation largie

On peut remplacer i = i+k par : i += k


ou encore a = a*b par : a *= b;
D'une manire gnrale, C permet de condenser les
affectations de la forme :
lvalue=lvalue oprateur expression
en
lvalue oprateur = expression

Cette possibilit concerne tous les oprateurs binaires


arithmtiques et de manipulation de bits.
46

Oprateur squentiel

L'oprateur squentiel(,) permet de runir plusieurs instructions en une seule.


Exemple : a*b , i+j est une expression qui value d'abord a*b, puis i+j et qui
prend comme valeur la dernire calcule (donc celle de i+j).
L'expression suivante : i++, j=i+k;
contient :
- l'valuation de l'expression i++
- l'valuation de l'affectation j=i+k.
On utilise alors la valeur de i aprs incrmentation.
L'oprateur squentiel sera principalement utilis en pratique, dans des
instructions de choix ou dans des boucles; l o celles-ci s'attendent trouver
une seule expression, l'oprateur squentiel permettra d'en placer plusieurs et,
permettra d'y raliser plusieurs actions ou plusieurs calculs.

47
Oprateur sizeof

L'oprateur sizeof, dont l'emploi ressemble celui d'une fonction,


fournit la taille en octets. Par exemple, dans une implmentation o le
type int est reprsent sur deux octets et le type double sur 8 octets, si
l'on suppose que l'on a affaire ces dclarations : int n; double z;
l'expression sizeof(i) vaudra 2,
l'expression sizeof(z) vaudra 8.
Avec un type sizeof renvoie la taille du type sizeof(double)
Cet oprateur offre un intrt lorsque l'on souhaite crire des
programmes portables dans lesquels il est ncessaire de connatre la
taille exacte de certains objets. On peut l'utiliser pour viter d'avoir
calculer soi-mme la taille d'objets d'un type relativement complexe
pour lequel on n'est pas certain de la manire dont il sera
"implment" par le compilateur.

48

Oprateur de manipulation des bits

Le langage C dispose d'oprateurs permettant de travailler directement sur le


"motif binaire" d'une valeur. Ceux-ci lui procurent ainsi des possibilits
traditionnellement rserves la programmation en assembleur.
A priori, ces oprateurs ne peuvent porter que sur des types entiers. Toutefois,
compte tenu des rgles de conversion implicite, ils pourront galement
s'appliquer des caractres (mais le rsultat sera entier).
Binaire & et (bit bit)
| ou inclusif(bit bit)
^ ou exclusif(bit bit)
<< dcalage gauche
>> dcalage droite
Unaire ~ complment un (bit bit)

49
Structure if

Les structures alternatives permettent de ne pas excuter systmatiquement certaines


instructions, mais seulement dans certains cas bien prvus par le programmeur. Dans
ce contexte, nous verrons les instructions if, if else et switch.
Syntaxe de l'instruction if
Le mot else est facultatif, de sorte que cette instruction if prsente deux formes.
if (expression) {
instruction ;
instructions ;
}else
instruction_2
if (expression)
expression_1
Plusieurs instructions if else peuvent tre combines pour prendre des dcisions
complexes. Ces instructions peuvent notamment tre imbriques. Un else se rapporte
toujours au dernier if rencontr auquel un else n'a pas encore t attribu.
50

Exercice 7

Programmation d'un jeu ...


Vous choisissez un nombre d'or entre 0 et 100 que vous
mettez en variable dans votre programme, vous
demandez l'utilisateur un nombre et vous affichez si le
nombre d'or est plus petit ou plus grand que le nombre
entr.

51
Structure switch

Une unique instruction if autorise deux choix. On peut augmenter le nombre de


choix en imbriquant les tests. En fait, il existe une instruction spcifique pour le
cas o il faut choisir entre plusieurs alternatives : cette instruction est nomme
switch.
switch(<expression>){
case constante_1 : [<instruction(s)>; break;]
case constante_2 : [<instruction(s); break]
case constante_n : [<instruction(s); break]
[default : [<instruction(s);]]
}
Lorsque la valeur de l'expression situe aprs le switch concide avec l'une des
constantes case, attention au pige suivant : le programme ne se contente pas
d'excuter l(es) instruction(s) de la branche case concerne, mais excute toutes
les instructions suivantes, cela jusqu' la fin du switch. C'est pour cela qu'on met
l'instruction break
52

Les instructions rptitives

Les itrations, appeles aussi structures rptitives ou encore


boucles(loops), permettent de faire excuter plusieurs fois certaines
phases de programme, sans qu'il soit ncessaire chaque fois de rcrire
les instructions correspondantes. Le langage C dispose de trois types de
boucle, avec les structures rptitives :
- while
- for
- do while
Les boucles while et for procdent la vrification avant que soit excute
une quelconque instruction, donc en dbut de boucle. La boucle do while,
en revanche, commence par excuter toutes les instructions dpendant de
la condition et vrifient seulement la fin de la boucle si la condition
autorise une reprise des instructions dpendantes. Cela signifie que les
instructions de la boucle do while, contrairement while et for , sont
excutes au moins une fois, que la condition soit remplie ou non
53
Boucle while

La structure while permet de faire rpter l'excution d'instructions


tant qu'une certaine condition est remplie.
Syntaxe :
while (<expression>)
<instruction>;
while(<expression>){
<instruction(s)>;
}
Exemple :
int z=3;
while (z>0)
printf("%d",z--);
54

Boucle for

Comme la structure while, la structure for est une boucle qui teste une
condition avant d'excuter les instructions qui en dpendent. Les
instructions sont rptes tant que la condition est remplie .
Syntaxe :
for (<expression_I>;<expression_C>;<expression_R>) <instruction>;
for(<expression_I>;<expression_C>;<expression_R>) {
<instruction(s)>;
}
Exemple :
int i;
for(i=1;i<11;i++) printf("%d",i);

55
Instruction do while

Contrairement aux structures for et while, la boucle do while teste sa


condition aprs excution des instructions du corps de la boucle.
do
<instruction>;
while(<expression>)
do{
<instruction(s)>;
} while(<expression>);
Le mot cl "do" est suivi par une ou plusieurs instructions qui sont excutes
avant que soit value la condition de bouclage <expression> place entre
parenthses aprs le mot cl "while". Si la condition vaut TRUE alors les
instructions sont nouveau excutes. Ds que la vrification donne la
valeur 0 (FALSE) pour la condition, la boucle do while se termine sans que
les instructions soient excutes une nouvelle fois
56

Break et continue

break ; Provoque l'arrt de la premire instruction for,


while, do englobante.
Dans une instruction for, while ou do, l'instruction continue
provoque l'arrt de l'itration courante, et le passage au
dbut de l'itration suivante.

57
Exercice 8

Reprendre l'exercice prcdent mais ritrez la demande


tant que le joueur n'a pas trouv le nombre d'or. Comptez
le nombre de points en ajoutant 1 point chacune des
demandes.

58

Les tableaux

Dans certaines applications, il serait utile de pouvoir ranger des valeurs logiquement
rattaches, non pas dans des variables distinctes mais dans une variable commune. Par
exemple, si on veut stocker en mmoire les cotes obtenues par 50 tudiants un examen, il
serait plus simple de pouvoir stocker toutes ces cotes dans une variable de type complexe
plutt que de devoir stocker ces cotes dans 50 variables diffrentes.

Les variables qui permettent de stocker non pas une mais plusieurs valeurs sont des variables
de types complexes(composs). Complexes parce qu'on peut imaginer une telle variable
comme faite d'une srie de variables lmentaires. Le langage C dispose de deux types de
donnes complexes : les tableaux et les structures.

Un tableau est une variable qui se compose d'un certain nombre de donnes lmentaires de
mme type, ranges en mmoire les unes la suite des autres. Chaque donne lmentaire
reprsente elle-mme une variable. Le type des lments d'un tableau peut tre quelconque

Le tableau est unidimensionnel lorsque ses lments ne sont pas eux-mmes des tableaux.
Mais un lment de tableau peut lui-mme tre un tableau, donc un objet de type complexe.
On dit alors que l'on a un tableau multidimensionnel. Le terme "tableau" admet comme
synonymes les mots "vecteur" (tableaux unidimensionnel uniquement), "table" ou "matrice"

59
Tableaux une dimension

La dfinition d'un tableau unidimensionnel admet la syntaxe


suivante :
<Type> <Nom du tableau> [nombre d'lments];
Exemple :
int t[4];
contient donc 4 lments : t[0], t[1], t[2] et t[3]
t[2]=7;
Les compilateurs C ne vrifient pas si l'index est valide, donc
compris entre les bornes 0 et index maximal. Si on emploie des
indices qui dpassent le maximum autoris, alors on adresse des
emplacements de mmoire situs hors du tableau sans que le
compilateur ne signale d'erreurs
60

Initialisation des tableaux uni-dimensionnels

Aprs sa dfinition
int x[3];
on peut initialiser ce tableau 0 en mettant :
x[0]=x[1]=x[2]=0;
Au cours de sa dfinition
<Type> <Nom du tableau> <[nombre d'lments>]={k1,k2,
,kn};
Exemple : int t[5]={0,0,0,0,0};
qui peut aussi s'crire int t[5]={0} ;car tous les lments
sont identiques
61
Exercice 9

Afficher un tableau qui comprend 1 au premier rang et le


double au rang suivant. 1, 2, 4, 8 etc..
On limitera l'exercice au 30 premiers entiers.
Que se passe-t-il si on va jusqu'aux 40 premiers entiers ?

62

Tableaux multi-dimensionnels

<Type> <Nom du tableau> [e1] [e2] [en];


Exemple : int k[3][4];
Pour un tableau deux dimensions le premier indice est l'indice
de ligne et le second indice est l'indice de colonne
Contrairement ce qu'il se passe avec les tableaux
unidimensionnels, pour les tableaux multidimensionnels l'image
par laquelle on les reprsente habituellement ne concorde plus
avec leur rangement en mmoire. Ainsi, un tableau
bidimensionnel est gnralement reprsent sous la forme
d'une matrice rectangulaire. En mmoire, par contre, un tel
tableau n'est nullement rang sous forme de "rectangle". Au
contraire, les lments des tableaux mme multidimensionnels
sont toujours disposs les uns la suite des autres.
63
Initialisation des tableaux multi-dimensionnels

On peut procder comme pour les tableaux unidimensionnels en


indiquant les valeurs d'initialisation droite de l'oprateur d'affectation
"=", entre des accolades et spares les unes des autres par des
virgules :
int k[3][4]={700,500,200,500,900,800,400,300,600,700,900,800};
Les valeurs sont attribues aux lments du tableau dans l'ordre. Le
premier lment k[0][0] reoit la premire valeur de la liste (700), le
second lment k[0][1] reoit la seconde valeur de la liste (500), le
troisime lment k[0][2] reoit le troisime lment de la liste(200),
ou bien on peut faire l'initialisation sous la forme :
int k[3][4]={ {700,500,200,500},{900,800,400,300},{600,700,900,800}};

64

Les chanes de caractres

Les chanes de caractres(ou string) sont des suites de


caractres composes de signes faisant partie du jeu de
caractres reprsentables de l'ordinateur. En C, les
chanes de caractres, qu'elles soient constantes ou
variables, sont de par leur structure des tableaux une
dimension ayant des lments de type char.
La dfinition :
char s[20];
cre un tableau s de 20 lments de type char.
Cette chane 's' pourra en fait contenir au maximum 19
caractres et pas 20 car le dernier caractre est 0
65
Les chanes de caractres

Les chanes de caractres(ou string) sont des suites de


caractres composes de signes faisant partie du jeu de
caractres reprsentables de l'ordinateur. En C, les
chanes de caractres, qu'elles soient constantes ou
variables, sont de par leur structure des tableaux une
dimension ayant des lments de type char.
La dfinition :
char s[20];
cre un tableau s de 20 lments de type char.
Cette chane 's' pourra en fait contenir au maximum 19
caractres et pas 20 car le dernier caractre est 0
66

Initialisation d'une chane de caractres

char chaine[41];
scanf("%s",chaine); // et pas &chaine
char * chaine="comment allez vous ?" ; // Fonctionne mais chaine est un
pointeur sur une chane constante pas question de changer la valeur de
chane
char s[]="bonjour"; // est quivalent char s[8]="bonjour" ;
char s[]={'b','o','n','j','o','u','r','\0'}; // idem
while((name[i]=getchar())!='\n'){
i++;
name[i]='\0';
}
Nous verrons que les chanes de caractres sont galement des pointeurs :
s[] se note *s
67
Copie de chanes de caractres

Il existe une fonction de bibliothque strcpy qui permet de recopier une chane dans un
tableau char, ce qui correspond bien la manipulation demande.
strcpy(<adresse_tableau1destination>,<adresse_tableau2source>);
Les deux paramtres de la fonction <Adresse_tableau1> et <Adresse_tableau2>
reprsentent les adresses de deux tableaux char. La fonction strcpy copie le contenu du
tableau dont l'adresse est spcifie par le second paramtre de la fonction (caractre
nul compris) dans le tableau dont l'adresse est donne par le second paramtre. Le
tableau "cible" devrait tre ici au moins aussi grand que la chane que l'on y recopie.
Les adresses des tableaux peuvent tre transmises la fonction sous l'une des formes
que nous connaissons dj (nom de tableau, constante chane, expression avec
l'oprateur &, pointeur).
char s[8];
strcpy(s,"bonjour");
L'utilisation de strcpy et de quelques autres fonctions de traitement de chanes de
caractres exige l'inclusion dans le programme du fichier d'en-tte : string.h qui contient
les dclarations des fonctions concernes.
#include <string.h>
68

Autres oprations sur les chanes de caractres

Concatnation de chanes de caractres


strcat (<adresse_tableau1>,<adresse_tableau2>);
Comparaison de chanes de caractres
strcmp(<Adresse_tableau1>,<Adresse_tableau2>);
si la valeur est infrieure 0, alors la chane dont l'adresse est donne par
le premier paramtre de la fonction est infrieure l'autre chane, si la
valeur est gale 0, alors les deux chanes sont gales, si la valeur est
suprieure 0, alors la chane dont l'adresse est donne par le premier
paramtre de la fonction est suprieure l'autre chane.
longueur d'une chane de caractres : strlen(<Adresse_tableau>);
copie n caractres char *strncpy(char *dest, const char *src, size_t n);

69
Les fonctions

Dans un programme, on est souvent amen rpter plusieurs fois les mmes
oprations des endroits diffrents et avec des donnes diffrentes. Pour viter de
devoir rcrire chaque fois cette suite d'oprations, la plupart des langages de
programmation permettent au programmeur de dfinir des sous-programmes qu'il
suffit d'appeler aux endroits voulus.
Ces sous-programmes sont aussi trs utiles lorsqu'on a un problme trs complexe
traiter. En effet, il est plus facile de le dcouper en sous-problmes et d'crire un
sous-programme pour chacun d'eux. Il suffit alors de rassembler le tout dans un
programme principal. En C tous les sous-programmes sont appels des fonctions.
Chaque fonction peut en gnral tre teste indpendamment du reste du
programme et une fonction peut tre utilise plusieurs fois diffrents endroits du
programme sans devoir rcrire les instructions chaque fois.
Il existe des fonctions prdfinies que le programmeur peut utiliser, par exemple
printf ou scanf.
Nous allons voir dans la suite du cours comment le programmeur peut dfinir de
nouvelles fonctions

70

Dfinition d'une fonction

Pour construire une fonction, il faut coder les instructions qu'elle doit excuter.
classe type identificateur (liste des paramtres formels avec leur type)
{
corps de la fonction
}
S'il n'y a pas de paramtres, les parenthses sont quand mme obligatoires ( pour
certains compilateurs, on doit mettre void entre parenthses pour indiquer qu'il n'y a
pas de paramtres).
Les dfinitions de fonction se placent dans n'importe quel ordre mais toujours en
dehors de toute fonction(c'est--dire de manire globale).
Si la fonction n'est pas dfinie avant son appel, on est oblig de la dclarer.

71
Dclaration de fonction

Tout objet en C doit tre dclar avant d'tre utilis. Ceci est donc applicable
aux fonctions on peut dclarer la fonction sans sa dfinition mais uniquement
avec ses paramtres. On appellera cela le prototype d'une fonction. Les
arguments sont appels la signature d'une fonction.
classe type identificateur (liste des types des paramtres);
Sur certains compilateur ceci pose problme
#include <stdio.h>
void main() {
message();
}
void message() {
printf("cours de langage\n");
}
on placera une dclaration avant le main
void message() ; // avec les arguments ventuels
72

Paramtres de fonction

double cube(double x) /*dfinition de la fonction */


{ double y;
y=x*x*x;
return y;
}
Un paramtre formel est une variable locale, connue
seulement l'intrieur de la fonction o est dfini ce
paramtre. Les paramtres formels et effectifs doivent
correspondre en nombre et en type ceux fournis
l'appel, les noms par contre peuvent diffrer.

73
Retour d'une fonction

L'instruction return met fin l'excution des instructions


d'une fonction et rend le contrle du programme
l'instance appelante. ventuellement elle lui renvoie une
valeur que l'instance concerne peut utiliser dans ses
propres instructions.
return (<expression>)

les parenthses sont facultatives.

74

Appel d'une fonction

Nom de la fonction (liste des paramtres)


Les valeurs des paramtres effectifs sont recopies dans les paramtres formels
correspondants et donc, si ces valeurs sont modifies dans la fonction, elles ne le
seront pas dans la fonction appelante (passage par valeur).
Pour appeler la fonction cube dfinie prcdemment, il suffit d'crire l'instruction :
y=cube(3); ou directement printf("%f",cube(3));

La fonction appele reoit le contrle et commence l'excution de ses instructions.


Si une instruction return est rencontre, l'excution de la fonction se termine et le
contrle est rendu la fonction appelante (une valeur peut tre renvoye la fonction
appelante via l'instruction return).
Si la fonction ne contient pas d'instruction return , celle-ci est excute jusqu' sa
dernire instruction.

75
Exercice 10

crire la fonction max qui donnent le maximum de deux nombres,


crire la fonction min qui donne le minimum de deux nombres
crire la fonction ascii qui renvoie le code ASCII d'un caractre
crire la fonction Char qui renvoie le caractre correspondant un entier entre 0
et 255
crire fonction premmajuscule qui met le premier caractre d'une chane de
caractres en majuscule.
crire la fonction majuscule qui met une chane de caractres en majuscule,
crire la fonction minuscule qui met une chane de caractres en minuscule
Les tester dans le corps de la fonction main()

76

Passage de l'adresse une fonction

En C, une fonction ne peut retourner qu'une seule valeur. Une fonction ne peut pas modifier la valeur de ses
paramtres.

Pour qu'une fonction puisse fournir des rsultats dans un de ses paramtres effectifs ou modifier un paramtre,
il faut utiliser les pointeurs comme paramtres. Le pointeur(adresse) ne sera pas modifi mais le contenu de
l'adresse sera ,lui, modifi !
void echange(int *,int *);
void main() {
int u,v;
scanf("%d %d",&u,&v);
echange(&u,&v) ;
}
void echange(int *a,int *b)
{ int z;
z=*a;
*a=*b;
*b=z;
}

77
Exercice 11

crire une fonction qui partir d'une chane de caractres


de la forme jj/mm/aaaa renvoie le jour, le mois et l'anne
sous forme d'entiers

78

Complment sur les directives de compilation

#define
#macro
#undef
#ifdef
Autres directives

79
Les #define

#define nbmax 5
demande de substituer au symbole nbmax le texte 5, et cela chaque fois que ce
symbole apparatra dans la suite du fichier source.
#define entier int
place en dbut de programme, permettra d'crire "en franais" les dclarations de
variables entires. Ainsi par exemple :
entier a,b;
sera remplac par :
int a,b;
On peut galement remplacer une instruction par un mot :
#define bonjour printf("bonjour");
#define affiche printf("resultat %d\n",a);
#define ligne printf("\n");

80

Attention attention

Une directive dfinit une constante pas une variable


ainsi :
#define MINIMAL 10
i=MINIMAL+10 ; => i vaut 20
MINIMAL=MINIMAL+10 ; => revient crire
10=10+10 ; qui ne veut rien dire
i=i+10 ; veut dire i prend la valeur de i + 10
i=10+10 ; veut dire i vaut 20
#define MINIMAL 10 ; passe car le compilateur ajoute
l'instruction vide ;
#define MINIMAL = 10 ; ne passe pas
81
Attention Attention

Une macro n'est pas une fonction


#define MAX(x,y) x > y ? x : y
int valeur=2 *MAX(2 ,3) ;
=> 2 * 2 > 3 ? 2 : 3 => 4 > 3 ? 2 : 3 => 3
alors que si MAX tait une fonction
2 * MAX(2,3) => 2*3=>6

82

Prprocesseur #define macro

La dfinition de macros ressemble la dfinition de symbole mais elle fait


intervenir la notion de paramtres.
#define <nom>(param1,param2,,paramN) <texte de remplacement>
Par exemple, avec cette directive :
#define carre(a) a*a
le prprocesseur remplacera dans la suite, tous les textes de la forme :
carre(x)
dans lesquels x reprsente en fait un symbole quelconque par : x * x
Par exemple :
carre(z) deviendra z*z
carre(valeur) deviendra valeur*valeur
carre(12) deviendra 12*12
83
Processeur #undef

L'instruction #undef supprime la dfinition d'une constante


symbolique prcdemment cre via #define. Cela signifie
qu' partir de cet endroit-l la constante n'a plus aucun
sens dans le programme.
On peut de mme supprimer la dfinition d'une macro :
#define ADD(a,b) a+b
#undef ADD

84

Autres directives

Commandes #ifdef et #ifndef


Dans ce qui prcde il est possible de remplacer les commandes #if expression par : #ifdef nom
ou #ifndef nom.
Dans ce cas, le test ne porte plus sur la nullit ou non d'une expression, mais sur la dfinition ou
non d'une macro. La commande #ifdef nom a pour smantique : << si nom est dfini >>, et
#ifndef nom a pour smantique : << si nom n'est pas dfini >>.

L'oprateur #defined
L'oprateur defined est un oprateur spcial : il ne peut tre utilis que dans le contexte d'une
commande #if ou #elif. Il peut tre utilis sous l'une des deux formes suivantes : defined nom ou
bien : defined ( nom ). Il dlivre la valeur 1 si nom est une macro dfinie, et la valeur 0 sinon.
L'intrt de cet oprateur est de permettre d'crire des tests portant sur la dfinition de plusieurs
macros, alors que #ifdef ne peut en tester qu'une.
#if defined(SOLARIS) || defined(SYSV)

La commande #error La commande #error a la syntaxe suivante : #error suite-d-units-lexicales


La rencontre de cette commande provoquera l'mission d'un message d'erreur comprenant la
suite-d-units-lexicales. Cette commande a pour utilit de capturer la compilation des
conditions qui font que le programme ne peut pas s'excuter sur cette plate-forme.

85
Programmation II

Gestion de la mmoire
Pointeurs et allocation dynamique
Structures et Unions
Champs de bits
Types et numrations

86

Les pointeurs

Prcdemment, l'accs une variable se faisait par l'intermdiaire de son nom. Si


par exemple, on devait affecter une variable 'a ' la valeur d'une autre variable
'b', on y arrivait par l'instruction suivante : a=b; dans laquelle un nom de variable
figurait des deux cts de l'oprateur d'affectation "=".
Mais au lieu d'accder par ce nom directement la variable concerne, on peut
choisir aussi un chemin d'accs indirect par le biais de l'adresse de la variable.
Pour cela, on utilise ce qu'on appelle un pointeur.
Un pointeur est une donne constante ou variable qui mmorise ladresse dune
variable. On dit que le pointeur renvoie ou pointe vers la variable concerne, cela
via son contenu consistant en une adresse de variable.
Une adresse nest rien dautre que la dsignation (indpendante du type) dun
certain emplacement mmoire, savoir celui partir duquel est range la donne
concerne.
Ladresse est donc ladresse du premier octet et on lappelle aussi adresse du
dbut de la variable. Quand on parle de ladresse dune variable, il sagit en fait
toujours de son adresse de dbut .

87
Dfinition

<type donne> *<nom pointeur>


Les pointeurs peuvent rfrencer des variables de type quelconque(sauf
les variables register et les variables champs de bits).
Exemples :
int *p; /* dfinit un pointeur vers un entier*/
char *x; /*dfinit un pointeur vers un caractre*/
float *z; /*dfinit un pointeur vers un flottant*/
un pointeur n'est pas tout fait un tableau :
Attention : char *s = "toto" ; // vous ne pouvez pas faire *s='c' ;
AAODBBD0
a 1 AAODBBD4 *ptr=1
3 AAODBBD8 ptr+1= AA0DBBD8
ptr AAODBBD4 AAODBBDB *ptr=&a *(ptr+1)= 3

88

Pointeur et adresse

int *pointeur ;pointeur sur un entier


int *pointeur=&a ; // le pointeur prend l'adresse de a
int *pointeur=0 ; // le pointeur est NULL,
int *pointeur =1 ; // n'est pas permis
int *pointeur ; *pointeur=1 ; //
int entier ; c'est un entier
*pointeur=entier ; le pointeur qui est un entier prend la valeur
de de l'entier
&entier : ceci est l'adresse en mmoire de entier, c'est un
pointeur. Ainsi &entier est un pointeur.
pointeur=&entier ;
89
Pointeurs et tableaux

En C, l'identificateur d'un tableau employ seul , est un pointeur


constant sur le premier lment du tableau
L'accs un lment quelconque d'un tableau peut se faire non
seulement par le nom du tableau accompagn d'un indice, mais aussi
par un pointeur manipul par des oprations spcifiques
d'arithmtique de pointeurs
int x[10];
int *px;
on peut dire : px=&x[0] (ou px=x)
px+1 reprsenterait alors l'adresse de x[1], px+2 l'adresse de x[2]
Attention : *p="bonjour" ; => p pointeur sur la constante bonjour qui ne
pourra tre modifie.

91

Gestion de la mmoire dynamique

Lorsqu'on dfinit un tableau dans un programme, on doit


lui donner obligatoirement une taille fixe. Ceci est un gros
inconvnient car souvent, on ne sait pas, l'avance, de
combien d'lments on aura vraiment besoin.
On parle alors de gestion dynamique de la mmoire. Cette
gestion est ralise l'aide de certaines fonctions
prdfinies du C.
On peut allouer de la mmoire dynamiquement par
malloc, calloc ou realloc
on libre la mmoire par la fonction free avec en argument
le pointeur sur l'objet alou. : void free(p)

92
malloc

#include <stdlib.h>
La fonction "malloc" prend de la place mmoire sur le tas (heap). Ce
dernier est une zone de mmoire libre, disponible pour le programme
concern. Pour cela, on transmet la fonction, comme paramtre , un
nombre entier exprimant la dimension (en octets) du bloc mmoire que l'on
dsire rserver. La fonction "malloc" rserve alors(si possible) un bloc de
mmoire contigu ayant la dimension indique et retourne son adresse
void * malloc(int size);
exemple : double *d;
d=(double*) malloc(400);
si malloc n'arrive pas rserver de la mmoire elle renvoie un pointeur
NULL

93

Exercice 12

crire deux fonctions qui renvoient l'inverse d'une chane


de caractres, l'une en utilisant les tableaux, l'autre en
utilisant les pointeurs. Exemple : maman => namam

94
Cas des chanes de caractres

Nous l'avons vu char chaine[30] ; permet de dfinir une chane de 29


caractres au maximum, le caractre \0 faisant office de dernier caractre.
La manipulation dune chane est donc analogue celle d'un tableau une
dimension. Maintenant, si on veut pouvoir fixer la taille de la chane en
cours de programme en fonction des besoins, il faut, comme nous lavons
vu prcdemment travailler de manire dynamique cest--dire dfinir un
pointeur vers un caractre et allouer de lespace mmoire en cours de
programme en utilisant les fonctions dallocation dynamique.
Exemple :
char *nom;
nom=(char*)malloc(20);
Dans ce mode de dclaration, on peut faire varier la place mmoire
occupe par la chane en cours de programme.

95

Organisation de la mmoire

HEAP (Tas)

malloc (C)
new (c++)

STACK (Pile LIFO)


variables locales, paramtres fonctions

DONNEES STATIQUES
variables globales et locales statiques, constantes,fonctions

CODE 96
Exercice 12 bis

crire un programme qui indique l'adresse mmoire :


d'une variable locale
d'une variable globale
d'une variable statique
d'un tableau local
d'un tableau global
d'une constante
d'une procdure

97

calloc

void * calloc(int,int);
les valeurs entires <nombre> et <dimension> dsignent
respectivement le nombre d'objets dsirs et la taille (en
octets) de chaque objet. <pointeur> est une variable
pointeur dans laquelle on range l'adresse du bloc allou
retourne par calloc.
calloc rservera donc nombre * dimension octets
calloc initialise la mmoire 0 ce qui peut tre utile

98
realloc

void * realloc ( void * base , size_t t )


La fonction realloc() tente de redimensionner un bloc
mmoire donn la fonction via son adresse base avec
une nouvelle taille t
size_t est souvent utilis pour dsigner un entier non sign
long. C'est un exemple de #define utilis pour forcer les
tailles des octets sur diffrentes architectures.
Si la tentative choue elle renvoie un pointeur NULL

99

Fonctions

Lorsqu'on veut qu'une fonction puisse modifier la valeur d'une donne passe
comme paramtre, il faut transmettre la fonction non pas la valeur de l'objet
concern, mais son adresse. La consquence en est que la fonction appele ne
travaille plus sur une copie de l'objet transmis, mais sur l'objet lui-mme (car la
fonction en connat l'adresse). La fonction appele range l'adresse transmise dans
un paramtre formel appropri, donc dans un pointeur. Bien que ce paramtre
formel ne soit qu'une variable locale la fonction appele, la fonction a maintenant
accs, via ce paramtre, l'objet de la fonction appelante dont l'adresse a t
passe comme paramtre effectif. Le passage des paramtres par adresse permet
donc une fonction de modifier les valeurs des variables d'autres fonctions.
Si nous reprenons la fonction "echange" dj rencontre, on peut comprendre
maintenant son prototype :
void echange (int *, int *);
en effet, on communique la fonction des adresses d'entiers et donc, les
paramtres formels de cette fonction sont des pointeurs vers des entiers.
l'appel se fera par echange(&val1,&val2)

100
Pointeur en argument d'une fonction

Soit T un tableau d'entiers dfini dans main(). Si on veut


transmettre l'adresse du tableau T une fonction fonc, il
suffira d'crire : fonc(T) ou fonc(&T[0]).
Le paramtre formel pourra s'crire : fonc (int *x) ou
fonc(int x[]).

101

Les pointeurs sur les fonctions

On peut dclarer des pointeurs sur des fonctions :


type_retour (*pointeur_fonction)(liste_paramtres);
la parenthse du milieu sert ne pas confondre le * avec un
pointeur sur le type en paramtre de retour
on peut passer un pointeur de fonction comme argument de
fonction
on peut construire un tableau de pointeurs de fonctions

102
Fonctions avec arguments variables

Ceci est une extension ANSI


#include <stdarg.h>
on dispose du type : va_list et de trois macros : v_arg, va_end, va_start
int fonction( int n,...) // les trois points indiquent le nombre d'arguments variables
{
va_list ap ;
int d ;
va_start (ap,n) ;
for ( ap =0 ; ap <n ; ap++) d=va_arg(ap, int) ;
va_end(ap) ;
...
}

v_start initialise ap qui peut tre de type entier, char * etc en fonction du type de n
v_arg renvoie l'argument suivant, suivant le type donn en deuxime argument
v_end dclenche un retour normal de la fonction

103

Le fonctions rcursives

Une fonction C peut tre rcursive c'est dire s'appeler elle-


mme.
Exemple n ! = n*(n-1)*..*1
unsigned long factoriel (int n){
if (n < 0) { exit (EXIT_FAILURE);}
else if (n == 1 || n == 0) {
return 1L;
} return n * factoriel (n - 1);
}
Attention :
sortir un jour de la boucle de rcursivit
aux stak overflow

104
Cration de nouveaux types

La dfinition d'un nouveau type utilisable pour dclarer


directement des variables, ncessite sa dfinition en
utilisant le mot-cl typedef
avec la la squence : typedef unsigned short ushort;
ushort devient un alias (synonyme) de unsigned short.
Il est ensuite possible de dclarer ou dfinir une variable x
par ushort x;

105

Les numrations

enum jours {lundi, mardi, mercredi, jeudi, vendredi, samedi, dimanche};


enum jours j ;
typedef enum {lundi, mardi, mercredi, jeudi, vendredi, samedi, dimanche}
jours;
jours j ;
enum jours {mardi=2, mercredi=3,lundi,jeudi=6} => lundi vaut 4
enum jours {mardi=4, mercredi=3,lundi,jeudi=6} => lundi vaut 4
on accde aux lements d'une numration par
jours j ;
if ( j == LUNDI)
ou (j ==0)
jours j ; j++ ;

106
Variables structures

struct livre{
char auteur[30];
char titre[20];
short an;
};
struct livre l={"AGATHA","CHRISTIE","MORT SUR LE NIL",1965};
on peut galement btir un tableau de variables structures
struct livre livres[200] ;
l'auteur du premier livre sera livres[0].auteur
on utilise souvent un typedef pour dfinir une structure
typedef struct {
char titre[10] ;
int ISBN ;
} livres;
On peut utiliser livres comme un type et dclarer livres l ;
107

Pointeurs et structures

struct article
{
char nom[20];
long numero ;
};
struct article *px; dfinit un pointeur sur la structure article
on accde on nom par (*px).nom ou par la notation simplifie
px->nom
Notons aussi que l'on peut trouver la variable struct article
a avec :
a.nom
&a->nom
108
Les structures

struct client{
char nom[30];
char prenom[20];
int cp;
float ca;
};
struct client a;
On accde nom par a.nom que l'on peut manipuler comme une chane
de caractres puisque c'en est une.
On peut faire struct client a, b ; suivi de b=a, par contre on ne peut
comparer deux structures.
la structure peut tre dclare dans la partie variable globale (en dehors du
main) ou dans la partie variable locale (dans une fonction)
on ne peut pas initialiser les diffrents champs des structures
109

Listes chanes

Il est souvent trs commode d'utiliser des listes chanes.


Chaque lment de la liste est compos
d'une ou plusieurs valeurs informatives
l'adresse de l'lment suivant
parfois l'adresse de l'lment prcdent.
On peut tendre ce mcanisme aux arbres avec feuilles gauches et feuilles
droites
On utilise un pointeurs dbut de liste (ou d'arbre) et des pointeurs pour parcourir
les listes
Exemple :
struct Liste { int valeur ; struct Liste *suivant;}
struct Liste *premier= malloc ( sizeof ( struct Liste ) ) ;
premier->valeur=45 ;
premier->suivant=NULL ;
110
Structures chanes avec typdef

Si on utilise un typedef avec un liste chane il faut prendre


conscience que le typedef n'existe pas pendant la cration
de la structure ainsi on doit explicitement faire
typedef struct TypeLivre {
char titre[20] ;
int annee ;
struct TypeLivre * suivant ;
} livre
ensuite on peut dclarer :
livre * elem ;

111

Exercice 13

Fabriquer une bibliothque de 5 livres. Pour chaque livre


on mmorisera son auteur, son titre, son anne de
parution, son nombre de pages et son genre. Utiliser un
tableau de structures.
Balayer la bibliothque et indiquer le titre de chaque livre.
Refaire l'exercice 13bis en utilisant cette fois ci une liste
chane de pointeurs pour dcrire la bibliothque
Dans l'exercice 13bis lorsqu'on ajoute un sixime livre
supprime le plus ancien, le second devient premier et le
nouveau le dernier.

112
Structures et fonctions

Comme les tableaux, les structures peuvent servir de


paramtres aux fonctions. Ici, cependant, contrairement
aux tableaux, on a de nouveau le choix entre le passage
d'une structure par valeur ou par adresse.
struct livre a ;
on peut appeler une fonction fonc(a) si la fonction est
dclare fonc ( struct livre a) ou bien fonc(&a) si la fonction
est dclare fonc ( struct livre *a)
Il vaut mieux passer une adresse qu'une structure car
quand celle si correspond une grosse zone de mmoire
le temps de copie peut devenir significatif.

113

Les unions

Les unions est un cas particulier de structure


union MonUnion
{
int entier;
double reel;
} u;
ici on utilise soit u.entier soit u.reel en fonction de la faon
dont on veut traiter l'information.
Une union est donc un choix entre plusieurs
reprsentations d'une zone mmoire.
une union peut tre incluse dans une structure
114
Les champs de bits

Le langage C permet de crer, l'intrieur d'une structure, des donnes (champs) dont
la taille est spcifie en bits. Ces champs doivent tre de type entier. Par exemple :
struct {
unsigned a : 1;
unsigned b : 1;
unsigned c : 4;
unsigned d : 3;
} x;
Ici, on a une structure x compose de 4 champs tous de type unsigned int : a de taille
= 1 bit, b de taille = 1 bit, c de taille = 4 bits, et d de taille = 3 bits. Cela ne signifie pas
que la taille de x est de 9 bits mais au moins 9 bits. La taille d'une donne est toujours
un multiple entier d'un "octet".
Les champs de bits peuvent tre galement utiliss, en faisant une union avec un
autre type, dans des programmes dpendantes d'une plateforme particulire pour
accder directement aux bits d'une donne quelconque. On retrouve alors l'intrt de
crer des champs sans noms : ils sont juste utiliss pour espacer des champs entre
eux. Dans des programmes portables, on utilisera plutt les oprateurs de
manipulation de bits que les unions et les champs de bits.
115

Les fichiers en haut niveau

Accs par FILE *fp qui est initialis par un fopen


on utilise stdio.h
La structure FILE contient
un pointeur sur le dbut du buffer
un pointeur donnant l'adresse du prochain byte
le nombre de caractres dans le buffer
l'tat du fichier
le descripteur du fichier (un n)
Ouverture FILE *fopen(char *<nom de fichier>,char * <"mode d'accs");
exemple : fp=fopen("client.dat","r");
mode d'accs peut tre "r" pour read, "w" pour write, "a" pour append, "r"
pour lecture seule avec le signe + le fichier est cr s'il n'existe pas
fclose(fp) ferme le fichier ou fcloseall() pour fermer tous les fichiers
116
Lecture criture fichier mode bloc

fonction de traitement bloc par bloc : fread et fwrite


unsigned int fwrite(adresse, taillebloc,nombreblocs,fp);
unsigned int fread(adresse,taillebloc,nombreblocs,fp);
feof (fp) 0 si la fin du fichier n'est pas atteinte
fonctions de traitement caractre par caractre : fgetc et
fputc
fonction de traitement ligne par ligne : fgets et fputs
char *fgets(char *s, int size, FILE *stream);
fonctions formates : fprintf et fscanf

117

criture lecture fichiers mode caractres

criture
int fputc(int <caractre>,FILE *<pointeur >);
La valeur de retour de cette fonction est un nombre entier
correspondant au caractre crit si pas de problme, ou
EOF (-1) en cas de problme.
Lecture
int fgetc (FILE *<pointeur>);
La fonction fgetc retourne le caractre lu sous la forme d'une
valeur entire. Si la valeur EOF(-1) est renvoye c'est que la
fin de fichier a t atteinte ou qu'il y a eu une

118
Lecture criture des chanes de caractres

criture
int fputs(char *<string>,FILE *<pointeur>);
La fonction fputs crit une chane de caractres dans un fichier, la
position courante. Le caractre nul de fin de chane n'est pas recopi. Fputs
retourne une valeur non ngative si l'criture s'est droule sans encombre.
La valeur de retour EOF indique une erreur.
Lecture
char * fgets(char *<string>, int <nombre>, FILE *<pointeur>);
Le premier paramtre correspond l'adresse de la zone mmoire qui va
recevoir la chane lue.Le deuxime paramtre donne le nombre de
caractres ranger dans la chane.Le troisime paramtre indique le
pointeur FILE rattach au fichier dans lequel on lit.
La fonction fgets retourne un pointeur vers le dbut de la zone mmoire
contenant la chane de caractres lue ou bien le pointeur NULL en cas de fin
de fichier ou d'erreur.
119

Exercice 14

Sauvegarder votre bibliothque dans un fichier texte


Rcuprer votre bibliothque depuis le fichier (exercice
14bis)

120
Classes de variables

VARIABLES GLOBALES Une variable globale est dfinie hors de toute


fonction (mme du main()). Elle est connue de chaque bloc et de chaque
fonction qui suit sa dfinition. Sa place est rserve lors de la
compilation. Les variables globales peuvent tre utilises et modifies
par toutes les fonctions, elles peuvent servir de moyen d'change
d'informations entre fonctions. Mais prenez garde aux accs multiples.
VARIABLES LOCALES Une variable locale est dfinie l'intrieur d'une
fonction ou d'un bloc. Une dfinition d'une variable locale doit toujours se
trouver en dbut de bloc. La porte d'une variable locale est limite au
bloc dans lequel elle est dclare, sa dure de vie dpendra de sa
classe de mmorisation. Une variable locale peut tre automatique
AUTO, statique STATIC, registre REGISTER,externe EXTERN

121

Variables auto

automatique : auto
Les variables de classe auto sont dfinies au sein d'une fonction ou d'un bloc.
Toute variable locale est donc par dfaut auto.
La porte d'une variable auto est la fonction dans laquelle elle est dfinie.
La variable n'existe en mmoire que durant l'excution de la fonction ou du bloc
dans lequel elle est dfinie. Lorsque toutes les instructions du bloc sont
excutes, la variable disparat de la mmoire et sa valeur est
automatiquement perdue pour le programme. Si le bloc est de nouveau
excut, la variable est recre.
Une variable auto n'a pas de valeur initiale par dfaut. Si elle apparat dans le
membre de droite d'une galit, elle doit avoir t initialise soit par affectation
soit explicitement lors de sa dfinition.

122
Variables static

statique : static
Les variables statiques sont dfinies avec le mot cl static.
Elles ont la mme porte que les variables auto mais elles
existent en mmoire pendant toute l'excution du
programme.
Une variable statique existe partir du moment o le bloc
dans lequel elle a t dfinie a t excut une fois.
Une telle variable est cre une seule fois en mmoire. Si
elle est initialise lors de sa dfinition ,elle ne sera plus
rinitialise lors d'un appel ultrieur.
Une telle variable est initialise automatiquement zro
123

variable extern

externe : extern
On utilise parfois, dans une fonction ou dans un bloc, le
mot cl extern dans la dfinition d'une variable. Il est l
pour indiquer au compilateur qu'il ne s'agit pas ici de la
dfinition d'une variable locale , mais de la dclaration
d'une variable qui a t dfinie ailleurs dans le
programme. Cette dclaration ne cre pas de nouvel objet,
et en particulier n'entrane aucune allocation de mmoire
pour quelque donne que ce soit. Elle sert simplement
dclarer au compilateur qu'il doit utiliser une variable
globale dfinie ailleurs dans le programme. On parle alors
d'importation de variable globale.

124
Exercice 15

Implmenter une fonction qui renvoie un nombre


incrment de un chaque appel

125

Variables volatiles

volatile : cette classe de variable sert lors de la


programmation systme. Elle indique qu'une variable peut
tre modifie en arrire-plan par un autre programme (par
exemple par une interruption, par un thread, par un autre
processus, par le systme d'exploitation ou par un autre
processeur dans une machine parallle). Cela ncessite
donc de recharger cette variable chaque fois qu'on y fait
rfrence dans un registre du processeur, et ce mme si
elle se trouve dj dans un de ces registres (ce qui peut
arriver si on a demand au compilateur d'optimiser le
programme)

127
Les principales options de compilation

-o program : dfinit le nom du programme sinon a.out


-g gnre les informations de dbogage
-0n : niveau d'optimisation de taille des binaires
-mcpu : code pour le cpu (-mx86)
-march=cpu : type de processeur par exemple -marm
-W : active de Warning supplmentaires
-Wall : actibe tous les Warning possibles

129

Les tapes de compilation

Quatre tapes
Preprocessing
gcc -E programme.c > programme.i
Compilation vers l'assembleur
gcc -S programme.i produit le fichier programme.s
Assembleur vers le code machine
gcc -c programme.s produit le fichier programme.o
dition des liens
gcc -o programme programme.o produit l'excutable programme
Mais en gnral on fait les 4 en une tape raccourcie :
gcc -o programme programme.c
130
Makefile

Un Makefile est un fichier constitu de plusieurs rgles de


la forme :
cible: dpendance
commandes
Les dpendances sont analyses, si une dpendance est
la cible d'une autre rgle du Makefile, cette rgle est son
tour value.
Lorsque l'ensemble des dpendances est analys et si la
cible ne correspond pas un fichier existant ou si un
fichier dpendance est plus rcent que la rgle, les
diffrentes commandes sont excutes.

131

Exemple d'un fichier make

all : hello
hello: hello.o main.o
gcc -o hello hello.o main.o
hello.o: hello.c
gcc -o hello.o -c hello.c
main.o: main.c hello.h
gcc -o main.o -c main.c
clean :
rm *.o

132
Pour aller plus loin

les makefiles sont dots de variables personnalises


gnralement CC, CFLAGS, LDFLAGS, EXEC
de variables internes
$@ : nom de la cible
$< : nom de la premire dpendance
$^ : liste des dpendances
$ ? : liste des dpendances plus rcentes que la cible
$* : nom du fichier sans suffixe
les commandes silencieuses commencent par un @
voir plus d'info sur la page gnu make
133

Les librairies

Les librairies dynamiques : le code de la librairie est prsent sur


le disque au moment de l'excution et le programme va
chercher les fonctions dont il a besoin
extension .so (sharing object) sous Unix
ou dll (dynamic link library) sous window
Les librairies statiques : le code de la librairie est inclus dans
l'excutable
extension .a
Dans le premier cas la librairie peut tre utilise par plusieurs
programme => rduction de place
Dans le cas de librairies rares on prfre les librairies statiques
134
Librairie statique

Fabrication librairie statique


gcc -c fonctions.c -o fonctions.o
ar -q libmachin.a machin.o
utilisation de la librairie statique au moment du lien
gcc program.o libmachin.a -o programme

135

Librairie dynamique

Cration
gcc -c -fPIC truc -o truc.o
gcc -shared -fPIC truc.o -o libtruc.so
L'option -fPIC (Position Independent Code) compile sans
indiquer d'adresse mmoire dans le code
Utilisation
cp libtruc.so /usr/local/lib
lancer ldconfig : il inspecte les bibliothques dans les
emplacements /lib,/usr/lib,/usr/local/lib, les chemins
indiqus dans /etc/ld.so.conf , les chemins de
LD_LIBRARY_PATH.
136
Techniques de dveloppement

Gestion du passage d'arguments d'une application


Alignement en mmoire
Granularit du code
Portabilit du code

137

Arguments d'une application

main ( int argc, char *argv[]) {


}
Le paramtre argv est en ralit un tableau de pointeurs.
Chacun de ces pointeurs pointe sur des chanes de caractres
argc est le nombre d'arguments >0
argv[0] est le nom du programme
les autres sont les arguments du programme
Ainsi si argc vaut 2 nous aurons argv[0] nom du programme et
argv[1] l'argument unique du programme qui peut tre vide

138
Alignement en mmoire

Pour augmenter leurs performances, les processeurs sont souvent


relis la mmoire vive par un bus plus large que la granularit de
leur adressage : ainsi, un processeur capable d'adresser des octets
est reli la mmoire par un bus de 32 bits, soit 4 octets. Si une
donne de 4 octets ne se trouve pas une adresse divisible par 4,
alors il faut deux accs la mmoire pour l'atteindre, ce qui est plus
lent, et cause mme une erreur d'alignement dans la plupart des
processeurs.
Pour viter les pertes de performance et les problmes, les donnes
sont donc alignes avec des multiples de 2, 4, 8 selon les
caractristiques du processeur cible.
L'alignement en mmoire dpend fortement de l'architecture et du
compilateur. Il est important de connatre ces caractristiques surtout
lorsque la place mmoire est importante ainsi que pour la
communication entre deux architectures diffrentes.
139

Exemple

typedef struct _noalign {


char c; // 1 octet
double d; // 8 octets
int i; // 4 octets
char c2[3]; // 3 octets
}noalign; // or ceci fait 24 octets car le compilateur ajoute des octets de padding
pour dbuter une adresse multiple de 8

typedef struct _align{


double d;
int i;
char c2[3];
char c;
}align; // ceci fait bien 16 octets
l'option -Wpadded permet de donner un warning si la structure n'est pas aligne

140
Rgles pour la portabilit

Redfinissez les types car : char est toujours sur 8 bits, mais en fonction de
architectures short, int peuvent aller de 16 64 bits,long de 32 64 bits. Idem pour
les pointeurs sur entier ou long
mfiez vous donc des cast sur les pointeurs
signed unsigned n'est pas portable
pensez que les chanes de caractres sont constitues de charactres UTF8 sur 16
bits
Pensez aux problmes d'alignements de donnes ( voir struct )
Pensez que certaines machines sont little endian d'autre big endian
Mfiez vous des manipulations de bits
Utilisez des librairies portes dans tous les environnements Qt4 par exemple
fonctionne sous Windows, Mac, Unix
vitez d'crire des portions de code qui communiquent avec un hardware, passez
par des librairies portables au pire crivez une librairie contenant toutes les
fonctions communiquant avec le hardware
141

Rgles pour la portabilit

Redfinissez les types car : char est toujours sur 8 bits, mais en fonction de
architectures short, int peuvent aller de 16 64 bits,long de 32 64 bits. Idem pour
les pointeurs sur entier ou long
mfiez vous donc des cast sur les pointeurs
signed unsigned n'est pas portable
pensez que les chanes de caractres sont constitues de charactres UTF8 sur 16
bits
Pensez aux problmes d'alignements de donnes ( voir struct )
Pensez que certaines machine sont little endian d'autre big endian
Mfiez vous des manipulations de bits
Utilisez des librairies portes dans tous les environnements Qt4 par exemple
fonctionne sous Windows, Mac, Unix
vitez d'crire des portions de code qui communiquent avec un hadware, passez
par des librairies portables au pire crivez une librairie contenant toutes les
fonctions communiquant avec le hardware
142
Techniques de dbogage

Dbugueur gdb
Interface ddd
Excution pas pas
Points d'arrt conditionnels
Scrutation des registres de la mmoire
Dbugage distance
Dbugage crois
nm

143

gdb

gdb est un dbogueur en interface ligne de commande il est appel par les outils de haut niveau
et peut tre masqu par des interfaces graphiques. Souvent les interfaces graphiques ne tirent
pas toute la puissance de gdb

il est utile d'avoir compil son programme avec l'option -g afin de disposer des tables des
symboles

on le lance par gdb programme.


en ligne de commande run permet de lancer l'excution mais avant on met des points d'arrt
run peut prendre les arguments du programme

une fois dans l'invite on peut :


placer des points d'arrt par
break nom de fonction ( fonctionne sans table des symboles)
break numro de ligne de programme ( ncessite la table des symboles)
on peut ajouter if condition aprs un break ( condition utilise les variables du programme )
taper continue pour continuer jusqu'au break suivant
taper next pour passer l'instruction suivante (sans rentrer dans une fonction )
step entre dans la fonction

clear breakpoint retire le break une ligne ou une fonction


144
gdb (suite)

help
help affiche une aide de premier niveau
help data affiche une aide de deuxime niveau sur la rubrique choisie ici data
help command affiche l'aide sur une commande
on peut afficher les variables voulues par :
print variable : affiche la variable
whatis fonction : affiche le prototype de la fonction
where affiche la pile des fonctions appeles
dump avec divers arguments permet d'envoyer des donnes dans un fichier
binaire
watch pose un point d'affichage c'est dire interrompt l'affichage lorsqu'une
variable est modifie
list : affiche l'endroit o l'on se trouve dans le code

145

Les dbogueurs graphiques

ddd: est d'interface rustique mais puissant sous Linux


qtcreator offre un bon dbogueur
code::block offre une fonction de dbogage similaire
celle de qtCreator
les outils borland et Microsoft offrent des fonctions de
dbogages sophistiques
Mais toutes utilisent moins d'option que gdb

146
Autres outils

Electric fence (Linux) indique les accs en dehors des zones de


mmoires alloues par la fonction malloc, dtecte les problmes
d'alignement
on compile avec la librairie electric fence par l'argument -lefence
on peut aussi forcer l'dition de lien au moment de l'excution par la
commande LD_PRELOAD=libefence.so.0.0 ./monprog
L'excution sera arrte en cas de problme
strace : affiche la liste des appels systmes effectus par le programme
et donc de suivre son droulement
ltrace : affiche les appels aux librairies
nm : permet d'afficher la liste des symboles d'un excutable

147

Debug aprs plantage

Sous Linux on peut facilement mettre en place un


mcanisme permettant de dboguer un programme en
cours de test.
ulimit -c : indique 0 si aucun fichier core sera gnr en cas
de crash d'un programme
dans le fichier /etc/profile mettre
ulimit -c unlimited >/dev/null 2>&1
il sera ensuite possible de dboguer le fichier core en le
rejouant

148
Debug aprs plantage

Sous Linux on peut facilement mettre en place un


mcanisme permettant de dboguer un programme en
cours de test.
ulimit -c : indique 0 si aucun fichier core sera gnr en cas
de crash d'un programme
dans le fichier /etc/profile mettre
ulimit -c unlimited >/dev/null 2>&1
il sera ensuite possible de dboguer le fichier core en le
rejouant

149

Debug crois ou distance

gdbserver : on lance gdbserver sur la machine cible avec la


syntaxe suivante :
gdbserver 192.168.0.32:2345 hello
o 192.168.0.32 est l'adresse IP de la machine qui utilisera les
commandes gdb
2345 est le port TCP
hello est le programme que vous dboguez
gdbserver peut tre galement appel via une ligne srie
Sur le poste de travail du dbogueur (ici d'adresse
192.168.0.32) on lance gdb et on peut dboguer distance
Eclipse, codeblock disposent d'un module graphique de
dbugage distance
150
C 99

Le C 99 est une extension du C de Kerninghan et Richie


qui offre les possibilits suivantes :
Les dclarations comme instruction : une dclaration de
variable peut tre fait ailleurs qu'en dbut de bloc. Ceci
implique que les tableaux peuvent tre dimensionns avec
un variable.
Les commentaires // : si les commentaires /* */ sont toujours
accepts on peut utiliser les commentaires ligne par ligne //
qui commentent le reste de la ligne
Les const :le mot cl const permet d'indiquer qu'une fonction
ne va pas modifier un paramtre void affiche( const Objet x)
Fonctions Inline
151

Fonctions inline

Plac devant la dclaration d'une fonction, inline demande au compilateurde


recopier le code de la fonction l'emplacement de l'appel Si la fonction est
grosse ou si elle est appele souvent, le programme devient plus gros, puisque
la fonction est rcrite chaque fois qu'elle est appele. En revanche, il devient
nettement plus rapide, puisque les mcanismes d'appel de fonctions, de
passage des paramtres et de la valeur de retour sont ainsi vits.
Cependant, il faut se mfier. Le mot cl inline est une indication au compilateur,
mais celui ci peut de pas effectuer cet directive.
De plus, il faut connatre les restrictions des fonctions inline :
elles ne peuvent pas tre rcursives ;
elles ne sont pas instancies, donc on ne peut pas faire de pointeur sur une fonction
inline.
il faut que ces fonctions soient dclares avant leur appel dans un fichier header
Syntaxe : inline type mafunction ( paramtres)

152
C++

Prsentation

153

C++

Le C++ peut tre considr espaces de nom et


comme une adjonction de oprateur ::
certaines fonctionnalits au les classes et ce qui en
C99 dcoule
(hritage,fonctions
oprateur new et delete
membres, constructeurs
type de donnes bool destructeurs)
introduit Surcharge des oprateurs
les rfrences les templates
trigraphes
la gestion des exceptions
les paramtres par dfaut
dans les fonctions
fonctions lambda
surcharge des fonctions
154
Mise en uvre C++

Les fichiers classe restent d'extension h, ce sont eux qui


contiennent les dclarations de classes
en gnral on appelle les programmes sources cpp
pour compiler on appelle plus le programme gcc mais g++
avec les mmes paramtres que pour gcc
g++ programme.cpp
g++ -o programme programme.cpp

155

Utilisation de librairies C

Dans les enttes des dlcarations faire


#ifdef __cplusplus
extern "C" {
#endif

char* maFonctionC_1 (void);


void maFunctionC2 (char *param1);
#ifdef __cplusplus
}
#endif

156
Vocabulaire

classe : c'est pour le moment une structure laquelle on


va ajouter des fonctions propres cette structure
mthodes : ce sont les noms de ces fonctions propres
ces structures ou ces classes
champs ou attributs ce sont les diffrents enregistrements
de cette structure ou de cette classe
dclaration : consiste dclarer dans un fichier header (.h)
les appels des mthodes et des champs
dfinition : consiste dfinir la fonction en C++

157

New Delete

T *p=(T*) malloc(sizeof(T)) ;
est remplac par
T *p = new T ;
Pour les tableau on ajoute la dimension
double *table= new double[dim]
int *tab= new int[10] ;
dim peut tre une expression quelconque et pas seulement une constante comme en C.
dans les tableaux deux dimensions seule la premire dimension peut tre une expression,
les autres doivent tre des constantes

delete p ; dtruit l'objet non utile


Exemple : int (*matrice)[3] = new int [3][3] ;
Attention pas de :
int **matrice = new int [3][3]; // incorrect
int matrice [][] = new int [3][3]; // incorrect
int table[] = new int[10]; // incorrect
158
#include

En C++ les include se font sans .h pour les classes


#include <iostream>
Par contre pour les includes de classe locaux
#include "string.h"
Pour les include de fichier h du c
#include <stdlib.h>

159

Boolen Commentaires Trigraphes

bool Trigraphes : certains


peut valoir true ou false
caractres inaccessibles
sur un environnements
exemple bool fini; peuvent tre accds par
Taille des objets des remplacements de
identiques integer trois caractres
commenant par ??
??= : # ??/ : \ ??' : ^
??( : [ etc ...

160
Dclaration de variables

On utilise souvent la On peut utiliser la syntaxe


mthode connue en C : propre au langage C++ :
type nom = valeur ; type nom(valeur) ;
Par exemple : Par exemple :
int i = 2 ; char lettre('a') ;
int *p =&i ; bool fini(false) ;
double pi=3.14 ; int i(2) ;
double pi(3.1415) ;
int u(2),v(3) ;

161

Espace de nom

Les espaces de nom ont t introduits pour permettre de faire des


regroupements logiques et rsoudre les collisions de noms
Utilisation d'un espace de nom :
using namespace std; // ne pas mettre dans le fichier entte
vite d'crire std::cout mais juste cout
cration d'un espace de nom :
namespace identifiant{
class {
...
};
} // pas de ; !!
Alias
namespace autre = identifiant
162
Dclaration des Strings

#include <string>
string nom("Albert Dupont") ;
string nom("Einstein"), prenom("Albert") ;

163

Les tableaux dynamiques

#include <vector>
vector <type> nom (taille) ;
initialisation :
vector <type> nom (taille,valeur) ;
Exemple :
vector <int> tableau(5) ; tableau[2] etc
vector <int> tableau(5,0) ;
vector<string> listeNoms(12, "Sans nom");
Modification de taille :
nom.push_back(valeur) ;
tableau.push_back(2) ; => on ajoute un lment initialis 2
tableau.pop_back(1) ; => on enlve 1 lment
tabeau.size() => taille courante du tableau

164
Mutable

Ce mot cl ne sert que pour les membres des structures.


Il permet de passer outre la constance ventuelle d'une
structure pour ce membre. Ainsi, un champ de structure
dclar mutable peut tre modifi mme si la structure est
dclare const.

166

Rfrences

Dfinition :
la rfrence est une faon de renommer un objet X& est une rfrence
vers l'objet
Exemple : double & ref = compteur ;
Une rfrence doit obligatoirement tre initialise au moment de sa
dclaration
ce mcanisme est utilis pour permettre le passage d'arguments de
fonction par rfrence
ainsi void incremente ( int *i )
peut s'crire void incremente (int &i)
si on fait prcder la rfrence par const on est sr que le paramtre ne
sera pas modifi et qu'en plus il n'y aura pas de recopie de l'argument
void incremente ( const int &i)
l'appel se fait juste par incremente (i) et surtout pas incrmente (*i) ;
167
Entres sorties simplifies

#include <iostream>
using namespace std ;
lecture d'un entier
cin >> i ;
Affichage d'un entier et du suivant
cout << i << i+1 ;
affichage d'une fin de ligne
cout << endl ;
affichage d'une chane de caractres
cout << chaine << endl ;
une fonction cerr permet d'envoyer les messages sur la sortie d'erreurs
remarque en omettant using namespace std ; on doit adopter la syntaxe :
std::cout<<chaine<<std::end ;

168

Accs au fichiers

#include <fstream>
using namespace std;
ofstream flux("fichier.txt"); // ouverture en criture
ofstream monFlux(" fichier", ios::app); // criture en fin
ifstream flux("fichier") ; // ouverture en lecture
ostream f
flux <<"entier :"<<i<<endl
on peut utiliser getc() etc ..
critre avec >>
fermeture avec flux.close() ;
consulter le fichier fstream.h
169
Paramtres par dfaut des fonctions

On peut spcifier des paramtres par dfaut pour les


fonctions avec la syntaxe suivante :
type mafonction( type1 t1, type2 t2, type3 t3=val1, type4
t4=val4)
Les affectations doivent tre effectus sur les derniers
arguments
l'appel de la fonction pourra se faire sous l'une des formes :
mafonction( t1,t2,t3,t4)
mafonction (t1,t2,t3)
ma fonction (t1,t2)
Dans les deux derniers cas t4 prendra la valeur par dfaut

170

Surcharge de fonctions

Si en C on ne peut dfinir plusieurs fonctions qui portent le mme nom, en C+


+, cette interdiction est leve, moyennant quelques prcautions. Le compilateur
peut diffrencier deux fonctions en regardant le type des paramtres qu'elle
reoit. La liste de ces types s'appelle la signature de la fonction. En revanche, le
type du rsultat de la fonction ne permet pas de l'identifier, car le rsultat peut
ne pas tre utilis ou peut tre converti en une valeur d'un autre type avant
d'tre utilis aprs l'appel de cette fonction.
float test(int i, int j) return (float) i+j;}
float test(float i, float j){return i*j;}
il ne faut pas qu'une fonction surcharge provoque une ambigut par rapport
une fonction avec paramtre par dfaut
dfinition : les fonctions surcharges ont obligatoirement une signature
diffrente. La signature est la combinaisons des paramtres passs.

171
Limites de la surcharge

Une mme classe ne peut pas redfinir une fonction avec le mme nom d'une
fonction existante si :
elles ne diffrent que par leur type retour ;
elles ont les mmes arguments, le mme type retour mais l'une d'elles est
statique ;
elles ont les mmes arguments, le mme type retour, la mme constance mais
l'une d'elles est virtuelle (ou virtuelle pure) et l'autre normale ;
elles ont les mmes arguments, le mme type retour, la mme constance mais
l'une d'elles est virtuelle et l'autre virtuelle pure ;
un argument ne diffre qu' cause d'un typedef ;
elles ne diffrent que par un const non significatif sur le type d'un argument.
elles ne diffrent que par les valeurs par dfaut de leur(s) argument(s).

172

Exceptions : principe

Une exception est l'interruption de l'excution du programme la


suite d'un vnement particulier
Les exceptions permettent une gestion simplifie des erreurs,
parce qu'elles en reportent le traitement. Le code peut alors tre
crit sans se soucier des cas particuliers, ce qui le simplifie
grandement. Les cas particuliers sont traits dans les
gestionnaires d'exception.
En gnral, une fonction qui dtecte une erreur d'excution ne
peut pas se terminer normalement. Comme son traitement n'a
pas pu se drouler normalement, il est probable que la fonction
qui l'a appele considre elle aussi qu'une erreur a eu lieu et
termine son excution. L'erreur remonte ainsi la liste des
appelants de la fonction qui a gnr l'erreur.

173
C++

Les classes

174

Dclarations de classes

Dans un fichier h (par convention) on dclare


struct Nom
{
[type champs;
[type champs;
[]]]

[mthode;
[mthode;
[]]]
}; // ne pas oublier le ;
les mthodes sont des fonctions propres cette classe
un objet correspondant une classe est une instance de la
classe
175
Exemple de dclaration de classe

struct client
{
char Nom[21], Prenom[21]; // Dfinit le client.
unsigned int Date_Entree; // Date d'entre du client
int Solde ;
bool dans_le_rouge(void {return (Solde<0);
}
bool bon_client(void)
{
return (Date_Entree<1993); // Date limite : 1993.
}
};

176

Conventions

En gnral on dclare les classes dans un ficher header


Dans le fichier string.h
class String{
variable ;
type fonction( parametres) ;
};
NB : on peut dfinir les prototypes de fonction en omettant les nom des
arguments :
int carre(int i) ;
int carret(int) ;
Dans un fichier string.cpp on dfinit les fonctions
#include "string.h"
type String::fonction ( parametres)
177
Utilisation

struct class
struct mere{ class mere{
int fonction(int) ;
int i ;
private:
public :
int i ; int fonction(int) ;
} }
int mere::fonction(int j) int mere::fonction(int j)
{
{
i=2 ;
i=2 ;
return ( 2*i*j) ;
return ( 2*i*j) ;
} }
int main() int main()
{
{
// en C++ sans struct
mere m ; mere m ;
int i= m.fonction(2) ; int i= m.fonction(2) ;
} }
178

Encapsulation des donnes

dans une dclaration de classe on peut dfinir des sections


encadres par les mot cls :
public:
toutes les mthodes ou variables seront accessibles depuis
l'extrieur de la classe, c'est dire depuis les fonctions appelant la
classe
private:
les mthodes ou variables ne seront accessibles qu' l'intrieur de la
classe, c'est dire pour des mthodes dfinies dans la classe
protected :
les mthodes ou variables ne seront accessibles que pour les sous
classes de la classe qu'on appelle classes drives

179
Exemple

struct client {
public:
char nom[21] ;
char prenom[21] ;
private :
bool bonclient() ;
bool mauvaisclient()
};
par dfaut les classes struct voient tous leurs lments publics
Si on veut que tous les lments soient par dfaut private on remplace le
mot struct par class (c'est souvent l'appellation par dfaut)
Dfaut veut dire que pour struct on n'est pas oblig de commencer par
public et pour class on n'est pas oblig de commencer par private

180

Utilisation et this

Pour utiliser une classe ou une structure dfinie on fait


comme avec une structure en C (sans le mot struct) :
MaClasse m ; m.fonction
MClasse *m = new MaClasse ; m->fonction() ;
MClasse *m = new MaClasse() ; m->fonction() ;
on ne peut bien sr pas appeler que des mthodes ou
d'attributs public (voir un peu plus loin)
This
l'intrieur d'une classe this dsigne un pointeur sur la classe
courante, il sert principalement passer en argument de
fonction un pointeur sur la classe courante
Pas de this dans le main() qui n'est pas une classe
181
Deux classes qui font rfrence l'une l'autre

class B ; // ceci est une dclaration anticipe


class A{
B *ptr ;
...
};
class A ;
class B {
A *ptr ;
...
};

182

Liste d'initialisation d'attributs

Une classe dclare se remplace par la notation


class A {
int Id ; A::A() : Id(0),
char * name ; name("coucou") ;
A() ; // constucteur en d'autres termes
~A() ;//destructeur l'initialisation des attributs
} se fait suivant une syntaxe
constructeur dfini analogue celle d'un
A::A() d'une fonction dont
{ l'argument serait la valeur
ld=0 ; et le nom l'attribut
name="coucou" ;
}
183
Attributs statiques

un attribut peut tre dclar statique


static int compteur ;
L encore l'attribut n'est pas accd dans la mthode this, c'est
dire qu'il appartient la classe mais pas l'objet
Par contre la classe peut accder cet attribut (par un setter ou
un getter)
On peut l'initialiser dans l'espace global comme suit :
int maclass::compteur = 5 ;
ne pas oublier le type
le mettre une seule fois surtout pas dans le main mais dans le fichier
cpp correspondant la classe
il se comporte donc comme une variable globale
185

Utilisation de ::

On voit parfois des appels de classe sous la forme :


#include <classe>
(1) classe::fonction( ...) ;
(2) classe::Symbole
(1) : ne peut s'effectuer que si la fonction est statique
(2) : fonctionne pour les numrations publique(*)
Ne fonctionne pas avec les attributs
(*) enum nom{val1,val2,val3} ;

186
Exercice 16

Crer une classe String qui contient deux mthodes


publiques :
l'une d'entre elle met les caractres de en majuscule
l'autre en minuscule
Appeler dans un programme main.cpp les deux mthodes
sur une chane de caractres donne

187

Constructeur de classe

Le constructeur est une mthode particulire appele la


cration d'un objet. Toute classe a un constructeur par
dfaut, fourni par le compilateur
on le redfinit gnralement car le constructeur par dfaut
ne fait rien
Le constructeur porte le mme nom que la classe et ne doit
avoir aucun type
ils peuvent avoir des paramtres et donc tre surchargs, il
ne peut tre virtuel ( nous verrons ce qu'est une mthode
virtuelle plus tard)
Nous verrons plus loin un autre type de constructeur appell
constructeur de copie
188
Destructeur

Le destructeur est une mthode particulire appele la


destruction d'un objet. Toute classe a un constructeur par
dfaut, fourni par le compilateur
on le redfinit gnralement
Le destructeur porte le mme nom que la classe prcd
du symbole ~
il ne doit avoir aucun type et il est unique sans argument et
ne peut par consquent tre surcharg
un lment dynamique ( Type * obj) est dtruit une fois
arriv la fin du bloc dans lequel il a t dclar

189

Exemple constructeur et destructeur

Dans un fichier h
class machin {
machin () ;
~machin() ;
};
Dans un fichier cpp
machin::machin(){
du code d'initialisation de la classe
}
machin::~machin(){
du code gnralement de libration de la mmoire dynamique
}
190
C++

Hritage drivation

192

Hritage / drivation

L'hritage permet de donner une classe descendantes toutes les caractristiques


d'une classe
la dclaration se fait comme suit :
class mere {
};
class fille : public|protected|private mere {
};
les donnes prives d'une classe hrite publique sont inaccessibles, les donnes
publiques sont publiques, les donnes protected sont protected.
si la classe est hrite protected les donnes publiques et protected seront protected
si la classe est hrite private les donnes public ou protected seront private
Par dfaut les classe seront hrites private et les struct public (c'est dire si on ne
met pas de quantificateur)
une classe fille est dite drive d'une classe mre

193
Exemple fondamental

class mere {
public :
int i ;
// la classe accde ses donnes class fille3: private mere{
mere(){ i=0; j=0; k=0; } public:
private : fille3() {k=3;} /// n'accde pas pas i ni j
int j; };
protected :
int k ;
}; int main()
class fille1 : public mere{ {
public: mere m;
// la classe accde i et k // de l'extrieur on accde uniquement la //
fille1(){ i=1; k=1; } // fille n'accde pas j donne publique
}; m.i ;
class fille2 : protected mere { fille1 f1;
public : // on n'accde la donne publique
// la classe accde i et k f1.j ; // accde j
fille2() {i=2 ;k=2 ; } /// n'accde pas j // aucune des donnes n'est publique
}; fille2 f2 ;
class fille21 : public fille2 { fille21 f21 ;
public : fille3 f3 ;
fille21() {i=21 ;k=21 ; } /// n'accde pas j return(1);
}; }
194

Rsum hritage

Modificateur d'accs visible dans la classe fille visibilit depuis l'extrieur


private non non
protected oui non
public oui oui

Classe mre classe fille public classe fille protected classe fille private
private non visible non visible non visible
protected visible protected visible protected visible private
public visible public visible protected visible private

195
Intrt des limiteurs private, public et protected

Une classe publique laissera l'accs toutes ses mthodes et


attributs public quand on instancie un objet :
mere a ; a.methodepublique() ;
a ne pourra pas appeler les mthodes prives ni les protected
Par contre si on prend la classe fille de mere on pourra utiliser
les mthodes prives mais galement les mthodes protected
fille a ; a.methodepublique() ; a.methodeprotected() ;
a ne pourra pas appeler les mthodes prives
On comprend que protected laisse le loisir de driver la classe
mre pour accder ses attributs et mthodes
Les donnes privs sont utiles que pour les concepteurs de la
classe.
196

Vocabulaire geek : getter setter

class A getWindowId est appel un


getter
{
private: setWindowId est appel un
setter.
int m_windowId ;
public : les setters et les getters
sont conventionnellement
int getwindowId(){ return prsents dans le fichier de
(m_windowId ) ;}
dclaration ;
void setwindowid(int i)
{ m_windowId=i;} ils sont utiles pour la
}; traabilit du code pour
encadrer l'accs une
variable prive
197
Vocabulaire savant: accesseur manipulateur

Acesseur : ce sont des Manipulateurs: ce sont


fonctions membres qui ne des fonctions membres qui
modifient pas l'tat de peuvent modifier l'tat de
l'objet. Le C++ permet de l'objet. Dans ce cas, on
dclarer une fonction omet le const dans la
membre const, indiquant au dclaration. Si une fonction
compilateur qu'elle ne membre dclare non
modifie pas l'tat de l'objet. const ne modifie pas l'tat
Si l'implmentation de la de l'objet, il y a lieu de se
fonction const tente de demander s'il ne faudrait
modifier une variable
pas la dclarer const.
membre de la classe, le
compilateur signalera une
erreur
198

Constructeur de classe drive

Lorsqu'on appelle le constructeur d'une classe ce


constructeur commence par appeler les constructeurs de
chacun de ses parents avant de commencer son propre
code
pour une instanciation de petite fille, le constructeur de petite
fille commencera par appeler le constructeur de fille qui
appellera le constructeur de mere
Le mme principe est appliqu pour les destructeurs, ds
qu'un destructeur est appliqu il applique son code ensuite
le destructeur de la classe mre est appel et ainsi de
suite

199
Exercice 17

instancier une classe petite fille pour tudier l'ordre


d'excution de chacun de constructeurs destructeurs
parents. On mettra en vidence les procds en affichant
un message explicite dans chacun de constructeurs
destructeurs des 3 gnrations.

200

Hritage avec mme attribut

si la classe mre comprend un ou des attributs public protected ou private


et que sa classe fille comprend les mmes attributs spcifis ceux-ci sont
surchargs
Exemple :
class mere {
mere(){i=1;}
private:
int i;
int j;
};
class fille {
public:
int i; // i sera initialis avec une valeur quelconque mais avec 1 que par le
fruit du hasard
int k;
};
201
Hritage avec mme mthode : masquage /
dmasquage

On considre une classe fille ayant la mme mthode que la


classe mre avec la mme signature et le mme paramtre
de retour : masquage
mere::message() ;
fille::message() ; // cette mthode masque celle de la mre,
comme pour les attributs
Mais on peut dans la fonction fille utiliser le stratagme
suivant que l'on nomme dmasquage:
fille :: message()
{
mere::message() ; // car fille est drive de mre
message() ; // ici c'est la mthode fille qui est utilise
}
202

Drivation de type

Soit mere avec une mthode priv methodemere() ;


soit fille drive de mere avec une mthode propre la
fille :
fille:methodefille() ;
Il se trouve que ceci fonctionne trs bien
mere.methodefille() ;
Par contre ceci ne fonctionne pas :
fille.methodemere() ;

203
Explication drivation de type

Mre

En passant par objet mre on ne


pourra accder qu'aux lments de
l'objet fille hrits

Fille

lments hrits de mre


lments propres fille

204

Hritage multiple

Une classe peut hriter de deux parents, la dclaration des


parents sera spare par une virgule
Exemple :
class cercle : public Emplacement, private figure
{
}
une mthode ou une variable peut tre redfinie dans une classe
fille
si on veut accder une mthode redfinie d'une classe mre on
la nomme mere::methode()
ceci est valable galement en cas de dfinitions identiques dans
plusieurs classes dont une classe drive
205
Exemple ambigut classe multiple

class mere1 {
public:
mere1(){i=1;}
int i ; int k;
};
class mere2 {
public:
mere2(){i=2;}
int i;
int j;
};
class fils :public mere1, public mere2 {
};
int main ()
{
fils f;
std ::cout<<f.mere2::i<<std ::endl; // Sans la classification mere2 :: on a ambigut
return 2;
}

206

Polymorphisme : prsentation

class mere{
public :
void methode() ;
}
class fille : public mere{
public :
void methode() ; // masquage de la mthode
}
void fonction ( mere m)
{
m.methode () ;
}
main()
{
mere m ;
fonction(m) ;
fille f ;
fonction(f) ; // c'est methode qui sera appele !! (rsolution statique)
}
207
Polymorphisme : mthode virtuelle

Pour rendre une mthode polymorphe il faut :


dclarer cette mthode virtuelle dans la classe mre l'aide
du modificateur virtual devant son prototype (pas dans la
dfinition)
la fonction doit tre appele par un pointeur ou une
rfrence
Quand on dfinit une telle mthode virtuelle, la classe
correspondante doit possder un destructeur virtuel
sinon le destructeur appel serait celui de la classe mre
alors que le constructeur tait celui de la classe fille

208

Exercice 18

Reproduire un cas de polyporphisme


l'aide d'un pointeur dans l'appel de la mthode
l'aide d'une rfrence dans l'appel de la mthode
mettre en vidence que sans pointeur ou rfrence le
polymorphisme ne fonctionne pas

209
Cas des constructeurs et destructeurs

Un constructeur ne peut tre virtuel puisque la


construction des objets se fait en appelant les
constructeurs de fille en mre
Qui plus est un constructeur ne peut pas appeler de
mthode virtuelle
Par contre l'appel du destructeur d'une instance de la
classe fille va appeler le destructeur de la classe mre, ce
qui peut poser des problmes. Ainsi pour les classe
disposant de mthodes virtuelles on dclare le destructeur
virtuel.
Les fonctions statiques ne peuvent bien sr pas tre
virtuelles
210

Fonctions virtuelles pure

Une fonction virtuelle pure est une fonction virtuelle


laquelle on ajoute =0 lors de sa dclaration.
Cette fonction n'est donc pas dfinie
Par contre elle peut tre redfinie dans une classe drive
On peut la redfinir virtuelle ou pas, de toutes les faons
elle sera virtuelle dans la classe drive.
Elle sert galement ne rien dfinir dans les cas o dans
la classe mre elle n'a pas de sens :
exemple : nombrederoue () a un sens pour les motos, pour
les voitures, pour les camions mais pas pour l'objet vhicule

211
Classes abstraites

Une classe qui possde au moins une mthode virtuelle pure


est dite classe abstraite
On ne peut instancier d'objet d'une classe abstraite ( en effet
comment implmenter le nombre de roue pour un objet ?)
Par contre on peut dfinir un pointeur sur une classe
abstraite
En rsum :
Une mthode virtuelle peut tre redfinie dans une classe fille.
Une mthode virtuelle pure doit tre redfinie dans une classe
fille.

212

Classes amies

L'amiti consiste donner l'accs complet aux lments d'une


classes qu'ils soient privs, protgs ou publics
si f est une fonction amie d'une classe A elle pourra en modifier tous
les attributs (de private public)
Exemple 8-8. Fonctions amie
class A{
int a; // Une donne prive.
friend void ecrit_a(int i); // Une fonction amie.
};
A essai;
void ecrit_a(int i){
essai.a=i; // Initialise a.
return;
}
213
Classes amies

Pour rendre toutes les mthodes d'une classe amies d'une autre classe,
il suffit de dclarer la classe complte comme tant amie.
class Hote
{
friend class Amie; // Toutes les mthodes de Amie sont amies.
int i; // Donne prive de la classe Hote.
public:
Hote(void) {
i=0;
}
};
Attention : l'amiti n'est pas transitive et les classes drives de classes
amies ne sont pas amies.

214

Transtypage de constructeur

on peut effectuer des conversions de type explicite ou implicite. Les


conversions explicites sont des casts.
Les conversions implicites d'un type classe vers un autre type sont
admises que si la classe possde un construction comprenant comme
seul et unique argument un argument du type transcrit.
Exemple de conversion implicite :
class Entier
int i;
public:
Entier(int j ) {
i=j;
return ;}
};
int j=2;
Entier e2=j ;
215
Forage de transtypage explicite

Si, pour une raison quelconque, le transtypage implicite


n'est pas souhaitable, on peut forcer le compilateur
n'accepter que les conversions explicites ( l'aide de
transtypage). Pour cela, il suffit de placer le mot cl explicit
avant la dclaration du constructeur
Exemple :
explicit chaine(unsigned int);
Le mot explicit n'interdit pas le transtypage explicite

216

Objet membre

On dsigne par objet membre, un objet qui est attribut


d'une classe
class B {
private:
A objetMembre;
};
Lors de la construction de B va automatiquement appeler
le constructeur de A
De mme le destructeur de B appellera le destructeur de A

217
Surcharge des oprateurs

les oprateurs comme les mthodes peuvent tre


surchargs.
on ne peut toutefois surcharger les oprateurs
suivants : :: . * ?: sizeof typeid static_cast dynamic_cast
const_cast reinterpret_cast
Il existe deux surcharges :
la surcharge interne
la surcharge externe

218

Surcharge interne

Oprateurs internes : ces oprateurs sont dclars


l'intrieur de la classe et modifient l'objet sur lequel ils
oprent. Le pointeur this est pass en paramtre. Ils ne
prennent qu'un paramtre
type operatorOp(paramtres)
par exemple :
dclaration : String &operator+= (const String &)
dfinition : String::&String::operator+=(const String &a)
{ ..
return (*this) ;
}
utilisation a += b ou a.operator+=(b)

219
Surcharge des oprateurs externes

Dans ce cas le pointeur this n'est pas pass en paramtre car la


surcharge s'opre sur plusieurs oprateurs
L'oprateur est surcharg l'extrieur de la classe
Syntaxe : type operatorOp(oprandes)
Exemple :
Type operator+(const type &c1, const type &c2)
dclaration : String &operator+(const String &,const String &)
dfinition : String::&String::operator+=(const String &a, const String &b)
{ ..
result = c1
return ( result+=c2}
utilisation a =b+c

220

Exercice 19

crire une classe qui gre des heures sous sous la forme
heures, minutes, secondes
On fournira une fonction qui indique l'heure sous forme
heures, minutes et secondes partir d'une chane
"hh:mm:ss", si aucune chane n'est entre le compteur
sera initialis zro
On fournira deux oprateurs permettant d'ajouter deux
heures (dure) et de retrancher deux heures (temps
pass)

221
C++

Librairies SL et STL

222

La librairie SL

Elle a dj t prsente en partie et comprend


les flux : cin, cout, cerr
les hritages du C : mme fichier sans l'extension .h
La STL ( hritage de l'ADA )
La documentation de base comprend 800 pages indigestes
en anglais mais on trouve des sites pdagogiques :
http://www.cplusplus.com
http://stdcxx.apache.org/doc/stdlibref/2.html
http://www.sgi.com/tech/stl/table_of_contents.html
http://www.dinkumware.com/manuals/#Standard%20C%2B%2B%20Lib

223
SL : hritage du C

cmath : pow (a,b) (puissance), sqtr (q) (racine), cos(x),


ceil(a) (valeur entire au dessus), floor(valeur entire au
dessus)
cctype : isalpha (alphanumrique ?), isdigit (chiffre?),
islower(?), isupper(?), toupper, tolower, etc..
ctime : time(0) temps coul depuis 01/01/1970
cstdlib : rand (random)
toutes ses librairies sont explorables via l'diteur de votre
environnement

224

STL

Stockage : tous les conteneurs peuvent contenirs des objets htrognes


vector : vector <int> tab(6) ; tab[i] ; push_back ; pop_back
deque(tableaux double queue) : idem + push_front, prop_front
list : list <double> a ;
stack : stack <int> l ; pop, push ( LIFO)
queue : idem mais FIFO
priority_queue : LIFO mais ordonnes
conteneurs associatifs :
set : ensemble de chanes : set <string> a ;
multiset : idem set avec plusieurs cls identiques
map : map<string, int> a ; a["valeur"] ;
multimap : idem multimap avec plusieurs cls identiques

225
Mthodes communes

Pour chacune de ces classes on retrouve des mthodes


communes :
clear() : remise zro ;
empty() : true si vide
a.swap(b) : change des contenus
les itrateurs :
begin() le premier
end() le dernier
deque <int>::iterator it ;
insert()
it ++ ; it +1 etc ..

226

C++

Notions avances

227
Les exceptions

Dans le corps une fonction on est amen faire des tests


(division par zro, fichier non existant,etc) et de renvoyer suivant
l'inspiration :
une valeur nulle ;
un boolen en dernier argument pour indiquer que la fonction a
rencontr un problme ;
un message d'erreur sur la console.
Aucune de ces solutions n'est rellement satisfaisante, compar
au mcanisme offert par les exceptions :
on fait un test dans le code : try { ... }
on lance une exception en cas de problme throw (... )
on attrape l'exception ailleurs dans le code catch(..) {...}

228

Exception : try

Structure du try
// ici on met du code sans test particulier
try
{
// ici on met du code qui peut gnrer une exception
throw ...
}
on peut mettre un bloc try dans un bloc try

229
Exceptions : throw expression

Lancer une exception consiste retourner une erreur sous


la forme d'une valeur (message, code, objet exception)
dont le type peut tre quelconque (int, char*,
MyExceptionClass, ...).
Le lancement se fait par l'instruction
throw 0 ;
throw 123 ;
throw string("grosse erreur") ;

230

Exception : catch

Pour attraper une exception, il faut qu'un bloc encadre l'instruction


Tout bloc try doit tre suivi d'un bloc catch
le catch prend comme argument une rfrence constante afin d'viter la
copie et de conserver le polymorphisme de l'objet reu
l'excution reprendra aprs le bloc catch une fois l'exception attrape
Il faut un catch par type d'objet lanc
try {
code lanant une exception par throw()
}
catch (int code) {
cerr<<"Exception"<<code<<endl
}
catch (string const &e) {
}
231
Exception : exemple

int division(int a,int b)


{
if (b==0) throw 0; // division par zro;
else return a/b;
}
void main()
{
try{
cout << "1/0 = " << division(1,0) << endl;
}
catch(int code)
{
cerr << "Exception " << code << endl;
}
catch(...)
{
cerr<<"Execption inconnue "<<endl ;
}
}
232

Templates

Un template est un patron dfinissant un modle de fonction ou


de classe dont certaines parties sont des paramtres
le patron est trs utile pour gnraliser un traitement
plusieurs types de donnes
pour les patrons de fonction on peut rsumer le concept
donner en paramtre d'une fonction un type de donnes
le patron va tre compil pour chaque instance de type
demand donc c'est un processus qui est long la compilation
parfois le programmeurs incluent les patrons dans des fichiers
d'extension tcc d'autre dans des fichiers header

233
Templates convention

le mot cl typename dfinit que le type qui suit est abstrait


le mot cl template indique que la structure, la classe ou
la fonction qui suit le mot cl prend des paramtres
template
on peut dfinir des templates
pour les fonctions
pour les classes

234

Template fonction

Exemple : dclaration
template <class T>
T Min(T x, T y){
return x<y ? x : y;
}
Utilisation par instanciation implicite
int i = Min (2 ,4) ;// comme 2 et 3 sont entiers T est considr comme entier
en cas d'ambiguit par exemple min (2 ,3.4) faire int i = Min<int>(2,3.4)
Utilisation par instanciation explicite
template int Min(int, int) ;
i = Min(2,3) ;

235
Template fonction

Exemple : dclaration
template <class T>
T Min(T x, T y){
return x<y ? x : y;
}
Utilisation par instanciation implicite
int i = Min (2 ,4) ;// comme 2 et 3 sont entiers T est considr comme entier
en cas d'ambiguit par exemple min (2 ,3.4) faire int i = Min<int>(2,3.4)
Utilisation par instanciation explicite
template int Min(int, int) ;
i = Min(2,3) ;

236

Template classe

Dfinition :
template <paramtres_template> class|struct|union nom;

Exemple :
template <class T> class Chaine
{
public:
// Fonction membre template dfinie
// l'extrieur de la classe template :
template<class T2> int compare(const T2 &) ;
// Fonction membre template dfinie
// l'intrieur de la classe template :
template<class T2>
Chaine(const Chaine<T2> &s) {
//
}
};
Instanciation
template<class T = char> class Chaine;
template Chaine<>; // Instanciation explicite de Chaine<char>.
237

You might also like