begin process at 2012 02 11 19:28:34
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Divers

 > 

Comprendre les pointeur


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Comprendre les pointeur

dimanche 16 février 2003 à 18:18:48 | Comprendre les pointeur

Incanus

Je vien de commencer a programmer en c++ et j'aimerai savoir se qu'est les pointeurs et à quoi ils servent. @+
Inc@nus
dimanche 16 février 2003 à 22:43:12 | Re : Comprendre les pointeur

vieuxLion

bonjour,
la question est un peu vague!
Voici quand même un essai pour débutant

on sait que les ordinateurs ne comprennent finalement que les 0 et les 1... qui sont quand même regroupés par huit en octets.
Les programmeurs humains (enfin la pluspart) préfèrent utiliser des noms : on appelle cela des variables.
Cela suffit bien souvent :
on fait

int i=0;
i++;
cout << "i=" << i<< endl;

Mais parfois, il faut pouvoir accéder à la partie "ordinateur" (on parle alors de partie "systeme")
On a besoin de savoir où sont rangées nos variables.
Où ? c'est le pointeur qui nous le dit
dans notre exemple, la variable "i" est rangée à l'adresse "&i"
Cette adresse est un POINTEUR vers la zone qui détient la VALEUR "i".
Ceci dit, l'utilisation des pointeurs - facultative pour la plupart des variables - devient très souvent obligatoire lorsque l'on travaille avec des données de type "chaine de caractères".
En voici un exemple :
char * pNom = "vieuxLion";
la variable pNom est un pointeur qui référence le premier caractère de la chaine (soit le 'v')

Il faut donc savoir travailler avec, et en particulier maîtriser l'utilisation du symbole *
Si l'on veut afficher le CONTENU situé derrière le pointeur, on utilise:
cout << *pNom ;

... et cela affiche la lettre 'v'
on utilise aussi ce que l'on appelle l'arithmétique des pointeurs, par exemple :
pNom++; cout << *pNom;

affiche cette fois ci la lettre 'i' (la suivante)
etc...



-------------------------------
Réponse au message :
-------------------------------

> Je vien de commencer a programmer en c++ et j'aimerai savoir se qu'est les pointeurs et à quoi ils servent. @+
> Inc@nus
lundi 17 février 2003 à 08:55:58 | Re : Comprendre les pointeur

jonathanmcdougall

Et oui, c'est encore moi.

> > Je vien de commencer a programmer en c++ et j'aimerai savoir se qu'est les pointeurs et à quoi ils servent. @+
> > Inc@nus
>

> Cette adresse est un POINTEUR vers la zone qui détient la
>VALEUR "i".

Pas vraiment, &i représente l'adresse de i. 'int* pi = &i' sera un pointeur qui pointe vers l'adresse de i.

> Ceci dit, l'utilisation des pointeurs - facultative pour la
>plupart des variables - devient très souvent obligatoire
>lorsque l'on travaille avec des données de type "chaine de
>caractères".
> En voici un exemple :
> char * pNom = "vieuxLion";

Préférer 'const char *pNom'.

> la variable pNom est un pointeur qui référence le premier caractère de la chaine (soit le 'v')

Oui et non. Oui dans le sens que 'pNom' pointe vers l'adresse de "vieuxLion" et non dans le sens que les compilateur travaille d'une façon particulère avec les char*.


Pour bien comprendre les pointeurs, Inc@nus, considère ceci

# include <iostream>
using std::cout;

int main()
{
int variable = 10;

cout << variable;
cout << &variable;
}

Ici, le premier cout est assez simple : il affiche 10. Mais le
deuxième est beaucoup plus intéressant. L'opérateur &
devant un nom retourne son *adresse* dans la mémoire (car
chaque valeur a son espace mémoire). L'affichage est
différent dans le temps, mais disons qu'il affiche 0x0005.
Cela voudrait dire que 'variable' est à la 'case' mémoire
numéro 0x0005 et que cette 'case' contient la valeur '10'.

À quoi ça sert? À beaucoup de choses, mais en même temps à pas grand choses. L'exemple classique est celui-ci :

