J´aimerais saisir l´interêt des pointeurs.
Chaques fois on me dit que c´est utilisé pour ne pas écrire sur une adresse memoire déjà utilisée.
Mais quand on initialise une variable on ne se soucie pas où elle va?
Est-ce qu´un bon programmeur pourrait me réexpliquer les pointeurs depuis le début, leur interêt et tout, ce serait VRAIMENT sympa!
pas mal c´etait une bonne explication.
mais je rajouterait que un pointeur pointe sur 4 GO de mémoire et prend donc 32 bits, quelque soit le type d´objet pointé.
mais ca c´est transparent on ne le sait pas en C.
il y a aussi les types pointeurs de pointeurs par exemple pour faire des tableaux de chaines a longeur variable.
Merci pour cette réponse très complète
c´est aussi assez nain teressant pour les listes chainees
Puisqu on parle de jeu video, l´exemple assez con et simple serait celui-ci.
Tu as ton personnage face à trois créatures qui ont chacune une variable contenant leurs points de vie respectifs:
PVcréature1 = 20;
PVcreature2 = 30;
PVcreature3 = 25;
SI le perso attaque un de ces 3 ennemis, il faudra pouvoir opérer une soustraction, et cela sur la bonne variable.
Pour cela, tu peux créer un pointeur et l´utiliser comme ca:
Si le perso vise la créature n°1, tu places le pointeur sur la variable pvcréature1.
Si en revanche, il s´agit de la créature2, tu places le pointeur sur pvcréature2
Et si c´est la créature3, tu places le pointeur sur pvcreature3.
Comme cela si le perso tire et cause des dégats, il te suffit simplement de faire la soustraction sur le pointeur.
non sous dos c´est plu compliké.
il y a les near pointers, et les far pointers.
un near pointer ne pointe que sur 64 ko de RAM il prend 16 bits.
si on veu avoir un pointeur sur la mémoire étendue (un far pointer) il faut un pointeur vers le segment et un pointeur vers l´offset.
cela fait 2 * 16 bits.
dans les systemes 32 bits d´aujourd´hui, la mémoire n´est plus qu´un vaste champ et ne fonctionne plus par EMB (Enhenced Memory Block) de 64 ko.
ce qui fait que les pointeurs sont tous des far pointers des fois on note LPVariable cela signifie LongPointer soit 32 bits.
pour les processeurs 64 bits je ne sait pas si les pointeurs aurons 64 bits puisque ca ferait plus de 18446744073709551616 Octets soit 18446 Peta Octets!!!! largement suffisant donc on va peut etre en rester aux 4GO sur 32 bits. mais je peut pas certifier.
Mon exemple pourri comme tu dis est un aperçu du système utilisé pour fallout.
J´avais rassemblé une chiée d´informations sur le fonctionnement de ce jeu à travers tout plein de sites outre-atlantiques, j´ai un peu levé le pied y´a quelques années déjà.
Toutefois, si ca t´intéresse
Je sais qu´un gars appelé pipboy2000 a fait une étude très avancée sur le système interne de fallout 1 et 2.
Tu devrais essayer d´aller voir sur son site, c´est plein d´outils de modding, y´a pas mal de trucs dont un décompilateur de script.
Tu y trouveras peut etre ton bonheur, l´URL m´échappe mais en cherchant un peu ca doit pas etre bien dur de la trouver.
Un pointeur est la location d´une variable.
Bon, alors vous vous prenez la tete sur une histoire un peu sans interet ( la validité de l´exemple ...)
J´va essayer de te donner un exemple plus parlant ( cas d´ecole ).
j´ai aujourd"hui dans un programme 10 entités.
Hors entités sont a meme de se reproduire...
Donc au debut de mon progamme j´ai 10 entité et au fil du temps je vais en rajouter. Bah, le probleme posé la, c´est que je sais pas combien je vais en rajouter. Donc tu peu pas faire de tableau static un truc du style
TYPEENTITE tab[MAX];
Ca marche pas pasque t´es limité par le MAX.
Donc l´idée c´est de connaitre l´adresse de tes entités. Et d´en faire une petite liste chainée.
Cela se passe un peu comme ca
typedef struct S_ELT_ENTITE
{
struct S_LISTE_MES_ENTITE * Next;
TYPEENTITE Contenu;
}T_ELT_ENTITE;
Chaque element, contient donc
Contenu = Les donnes que tu veux conserver
Next = Un poiteur sur le suivant dans la liste.
Tu tiens ta liste par un pointeur de tete.
Tu parcours ta liste en avancant sur le next.
Tu place le dernier NEXT a NULL ( cela te permet de t´arreter car NULL est une adresse invalide bien connue de tout les systeme d´exploitation.
Un pointeur a une fonction plus basique en C.
Comment appelant une fonction celle ci peut changer une valeur ? Tu lui passe l´adresse sur la valeur et tu peux changer le contenu. Tu me dira qu´en C++ t´en a rien a faire pasque tu peux faire un passage par reference ( et t´a bien raison ) mais un passage par refenrece c´est rien de plus qu´un passage par adresse controlé au niveau de la conpilation.
Si tu souhaite plus d´explication n´hesite pas a laisser un message ...
Pour les petits malins ki se prennent la tete en near et far pointeur sous dos, je leur dit qu´il vaut mieux arreter l´informatique de grand papa ( c´est pas dit mechament attention ). Mais ayant eut le plaisir de subir ce genre de conneries et autres pagination pour acceder a la memoire etendue, je ne dis qu´une chose : pourquoi se prendre la tete avec ca alors qu´une petite compilation 32bit avec une memoire virtuelle bien geré par un OS decent resoud tout ce genre de tracas ?
Moi aussi, je cherche à savoir la véritable utilisation des pointeurs :
je pense qu´il y aurait :
-L´allocation dynamique de mémoire (malloc, new...)
-Pour les fonctions :
En effet, on utilise aussi les pointeurs pour les passages par référence, non?
genre :
void FHONKSIONKIITU(float *truc, float *truc2)
{
return((*truc1)*(*truc2));
//le petit casse tete pour un débutant
)
}
void main(void)
{
float un=1, deux=2;
...
FHONKSIONKIITU(&, &);
}
C´est une autre utilisation des pointeurs, n´est-ce pas???
++
Pix
PS : je n´étudie l´info que par moi-même, donc c´est (peut-être) pas très académique... ;)
Oh oui, quelle erreur!!!
Pardon :
float FHONKSIONKIITU(float *truc, float *truc2)
{
return((*truc1)*(*truc2));
//le petit casse tete pour un débutant
)
}
void main(void)
{
float un=1, deux=2;
float trois;
...
trois = FHONKSIONKIITU(&, &);
}
J´ai vraiment pas réfléchi en donnant mon tout premier exemple...
Tu as raison...
Mais ce passage par référence (pour ceux qui savant po) sert à changer directement la valeur de la variable en elle-même, ce qui est parfois utile... Voilou, mais mon exemple ne correspond pas.
++
Pix
Salut,
J´ai moi aussi un chtit question.
J´ai pu voir, dans un programme au boulot, une utilisation de pointeurs sur pointeurs.
La declaration de la fonction est un truc du genre
void MaFonction (void **ret_val)
Quelqu´un connaitrait-il l´utilite des pointeurs de pointeur ?
On a vaguement essaye de m´expliquer que c´etait pour conserver l´ancienne valeur du parametre mais dans ce cas, pourquoi ne pas le passer par valeur (sans utiliser de pointeur) ?
Et puis c´est pour faire des tableaux à allocation dynamique de mémoire, mais dont en plus, tu ne connais pas le nombre (de tableau) au départ...
Ca peut arriver, mais je sais pas si c´est fréquent! ![]()
++
Pix
bien sur, c´est meme tout le temps qu´on a besoin de tableaux dynamiques !
et le mieu pour éviter les erreurs c de faire des classes ou d´utiliser celles de la MFC (CArray)
Bien sur que c´est frequent !
Suffit d´avoir une liste de chaine de caractere.
Un chaine de caratere c´est un pointeur
La liste, c´est un pointeur sur des pointeur de chaine.
Zou
Les CArray sont des bouffeur de cycle et des destructeur de mapping memoire en puissance.
C´est bien a utiliser lors d´une phase de debug, mais lorsque tu livre faut les eliminer sans hesitation.
aucune importance si ton application c´est un éditeur de texte.
bouffeur de cyle oui, mais pour le mapping en mémoire c plutot bien rélaisé et le growing est pas mal intelligent je trouve. de plus il essaie d´eviter la fragmentation ce qui est interressant.
enfin en tout cas le gros avantages par rapport a new et delete c´est ke on est sur de ne jamais modifier une zone en mémoire non allouée pour notre programme.