Académique Documents
Professionnel Documents
Culture Documents
1
UVT - N2TR C++&Java
Toute tentative de modification du contenu d’une constante génère une erreur à la compilation :
seules les opérations de lecture sont autorisées. On est donc assuré à la déclaration d’une telle entité
qu’aucune modification de valeur ne sera permise. Cette restriction entraîne qu’il n’est pas possible
de définir un pointeur « normal » sur une constante : le contenu de la constante pourrait alors être
modifié via le pointeur. On est alors obligé de définir un pointeur sur constante. De même, si on
souhaite que la valeur du pointeur ne soit pas modifiée au cours du programme, il faut définir un
pointeur constant sur constante.
2
UVT - N2TR C++&Java
Cette possibilité autorise une gestion plus précise de la mémoire, mais peut nuire à la structuration
des programmes.
3
UVT - N2TR C++&Java
4
UVT - N2TR C++&Java
5
UVT - N2TR C++&Java
Remarques :
6
UVT - N2TR C++&Java
• Les arguments, dont la valeur est fournie par défaut, doivent OBLIGATOIREMENT se
situer en fin de liste. Autrement dit, dès qu’un argument reçoit une valeur par défaut, il faut
que tous les arguments qui le suivent le soient également.
• Les valeurs par défaut doivent être mentionnées uniquement dans la déclaration d’une
fonction.
7
UVT - N2TR C++&Java
L’opérateur new alloue de l’espace mémoire à des objets de type élémentaire ou étendu.
N : est une expression donnant le nombre d’éléments du tableau (N peut être une constante
ou une variable)
• Pour allouer de la mémoire à un tableau à plusieurs dimensions : ptr = new type [C1]
[C2] ... [Cn];
8
UVT - N2TR C++&Java
Remarques :
• II peut arriver qu’une tentative d’allocation se solde par un échec (par exemple, lorsqu’il n’y
a pas assez d’espace mémoire libre). Dans ce cas, il ne se produit pas d’erreurs au niveau de
l’exécution du programme, mais l’opérateur new va retourner un pointeur nul, contenant la
valeur NULL (constante représentant une adresse nulle). D’où, il est toujours conseillé de
faire un test après l’allocation
9
UVT - N2TR C++&Java
int i = 3;
i++;
Ceci peut s’écrire, dans un autre style, mais ayant le même résultat :
int i;
i = 3;
i++;
En C il existe une totale équivalence, garantie, entre les deux écritures. L’opérateur = de
l’initialisation est traité de la même façon que celui de l’affectation.
i = 3 affectation
int i = 3 abus de langage, initialisation
Si on considère maintenant le qualificatif static appliqué à une variable locale
void F()
{static int i = 3;
10
UVT - N2TR C++&Java
i++;
}
L’initialisation n’est faite qu’une fois, lors de la déclaration de la variable. Cela illustre qu’il y a
quand même une différence entre une initialisation et une simple affectation.
11
UVT - N2TR C++&Java
Seul le contexte du programme permet de déterminer s’il s’agit de l’une ou l’autre des deux
significations.
a) Le type référence
Le type référence est un type nouveau introduit par C++. C’est un nom alternatif ou un alias pour un
objet. La syntaxe de la déclaration d’une variable référence est la suivante :
Cette déclaration permet de définir une variable NomRef qui est une référence sur la variable
VarAReferencer qui est du type spécifié. VarAReferencer est une variable déclarée au préalable et
pour laquelle NomRef est un alias ou un synonyme.
Une variable de type Référence doit obligatoirement être initialisée lors de sa déclaration (càd,
associée à une variable déjà déclarée).
Ainsi déclarée et initialisée, une variable de type référence se comporte comme un synonyme de la
variable à laquelle elle a été associée --> tout se passe comme si les deux variables représentaient le
même objet en MC : càd que les opérations effectuées sur l’une affecte automatiquement l’autre.
Voici des exemples qui montrent qu’une référence se comporte comme un synonyme de la variable
précisée lors de l’initialisation.
12
UVT - N2TR C++&Java
Remarques
• Les variables références en tant que telles sont très peu utilisées. Elles sont principalement
utilisées dans la spécification des paramètres et dés valeurs de retour d’une fonction.
13
UVT - N2TR C++&Java
En C, comme en C++, un sous-programme ne peut modifier la valeur d’une variable locale passée
en argument de
fonction. Pour
se faire, en C, il
faut passer
l’adresse de la
variable.
14
UVT - N2TR C++&Java
L’exemple illustre la création d’une variable i, par appel de fonction. C’est une variable locale (ou
"privée") de la fonction, que l’on ne peut atteindre autrement que par la fonction (forme
d’encapsulage). La fonction en fournit l’adresse en retour d’appel. On peut alors écrire le code du
main () suivant :
La fonction f () a une fonctionnalité de lvalue et de rvalue si, et seulement si, on utilise la notion de
pointeur. On a donc l’encapsulage (protection des accès directs aux données), même en C "normal".
Mais on doit systématiquement utiliser la notion de pointeur. Par contre, on sait écrire
*f() = *f();
15
UVT - N2TR C++&Java
En C++, la fonction f() en tant que valeur de retour peut devenir une lvalue (l’appel de fonction peut
devenir un récipient, et non plus rester une simple rvalue). On déclare la fonction f() comme
retournant un récipient (retourne une référence sur un objet).
La fonction retourne i, mais celui-ci est commue en une référence. C’est le "mot" f qui est en fait
une référence sur i. Dans le programme appelant, on trouve la notation suivante :
f() = f();
• f () à gauche est une référence sur i (lvalue). On a l’impression de travailler sur l’adresse et
de faire l’équivalent du *f() dans la manipulation des pointeurs.
En C on se fait jeter par le compilateur, avec un message du type " left-value required". En effet,
une affectation exige un récipient en opérande gauche. Or une fonction C est une right-value. Si la
fonction f() retourne un pointeur, adresse d’un récipient, alors on doit écrire en C : *(f()) = 3;
Le retour de la fonction est ambigu. On retourne une valeur. Mais i est aussi un entier, c’est donc
aussi une variable. Si à l’arrivée dans le code de la fonction i vaut 3, on retourne la valeur 4. Mais
on retourne aussi l’endroit où réside cette valeur (son adresse !). On a donc deux informations qui
sont retournées dans le cas d’un retour de fonction défini comme une référence :
• la valeur
• sa localisation
16
UVT - N2TR C++&Java
Lorsqu’on manipule une référence, rien ne la distingue de la variable à laquelle elle correspond, ni
de la valeur que celle-ci contient.
Axiome : toute utilisation d’une référence est totalement équivalente à l’utilisation d’une variable
"normale".
La transparence reste totale lorsqu’on manipule des objets de type composé tels des structures :
Remarque : on peut constater que ce genre de fonction ne marche que pour des objets statiques.
17
UVT - N2TR C++&Java
En rajoutant le mot-clé inline lors de la définition de la fonction, la fonction est considérée comme
inline : chaque appel fait à la fonction sera remplacé par le code source correspondant à la fonction.
On dit que la fonction est expansée à son point d’appel.
Remarques :
ii. Pour bénéficier de cette fonctionnalité, la fonction doit être définie et déclarée inline.
iii. la déclaration inline d’une fonction n’est qu’une recommandation faite au compilateur, qui
peut décider ou non d’effectivement laisser cette fonction inline. En particulier, si le corps
de la fonction est trop important, il y a peu de chances que la fonction reste inline (il y a peu
de gain) cette technique s’avérant rentable uniquement sur les fonctions comportant peu
d’instructions.
18