int main()
{
int variable = 10;
int *pointeur = &variable;

cout << pointeur;
cout << *pointeur;
}

Ici, 'variable' est un int et contient 10. Tu seras probablement tenté de dire que 'pointeur' est un int aussi, mais non. 'pointeur' est, justement, un *pointeur* vers un int. Et comme de fait, on ne stocke pas une valeur quelconque dans ce pointeur, on y stocke *l'adresse* de 'variable' en utilisant l'opérateur & qu'on a vu plus haut.

Le premier cout affiche donc ce qu'on a mis dans 'pointeur' et ce qu'on y a mis, c'est l'adresse de 'variable', donc quelque chose comme 0x0005. Le deuxième cout fait quelque chose d'encore mieux : il va chercher la valeur qui est à l'adresse contenue dans 'pointeur'.

Confus? Très bien, c'est ça qu'il faut (faut bien filtrer les programmeurs, sinon y'en aurait trop :) ).

Je récapitule. La variable 'pointeur' n'est pas une variable ordinaire. Elle ne sert *pas* à contenir des valeurs comme n'importe qu'elle autre variable. Elle ne sert qu'à stocker une adresse. L'adresse d'une autre variable. J'ai dis plus haut que

&variable

retourne l'adresse, dans la mémoire, de 'variable'. On stocke donc cette adresse dans le pointeur. Maintenant,

variable == 10

et

pointeur == 0x0005

(en supposant toujours que l'adresse de 'variable' est 0x0005). Maintenant, si on affiche le pointeur, ça ne servira pas à grand chose. Mais on a la possibilité d'aller voir ce qu'il y a à cette adresse et on le fait en (ré)utilisant l'opérateur * :

cout << *pointeur;

Ici, on dit "je veux la valeur qui est à l'adresse contenue dans 'pointeur'", donc, en fait, la valeur de 'variable'.

Les étoiles t'en font voir? L'astérisque sert à deux choses ici :
1) à la définition d'un pointeur :

int *p;

Ici, p est un pointeur vers un int.

2) à chercher la valeur qu'il y a à l'adresse contenue dans le pointeur :

cout << *p;

Ici, on va chercher la valeur qui est à l'adresse contenue dans 'p'. Le vrai mot est 'déréférencement'. Décortiquons ce mot : "référencer" veut dire que 'pointeur' est comme une référence de 'variable'. "Référencement" est l'action de mettre une addresse dans 'pointeur' et déréférencement est l'action d'aller chercher la valeur à cette adresse.

Ouf. Mais ça ne te dis toujours rien sur l'utilité.

