PDA

Afficher la version complète : [Réglé] Problème dans les pointeurs



Othmane33
07/05/2006, 14h53
Bonjour,
J'ai trouvé un tuto très bien: www.siteduzero.com section C/C++, mais je n'arrive pas à piger le principe des pointeurs en C! Quelqu'un peut m'aider?
Merci

Dudule-le-poisson
07/05/2006, 17h22
C'est assez difficile de répondre rapidement. Disons que pour résumer, un pointeur vers un élément donné est l'adresse mémoire de cet élément. Tu peux t'amuser à afficher les pointeurs sous forme d'adresse mémoire avec un printf("%p\n", ton_pointeur); (en C++, avec un std::cout, je crois que tu dois caster en (void *) pour afficher l'adresse mémoire.)

Pour le reste, il faudrait que tu poses des questions plus précises.

abgech
07/05/2006, 18h16
Imagine la mémoire comme une succession de case, pouvant contenir 1 octet sur les PC et compatibles, sur les système scientifiques ou autres la case n'est pas forcément d'un octet, généralement, sur ce genre de système la case occupe 64 ou 128 bits.
Chaque case est identifée par un numéro (comme les cases postales) qui va de 0 à taille_mémoire - 1. Ce numéro porte le nom d'adresse mémoire.

Un pointeur est tout simplement une variable capable de contenir l'adresse mémoire d'une autre variable.

Les instructions machines ne connaissent absolument pas le nom d'une variable, elles ne peuvent travailler qu'en utilisant l'adresse mémoire, par exemple (c'est schématique):
add 311,453
signifie pour la machine:
additionne le contenu de la mémoire 453 au contenu de la mémoire 311 et met le résultat dans la mémoire 311.
Bien sûr, add, 311, 453, un petit bout de programme, sont eux-même stockés dans la mémoire et, en réalité, sont en binaire.


Imaginons que tu écrive le programme suivant (les numéros de lignes sont mis pour l'explication):

01 int a, // UNE VARIABLE DE TYPE ENTIER
02 *pa; // UNE VARIABLE CAPABLE DE CONTENIR UNE ADRESSE MEMOIRE D'UN ENTIER
02 pa = &a; // MISE DE L'ADRESSE DE a DANS LA VARIABLE pa
03 *pa = 31; // MISE DE 31 DANS LA VARIABLE DONT L'ADRESSE EST CONTENUE DANS pa (C'EST A DIRE, EN L'OCCURENCE, a)

a est une variable capable de contenir un entier.
pa est une variable capable de contenir l'adresse d'une variable de type entier.
&a représente l'adresse de la variable a.
*pa représente la variable dont l'adresse est contenue dans pa.

Lors de la compilation le compilateur va effectuer le travail suivant (les instructions machines sont fictives, mais ressemble bigrement à ce qu'on peut trouver sur un CPU):

- ligne 01 et 02, le compilateur va réserver des places en mémoire pour mettre les variables, supposons qu'il mette a à l'adresse 53, pa à l'adresse 67 et une constante, 31, à l'adresse 89.

- ligne 03, l'instruction machine suivante est générée:
ldi x1,53
c'est à dire: met l'adresse de a (53) dans le registre hardware appelé registre d'index x1.

- ligne 04, l'instruction machine suivante est générée:
lda [x1],89
c'est à dire: met le contenu de l'adresse 89 (31) à l'adresse mémoire qui se trouve dans le registre x1 (53, c'est à dire, l'adresse de a).

Voilà, si tu as compris un peu ce qui précède, tu as tout simplement commencé à comprendre un peu comment fonctionne un CPU et comment on programme en assembler.

En C/C++, les pointeurs sont typés, c'est-à-dire qu'ils contiennent des adresses qui pointent sur un type déterminé de variable, c'est purement fictif et lié au langage (pour permettre au compilateur de faire certains contrôle et ainsi éviter des bugs), mais la plupart des CPU ne connaissent absolument pas les types de données (pas forcément vrai pour les gros CPU scientifiques).
Tu peux t'affranchir du typage en "castant" sur un type pointeur générique (qui s'adapte à n'importe quel type de données: void*.
Par exemple: void *xyz; est un pointeur qui peux pointer (contenir l'adressse) de n'importe quelle variable de n'importe quel type.

REMARQUE IMPORTANTE
Tu ne peux absolument pas faire l'économie de l'étude des pointeurs. Ils sont indispensables si tu veux utiliser des structures de données dynamiques (piles, files, listes, arborescences, graphes, etc). Et ceci, QUEL QUE SOIT le langage que tu utilises, même si ce langages a des pointeurs implicites.

J'espère ne pas avoir trop long et surtout d'avoir apporté des éléments d'information qui te seront profitables.

Othmane33
07/05/2006, 22h14
Merci, maintenant je comprends le principe.
Mais à quoi servent exactement les pointeurs?

Rennou
07/05/2006, 23h35
Pourtant j'ai suivi le même tuto que toi sur le site du zéro, j'avais jamais entendu parler des pointeurs et je trouve que le tuto explique super bien tout ça, j'ai compris tout de suite : vive le site du zéro !

Dudule-le-poisson
08/05/2006, 00h18
Les pointeurs servent tout simplement à manipuler la plupart de tes variables :
-un tableau de char/int/double/float n'est rien d'autre qu'un pointeur sur le premier élément de ce tableau
-lorsque tu manipuleras des structures, des unions ou des objets (en C++), tu les manipuleras généralement grâce à des pointeurs
-lorsque tu veux passer l'une de ces structures en paramètre à une fonction, tu utiliseras aussi un pointeur, ce qui évitera de copier toutes les données contenues dans l'objet dans la pile => gain de performance

Evidemment, quand on débute et qu'on fait des programmes avec des données simples (genre trois entiers et un double), on ne voit pas tout de suite l'intérêt des pointeurs. Pourtant par la suite tu verras qu'ils s'avèrent absolument indispensables. Et comme l'a souligné abgech, tu ne peux pas te permettre de faire une ellipse sur ce sujet.

Othmane33
08/05/2006, 01h24
Merci!
J'ai (bien sûr) compris le principe, mais je ne comprenais pas à quoi cela servait!
Et comme je suis compliqué, je croyais que je n'avais pas compris!
Merci!

galagann
08/05/2006, 11h40
C'est la partie qui ma pris 3 mois pour comprendre.

Je te conseil, ce livre : Langage C++ écrit par Nino Silverio au édition Eyrolles
Ou encore : Langage C écrit par G. Willms au édition Micro Application en version de Poche pour l'avoir toujours avec toi http://www.alionet.org/style_emoticons/<#EMO_DIR#>/tongue.gif

Othmane33
08/05/2006, 11h46
Merci, je vais voir s'il est dans ma librairie à coté