Hiver 2010 JGA Beaulieu GEF 243B Programmation informatique appliquée Les pointeurs rencontrent les fonctions Pointeurs à pointeurs §9.2 – 9.3
Hiver 2010 JGA Beaulieu
GEF 243BProgrammation informatique
appliquée
Les pointeurs rencontrent les fonctions Pointeurs à pointeurs
§9.2 – 9.3
2Hiver 2010 JGA Beaulieu
Revue
• Comment est-ce que les deux variables suivantes sont représentées en mémoire?char character = 'a' ;char[] string = "a";
• Est-ce que mon ami le compilateur va se pleindre avec ceci? Que va-t-il se passer?:char[] temp = "";char[] text = "Some text";
int i;for (i = 0, strlen(text), i++)temp[i] = text[i];
3Hiver 2010 JGA Beaulieu
Synopsis
• Pointeurs et fonctionsPassage d’un pointeur à une fonctionRetourner un pointeur à partir d’une fonctionSommaire de la communication avec les fonctions
• Pointeurs à pointeurs
• Pointeurs de type voidUtilisationsDéclaration Casting des pointeurs
4Hiver 2010 JGA Beaulieu
Pointeurs rencontrent les fonctions
• Une des plus grandes utilités des pointeurs est de passer des paramètres par adresses aux fonctions
• Comme nous l’avons vue pour les tableaux, il est parfois plus efficace de passer l’information par référence au lieu de par valeur
• Le passage des données par référence n’est pas seulement efficace, mais parfois c’est nécessaire pour que certaines fonctions soient possibles
5Hiver 2010 JGA Beaulieu
Pointeurs rencontrent les fonctions
• Tout comme pour les tableaux, quand vous passez des paramètres par référence, tout changement qui est fait dedans la fonctions est appliqué directement à la variable actuelle
• Une fonction simple qui utilise les pointeurs comme paramètres est la fonction pour échanger deux valeurs entre deux variables
• Une telle fonction peut être utilisée dans un algorithme de triage
6Hiver 2010 JGA Beaulieu
Passé par valeur ne fonctionne pas…
7Hiver 2010 JGA Beaulieu
Passé par référence fonctionne …
8Hiver 2010 JGA Beaulieu
Pointeurs comme paramètres
• Passez des pointeurs seulement si il est nécessaire que vous ayez accès à la variable directement quand vous voulez changer la valeur du paramètre
actuel
• Si vous n’avez pas un besoin de changer la valeur de la variable externe, passer le paramètre actuel par valeurvous allez alors protéger le paramètre actuel contre tout
changement non voulu
9Hiver 2010 JGA Beaulieu
Retourner les pointeurs des fonctions
• Les fonctions ne font pas que d’accepter les pointeurs, elles peuvent aussi les retourner!!!
• Cela peut être utile quand on veut retourner une référence à un des paramètres passés à la fonction
• Le prochain exemple nous montre une fonction qui retourne un pointeur à une des deux variables qui lui ont été passé; au retour, le pointeur pointe à la variable ayant la plus petite valeur Le pointeur (adresse) est ensuite stocké dans une variable pointeur
dans la fonction qui a fait l’appel
10Hiver 2010 JGA Beaulieu
Pointeurs rencontrent les fonctions
11Hiver 2010 JGA Beaulieu
Sommaire de la communication avec fonctions
12Hiver 2010 JGA Beaulieu
Pointeurs à pointeurs
• Donc si un pointeur tient l’adresse d’une autre variable, est-ce qu’il peut contenir l’adresse d’un autre pointeur?
• Oui il le peut. Un pointeur à un pointeur représente deux niveaux
d’indirection
• En fait, il n’y a aucune limite au nombre d’indirections que l’on peut utiliser en CEn pratique, cependant, vous allez rarement passer
deux niveaux d’indirection
13Hiver 2010 JGA Beaulieu
Pointeurs à pointeurs
• Voici comment on déclare un pointeur à un pointeur à intint** p; //un pointeur à un pointeur à un int
• Chaque fois que vous voulez accéder à la valeur pointé par un pointeur à un pointeur, il faut le déréférencer deux fois :
int** p;
int* r;
int a = 0;
r = &a; //r pointe à a
p = &r; //p pointe à r qui pointe à a
**p = 5; //La valeur de a change à 5
14Hiver 2010 JGA Beaulieu
Pointeurs de type void
• Tout comme indiqué lors du dernier cours, C ne permet pas de faire des comparaisons ou de mélanger les types des pointeurs Il y a une exception à cette règle:
• Le pointeur void
• En C le pointeur void est un pointeur générique ou universel qui peut être utilisé là où le type des données auxquelles ont veut pointer n’est pas connu avant la compilation et l’exécution du programme
15Hiver 2010 JGA Beaulieu
Pointeurs de type void
• Nous allons bientôt voir l’allocation dynamique de la mémoire.
• Quand on demande de la mémoire, C nous retourne un pointeur qui pointe vers la mémoire demandée. Ce pointeur est voidParce que la fonction qui nous donne la mémoire
(malloc) n’a aucune idée de quelle type de données on va mettre dedans
• Si nous voulons une fonction générique capable de trier toutes sortes d’information (int, char, float, ou types dérivés), nous pouvons accepter un pointeur void qui pointe à l’information qui doit être triée
16Hiver 2010 JGA Beaulieu
Pointeurs de type void
• Vous déclarez un pointeur à void de cette façon:void* pointerAVoid;
• Parce que le pointeur ne pointe à aucun type de variable, on ne peut pas le déréférencer dans un énoncéint maVar;
maVar = *pointerAVoid; //erreur!
*pointerAVoid = maVar; //erreur!
17Hiver 2010 JGA Beaulieu
Pointeurs de type void - casting
• Nous pouvons utiliser un « cast » avec les types de pointeurs
int* pInt;
char* pChar;
void* pVoid;
…pInt = pChar; //Erreur de compilateur (warning)
pInt = (int *) pVoid; //bon
pChar = (char *) pVoid; //bon
pInt = (int *) pChar; //valide mais pas logique!
18Hiver 2010 JGA Beaulieu
Pointeurs de type void - casting
• Vous devez « caster » une fonction si elle retourne un pointeur à void. Voici un exemple avec la fonction malloc:
//malloc retourne une adresse à un bloc de mémoire
void* malloc(int size); //comme définit en C
int* iPtr;
…
iPtr = (int *)malloc(10 * sizeof(int)); //casting
19Hiver 2010 JGA Beaulieu
Quiz Timechar anotherChar, myChar = 'a';int *pNum;char *pChar, **ppChar;void *pNothing;
void main(void){ ppChar = &pNum; //1. Est-ce légal? pChar = &myChar; //2. Est-ce légal? pNothing = pChar; //3. Est-ce légal? ppChar = &pChar; //4. Est-ce légal? *pChar = 'z'; //5. Est-ce bon? Ca fait quoi? **ppChar = 'y'; //6. Est-ce bon? Ca fait quoi? anotherChar = *pNothing; //7. Est-ce que je peut faire ça?
pChar = pNothing; //8. Est-ce légal?}