Eh bien sache qu'il n'y en a plus beaucoup. Le C++ à introduit la notion de 'référence' qui ressemble à un pointeur toujours déréférencé. Lis à propos de ça dans ton livre (si tu n'en as pas, honte à toi. Cours vite en acheter un, je recommande "Programmer en langage C++" de Claude Delannoy").

Mais encore, l'usage le plus fréquent est l'allocation dynamique à l'aide de 'new'. Le reste peut pas mal se faire avec les références.

Mais pour satisfaire ta curiosité insatiable, voici quand même un exemple :


# include <iostream>
using std::cout;

void ajouter_un(int maCopie)
{
maCopie = maCopie + 1;
}

int main()
{
int monChiffre = 10;

ajouter_un(monChiffre);

cout << monChiffre;
}

Ici, il n'y a pas de pointeurs. On a un int qui s'apelle 'monChiffre' qui contient 10. On passe cette variable à ajouter_un() qui lui rajoute 1 et on revient au main() pour afficher 'monChiffre'. Résultat? 10, évidemment.

La raison est que 'monChiffre' est passé *par valeur*, c'est-à-dire que ajouter_un() ne joue pas avec 'monChiffre', mais bien avec une *copie* de 'monChiffre'. Le compilateur a pris ce qu'il y avait dans 'monChiffre' et l'a copié dans 'maCopie'. ajouter_un() a ensuite incrémenté 'maCopie' et est retourné au main() où 'monChiffre' n'a jamais été modifié.

Ce qui nous cause problème. Nous, on voulait ajouter 1 à cette variable. La solution? Les pointeurs (ça tombe bien).

La solution n'est donc plus de passer la *valeur* de 'monChiffre', mais bien son *adresse*. Ainsi, ajouter_un() pourra ajouter 1 non pas à une variable copiée, mais bien à 'monChiffre'.

# include <iostream>
using std::cout;

void ajouter_un(int* monPointeur)
{
*monPointeur = *monPointeur + 1;
}

int main()
{
int monChiffre = 10;

ajouter_un(&monChiffre);

cout << monChiffre;
}

Beaucoup d'étoiles, non? Maintenant, ajouter_un() prend une adresse comme argument, non plus une valeur. Et c'est ce qu'on fait : en appelant ajouter_un(), on passe *l'adresse* de 'monChiffre' en utilisant le &. À l'intérieur de ajouter_un(), 'monPointeur' pointe vers 'monChiffre'. Voyons maintenant

*monPointeur = *monPointeur + 1;

Partons de la droite. On prend la *valeur* qui est à l'adresse stockée dans 'monPointeur', donc en fait on prend la valeur de 'monChiffre'. On lui additionne 1 et on le stocke à l'endroit où pointe 'monPointeur', donc, dans 'monChiffre'.

Et voilà, 'monChiffre' est incrémenté et nous sommes heureux.

Mais voyons ce qui se serait passé sans étoiles :

monPointeur = monPointeur + 1;

Qu'y a-t-il dans 'monPointeur'? L'adresse de 'monchiffre'. Alors tout ce qu'on fait est de prendre cette adresse (0x0005), de lui ajouter 1 (0x0006) et de la mettre dans monPointeur. (En fait, on ajoute pas 1, mais bien sizeof(int), mais c'est pas grave). Qu'est-ce que ça nous donne? Eh bien on a maintenant un pointeur qui pointe vers un espace qui n'existe pas (il n'y a rien à 0x0006). Donc, mauvais. Voyons ceci :

monPointeur = *monPointeur + 1;

Ici, toujours en partant de la droite, on prend la valeur qui est à l'adresse stockée dans 'monPointeur', c'est-à-dire la valeur de 'monChiffre' et on lui ajoute un. Ça fait 11 (il y avait déjà 10 dans 'monChiffre'). Et maintenant, on ajoute 11 à... quoi? À l'adresse contenue dans 'monPointeur'! Ce qui nous donne maintenant un pointeur qui pointe vers un autre espace (0x0010, c'est du hexadécimal, rappele toi) qui n'existe toujours pas. Donc mauvais aussi. La solution est donc bel et bien

*monPointeur = *monPointeur + 1;

Ouf encore. Quelques petites choses en terminant, lorsque je disais que 'pointeur' est un pointeur vers un int, c'est que 'pointeur' ne peut contenir que l'adresse d'un int :

double monDouble = 10.5;
int *pointeur = &monDouble;

ne compile même pas (a value of type "double *" cannot be used to initialize an entity of type "int *"), ce qui est bien normal.

Et voilà. La morale est 1) achète un bon livre et 2) va voir mon site web où t'auras plus d'aide encore (oui oui, je fais de la pub).

Bonne soirée!

--
Jonathan Mcdougal
Montréal, Québec
mcdougalljonathan@hotmail.com
http://www.multimania.com/utopiasoftware

lundi 17 février 2003 à 22:27:26 | Re : Comprendre les pointeur

vieuxLion

désolé, ce n'est pas comme cela que l'on s'adresse à un débutant



-------------------------------
Réponse au message :
-------------------------------

