GEF 243B Programmation informatique appliquée Pointeurs et adresses §9.1
21-Jan-14 2 JGA Beaulieu Revue Quest-ce quun type dérivé? Pourquoi est-ce que les tableaux sont des types dérivés? Quelles sont les trois caractéristiques dun tableau? Que veut-on dire par passer par valeur et par référence?
21-Jan-14 3 JGA Beaulieu Synopsis Adresses: symbolique, logique et physique Lopérateur dadresse - & Pointeurs Opérateur dindirection * Initialisation des pointeurs Travailler avec les pointeurs et les adresses Types de pointeurs
21-Jan-14 4 JGA Beaulieu Adresses Jusquà maintenant nous avons utilisés les variables pour identifier nos données dans nos programmes On assigne un identificateur (un symbole) à nos variables dans une déclaration, et ensuite nous utilisons ce nom pour manipuler les données Le compilateur utilise ces identificateurs pour résoudre la location symbolique dune variable à une adresse
21-Jan-14 5 JGA Beaulieu Adresses Quand nous avons parlé des tableaux et fonctions, nous avons vue que de passer une variable par référence au lieu de par valeur peut être plus efficace Ceci est due au fait que la fonction peut avoir accès à des données extérieurs et de les modifier directement; sauvant le temps de système pour les appels de fonctions Cet accès direct aux variables a beaucoup plus dutilités
21-Jan-14 6 JGA Beaulieu Adresses Adresses…mais les systèmes dexploitation peuvent charger les programmes où ils le veulent dans la mémoire physique. Pour une exécution, la variable a peut être à ladresse physique 01A4:F4A1 et pour la prochaine exécution la même variable peut être à 34BC:4DA1 Même si nous voulons la puissance de nous servir des adresses, nous ne voulons pas perdre la flexibilité que nous donnes les noms symboliques
21-Jan-14 7 JGA Beaulieu Adresses Et bien vous êtes chanceux, C nous permet de nous servir dadresses symboliques en utilisant ce qui sappel un pointeur. Mais avant daller plus loin, nous allons regarder un modèle de mémoire pour visualiser ce que sont ces genres de mémoires
21-Jan-14 8 JGA Beaulieu Adresses – modèle de mémoire #define stuff … void main() { … int a; … } 0000 Symbolique LogiquePhysique 00FF … Compile et link chargement Environment
21-Jan-14 9 JGA Beaulieu Adresses Le modèle que nous venons de voir peut être simplifié si nous comprenons quà partir de notre programme dans le monde symbolique (le code en C) nous pouvons obtenir une adresse durant lexécution dun programme Les adresses symboliques cachent les complications du système dexploitation et du matériel dadressage Pub: si vous prenez le cours de systèmes dexploitation en 4 ème année, vous allez voir la poussière sous le tapis
21-Jan JGA Beaulieu Opérateur dadresse (&) Alors où est-ce que ma variable crèche? En utilisant lopérateur dadresse (&) en avant dune variable dans le code, nous pouvons obtenir sa location en mémoire Si maVariable dans mon programme est un char alors &maVariable est ladresse logique de ce char Il ne faut pas oublier que cest le hardware qui fait la conversion de logique à physique Donc nous avons la capacité dobtenir une adresse; on veut aussi être capable de stocker et manipuler cette adresse
21-Jan JGA Beaulieu Variables pointeurs En C nous avons des variables qui peuvent stocker des adresses dordinateur; ce sont des variables pointeurs ou pointeurs tout court Donc si jutilise lopérateur & et que jobtiens ladresse dune variable, je peux affecter cette adresse à une variable pointeur Un pointeur est déclaré comme suit: int* pointeurAInt; //pointeur à int char* ptrAChar; //pointeur à char
21-Jan JGA Beaulieu Variables pointeurs Notez la similarité dans la façon de déclarer les pointeurs et les tableaux : int* pointeurAInt; int tableauDeInts[]; Donc les pointeurs sont des types dérivés tout comme les tableaux.
21-Jan JGA Beaulieu Variables pointeurs … void main() { … int a = 145; int* p; // un pointeur … p = &a; //prend ladresse de a //et met la dans le ptr p } Symbolique Mémoire a XX p 46798
21-Jan JGA Beaulieu Variables pointeurs … void main() { … int a = 145; int* p; // un pointeur … p = &a; //prend ladresse de a //et met la dans le ptr p } Symbolique Mémoire a p 46798
21-Jan JGA Beaulieu Variables pointeurs … void main() { … int a = 145; int* p; // un pointeur … p = &a; *p = 99; //indirection } Symbolique Mémoire a p *p
21-Jan JGA Beaulieu Variables pointeurs … void main() { … int a = 145; int b = 0; int* p; // un pointeur … p = &a; *p = 99; //indirection b = *p; //b = valeur de la var //pointée par p }//main Symbolique Mémoire a p b
21-Jan JGA Beaulieu Variables pointeurs - init Un pointeur, comme toutes les autres variables en C, na pas dinitialisation automatique Il contient des déchets Une séquence de bits aléatoires Plus que nimporte quelles autres variables, vous devriez toujours initialiser vos pointeurs explicitement Vous pouvez initialiser vos pointeurs avec une adresse réelle: int a; int* p; p = &a;
21-Jan JGA Beaulieu Variables pointeurs - init Ou utiliser le mot NULL (dans stddef.h ) int* p = NULL; Si votre pointeur a une valeur NULL et que vous le déréférencez, vous allez avoir une erreur dexécution ( run-time ) Les pointeurs ambiguës ou qui sont mal initialisés sont une source majeure derreurs en C Une des choses les plus utiles que vous pouvez faire quand vous travailler avec des pointeurs est de dessiner votre logique de pointeurs
21-Jan JGA Beaulieu Pointeurs - Avantages Les pointeurs nous permettent de passer les adresses de variables en paramètres aux fonctions Ils sont à la base de lallocation dynamique de la mémoire en C Nous permettent de grandir ou rapetisser les structures de données si nous ne savons pas avant la compilation la grandeur des données Utilisation efficace de la mémoire – Excellent pour les petits microcontrôleurs Les pointeurs nous permettent la manipulation efficace des données dans les tableaux
21-Jan JGA Beaulieu Travailler avec les pointeurs et les adresses int a = 6; int b = 10; int* p = NULL; int* r = NULL; p = &a; r = p; //pointe à la //même variable b = *r; SymboliqueMémoire a p b r
21-Jan JGA Beaulieu Travailler avec les pointeurs et les adresses int a = 6; int b = 10; int* p = NULL; int* r = NULL; p = &a; r = p; //pointe à la //même variable b = *r; //b = a p = &b; //p pointe //à b *p = 8; //change la //valeur de b SymboliqueMémoire a p b r
21-Jan JGA Beaulieu Pointeurs - flexibilité Touts ces énoncés sont équivalents: int a; int* p = &a; … a = a + 1; a++; *p = *p + 1; (*p)++; //notez les () a = *p + 1;
21-Jan JGA Beaulieu Pointeurs - types Il est important de comprendre quun pointeur na pas seulement un type; mais que le pointeur pointe à une variable qui a un type particulier. Donc un pointeur prend les attributs du type auquel il pointe, en plus de ses attributs de pointeur Ceci est parce que vous pouvez déréférencer un pointeur et appliquer des opérations associées avec le type qui est pointé
21-Jan JGA Beaulieu Pointeurs - types Donc vous ne pouvez pas mêler les types de pointeurs dans les énoncés: int* p = NULL; char* r = NULL; … r = p; //erreur (avertissement) La seule exception à cette règle est le type de pointeur void (prochain cours)
21-Jan JGA Beaulieu Quiz Time int a = 1; int b = 2; int *p = NULL; int *r = NULL; … p = &b; r = &a; *r = *p; //quelles sont les //valeurs de a et b?
21-Jan JGA Beaulieu Devoir int question; int chapitre=9; char livre[]="Forouzan"; void main(void) { for(question=16; question<=20; question++) RépondQuestion(livre, chapitre, question); }