> Et oui, c'est encore moi.
>
> > > Je vien de commencer a programmer en c++ et j'aimerai savoir se qu'est les pointeurs et à quoi ils servent. @+
> > > Inc@nus
> >
>
> > Cette adresse est un POINTEUR vers la zone qui détient la
> >VALEUR "i".
>
> Pas vraiment, &i représente l'adresse de i. 'int* pi = &i' sera un pointeur qui pointe vers l'adresse de i.
>
> > Ceci dit, l'utilisation des pointeurs - facultative pour la
> >plupart des variables - devient très souvent obligatoire
> >lorsque l'on travaille avec des données de type "chaine de
> >caractères".
> > En voici un exemple :
> > char * pNom = "vieuxLion";
>
> Préférer 'const char *pNom'.
>
> > la variable pNom est un pointeur qui référence le premier caractère de la chaine (soit le 'v')
>
> Oui et non. Oui dans le sens que 'pNom' pointe vers l'adresse de "vieuxLion" et non dans le sens que les compilateur travaille d'une façon particulère avec les char*.
>
>
> Pour bien comprendre les pointeurs, Inc@nus, considère ceci
>
> # include <iostream>
> using std::cout;
>
> int main()
> {
> int variable = 10;
>
> cout << variable;
> cout << &variable;
> }
>
> Ici, le premier cout est assez simple : il affiche 10. Mais le
> deuxième est beaucoup plus intéressant. L'opérateur &
> devant un nom retourne son *adresse* dans la mémoire (car
> chaque valeur a son espace mémoire). L'affichage est
> différent dans le temps, mais disons qu'il affiche 0x0005.
> Cela voudrait dire que 'variable' est à la 'case' mémoire
> numéro 0x0005 et que cette 'case' contient la valeur '10'.
>
> À quoi ça sert? À beaucoup de choses, mais en même temps à pas grand choses. L'exemple classique est celui-ci :
>
> int main()
> {
> int variable = 10;
> int *pointeur = &variable;
>
> cout << pointeur;
> cout << *pointeur;
> }
>
> Ici, 'variable' est un int et contient 10. Tu seras probablement tenté de dire que 'pointeur' est un int aussi, mais non. 'pointeur' est, justement, un *pointeur* vers un int. Et comme de fait, on ne stocke pas une valeur quelconque dans ce pointeur, on y stocke *l'adresse* de 'variable' en utilisant l'opérateur & qu'on a vu plus haut.
>
> Le premier cout affiche donc ce qu'on a mis dans 'pointeur' et ce qu'on y a mis, c'est l'adresse de 'variable', donc quelque chose comme 0x0005. Le deuxième cout fait quelque chose d'encore mieux : il va chercher la valeur qui est à l'adresse contenue dans 'pointeur'.
>
> Confus? Très bien, c'est ça qu'il faut (faut bien filtrer les programmeurs, sinon y'en aurait trop :) ).
>
> Je récapitule. La variable 'pointeur' n'est pas une variable ordinaire. Elle ne sert *pas* à contenir des valeurs comme n'importe qu'elle autre variable. Elle ne sert qu'à stocker une adresse. L'adresse d'une autre variable. J'ai dis plus haut que
>
> &variable
>
> retourne l'adresse, dans la mémoire, de 'variable'. On stocke donc cette adresse dans le pointeur. Maintenant,
>
> variable == 10
>
> et
>
> pointeur == 0x0005
>
> (en supposant toujours que l'adresse de 'variable' est 0x0005). Maintenant, si on affiche le pointeur, ça ne servira pas à grand chose. Mais on a la possibilité d'aller voir ce qu'il y a à cette adresse et on le fait en (ré)utilisant l'opérateur * :
>
> cout << *pointeur;
>
> Ici, on dit "je veux la valeur qui est à l'adresse contenue dans 'pointeur'", donc, en fait, la valeur de 'variable'.
>
> Les étoiles t'en font voir? L'astérisque sert à deux choses ici :
> 1) à la définition d'un pointeur :
>
> int *p;
>
> Ici, p est un pointeur vers un int.
>
> 2) à chercher la valeur qu'il y a à l'adresse contenue dans le pointeur :
>
> cout << *p;
>
> Ici, on va chercher la valeur qui est à l'adresse contenue dans 'p'. Le vrai mot est 'déréférencement'. Décortiquons ce mot : "référencer" veut dire que 'pointeur' est comme une référence de 'variable'. "Référencement" est l'action de mettre une addresse dans 'pointeur' et déréférencement est l'action d'aller chercher la valeur à cette adresse.
>
> Ouf. Mais ça ne te dis toujours rien sur l'utilité.
>
> Eh bien sache qu'il n'y en a plus beaucoup. Le C++ à introduit la notion de 'référence' qui ressemble à un pointeur toujours déréférencé. Lis à propos de ça dans ton livre (si tu n'en as pas, honte à toi. Cours vite en acheter un, je recommande "Programmer en langage C++" de Claude Delannoy").
>
> Mais encore, l'usage le plus fréquent est l'allocation dynamique à l'aide de 'new'. Le reste peut pas mal se faire avec les références.
>
> Mais pour satisfaire ta curiosité insatiable, voici quand même un exemple :
>
>
> # include <iostream>
> using std::cout;
>
> void ajouter_un(int maCopie)
> {
> maCopie = maCopie + 1;
> }
>
> int main()
> {
> int monChiffre = 10;
>
> ajouter_un(monChiffre);
>
> cout << monChiffre;
> }
>
> Ici, il n'y a pas de pointeurs. On a un int qui s'apelle 'monChiffre' qui contient 10. On passe cette variable à ajouter_un() qui lui rajoute 1 et on revient au main() pour afficher 'monChiffre'. Résultat? 10, évidemment.
>
> La raison est que 'monChiffre' est passé *par valeur*, c'est-à-dire que ajouter_un() ne joue pas avec 'monChiffre', mais bien avec une *copie* de 'monChiffre'. Le compilateur a pris ce qu'il y avait dans 'monChiffre' et l'a copié dans 'maCopie'. ajouter_un() a ensuite incrémenté 'maCopie' et est retourné au main() où 'monChiffre' n'a jamais été modifié.
>
> Ce qui nous cause problème. Nous, on voulait ajouter 1 à cette variable. La solution? Les pointeurs (ça tombe bien).
>
> La solution n'est donc plus de passer la *valeur* de 'monChiffre', mais bien son *adresse*. Ainsi, ajouter_un() pourra ajouter 1 non pas à une variable copiée, mais bien à 'monChiffre'.
>
> # include <iostream>
> using std::cout;
>
> void ajouter_un(int* monPointeur)
> {
> *monPointeur = *monPointeur + 1;
> }
>
> int main()
> {
> int monChiffre = 10;
>
> ajouter_un(&monChiffre);
>
> cout << monChiffre;
> }
>
> Beaucoup d'étoiles, non? Maintenant, ajouter_un() prend une adresse comme argument, non plus une valeur. Et c'est ce qu'on fait : en appelant ajouter_un(), on passe *l'adresse* de 'monChiffre' en utilisant le &. À l'intérieur de ajouter_un(), 'monPointeur' pointe vers 'monChiffre'. Voyons maintenant
>
> *monPointeur = *monPointeur + 1;
>
> Partons de la droite. On prend la *valeur* qui est à l'adresse stockée dans 'monPointeur', donc en fait on prend la valeur de 'monChiffre'. On lui additionne 1 et on le stocke à l'endroit où pointe 'monPointeur', donc, dans 'monChiffre'.
>
> Et voilà, 'monChiffre' est incrémenté et nous sommes heureux.
>
> Mais voyons ce qui se serait passé sans étoiles :
>
> monPointeur = monPointeur + 1;
>
> Qu'y a-t-il dans 'monPointeur'? L'adresse de 'monchiffre'. Alors tout ce qu'on fait est de prendre cette adresse (0x0005), de lui ajouter 1 (0x0006) et de la mettre dans monPointeur. (En fait, on ajoute pas 1, mais bien sizeof(int), mais c'est pas grave). Qu'est-ce que ça nous donne? Eh bien on a maintenant un pointeur qui pointe vers un espace qui n'existe pas (il n'y a rien à 0x0006). Donc, mauvais. Voyons ceci :
>
> monPointeur = *monPointeur + 1;
>
> Ici, toujours en partant de la droite, on prend la valeur qui est à l'adresse stockée dans 'monPointeur', c'est-à-dire la valeur de 'monChiffre' et on lui ajoute un. Ça fait 11 (il y avait déjà 10 dans 'monChiffre'). Et maintenant, on ajoute 11 à... quoi? À l'adresse contenue dans 'monPointeur'! Ce qui nous donne maintenant un pointeur qui pointe vers un autre espace (0x0010, c'est du hexadécimal, rappele toi) qui n'existe toujours pas. Donc mauvais aussi. La solution est donc bel et bien
>
> *monPointeur = *monPointeur + 1;
>
> Ouf encore. Quelques petites choses en terminant, lorsque je disais que 'pointeur' est un pointeur vers un int, c'est que 'pointeur' ne peut contenir que l'adresse d'un int :
>
> double monDouble = 10.5;
> int *pointeur = &monDouble;
>
> ne compile même pas (a value of type "double *" cannot be used to initialize an entity of type "int *"), ce qui est bien normal.
>
> Et voilà. La morale est 1) achète un bon livre et 2) va voir mon site web où t'auras plus d'aide encore (oui oui, je fais de la pub).
>
> Bonne soirée!
>
> --
> Jonathan Mcdougal
> Montréal, Québec
> mcdougalljonathan@hotmail.com
> http://www.multimania.com/utopiasoftware
>
>
mardi 18 février 2003 à 03:37:28 | Re : Comprendre les pointeur

jonathanmcdougall

> désolé, ce n'est pas comme cela que l'on s'adresse à un
>débutant

<snip>

Je tiens un site web depuis plus d'un an avec des tutoriaux sur le basic et le C++, la compréhension des gens est donc importante pour moi.

Si tu pouvais (et Incanus aussi) m'en dire plus, ça m'aiderait beaucoup.

Merci,

--
Jonathan Mcdougal
Montréal, Québec
mcdougalljonathan@hotmail.com
http://www.multimania.com/utopiasoftware



Cette discussion est classée dans : pointeur, comprendre


Répondre à ce message

Sujets en rapport avec ce message

Pointeur et référence [ par kawazaki ] Bonjour je commence a programmer en c++ je voudrais comprendre quand j'utilise les pointeurs et les références ainsi que les déclarations:*var**var&va Pointeur qui fait planter Windows !!! [ par coyito ] Salutquand je défini moi même une addresse pour un pointeur (exemple pour lire n'importe ou dans la mémoire) j'ai une erreur windows "access violation Pointeur sur methodes avec parametre [ par Kinamstrong ] Salut a toi,Je cherche à savoir comment marche les pointeurs sur les methodes avec parametres.Qu'est ce qui va differencier deux meme methodes en cour tableau et pointeur [ par cognac ] Bonjour,Je tente de faire apparaitre les mois de l'année (simple mais pour un débutant....). Bon il y a toujours "cout"12 fois mais j'ai pensé à un ta je comprend plus rien(pointeur) [ par bidules ] Bonjour,Pour moi on utilise les pointeur pour creer des tableau dynamiquement.or j'ai reussi a en declarer un avec une taille entrer a l'aide d'une va Probleme de Débutant [ par Dorgendubal ] Hello à tous,j'ai déjà programmé en C++ et même avec des envirronements graphiques (comme QT sous linux) mais jamais avec Visual C++.Alors j'ai un pro Probleme complique sur pointeur mais reponse simple surement [ par MrKribou ] Un probleme de pointeur je pense.Je vous expose la situation :Dans une Classe (ClassEx) voila je fais un truc du genre :char* pChar = this->getInfo("i le pointeur de souris. [ par Pyou ] Bonjour ! J'aimerais savoir comment faire pour ne pas afficher le pointeur la de souris par defaut dans ma fenetre opengl, puisque je veux en afficher pointeur non initialisé [ par arc59 ] J'ai créé un programme qui permet de lire les tag des fichiers MP3. Ce programme utilise une structure de pointeurs vers des char. Les tag d'un fichie Pb Class et pointeur ... [ par payen ] salut a tous,j'ai un petit probleme en C++: j'ai definit une class CImage, avec entre autre, un pointeur vers une variable de type char (char *nom_ima


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,577 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales