Pointeur c/c++
Fermé
mixtape
Messages postés
18
Date d'inscription
mardi 15 novembre 2005
Statut
Membre
Dernière intervention
22 mai 2006
-
15 nov. 2005 à 11:32
mamiemando Messages postés 33545 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 25 février 2025 - 2 mai 2007 à 02:35
mamiemando Messages postés 33545 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 25 février 2025 - 2 mai 2007 à 02:35
5 réponses
mamiemando
Messages postés
33545
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
25 février 2025
7 829
16 nov. 2005 à 00:37
16 nov. 2005 à 00:37
Rappels sur les pointeurs
Je ne sais pas si ca va t'aider mais une declaration de pointeur ce lit de deux façons :
*p est un int
p est un int * (pointeur sur un entier).
Personnellement je trouve que pointeur, bien que ce soit parlant, occulte un peu ce qui se passe en réalité. En fait tous les pointeurs sans exception et -quel que soit leur type- sont une adresse mémoire, donc une valeur qui tient toujours 4 octets (il me semble que c'est 4), et ce complètement indépendamment de ce qui se trouve à cette adresse. Le type associé à un pointeur caractérise uniquement la manière dont on va interpréter ce qui est à cette adresse.
Bref, int *p=0x1234566 est une adresse.
A cette adresse se trouve la valeur de l'entier *p si le pointeur a été fabriqué correctement.
Tu noteras que tu déclares une adresse comme une variable classique donc
int * p=NULL; //l'adresse stockée dans p recoit l'adresse nulle
Rien ne t'empeche de changer le type d'un pointeur puisque c'est une adresse. Tu ne fais que changer la manière dont est interprété ce qui se trouve à cette adresse (cast).
Allocation mémoire
Bien entendu en déclarant un pointeur tu alloues la place nécessaire pour stocker l'adresses (quelques bits), mais encore faut il que cette adresse soit valide. Le role des malloc et calloc du C (et du new en c++) est justement d'allouer un espace memoire et de l'affecter à ton pointeur.
Tu noteras que malloc retourne un pointeur (void *) c'est à dire une adresse sans présumé de ce qui se trouve à cette adresse (un int * présume que ce qui s'y trouve est un int), d où le cast :
Pointeurs de pointeurs, opérateurs * et &
Rien ne t'empêche de construire des adresses d'adresses (double pointeurs et ainsi de suite). Ainsi :
Comme tu le vois * permet de passer d'une adresse à la valeur stockée à cette adresse. mais le C propose l'opérateur réciproque (à savoir quel est l'adresse de ma variable). Ainsi :
A ce stade tu devrais commencer à maitriser les notations avec des * et des &.
Libérer la mémoire
Tu peux allouer de la mémoire avec des malloc ou des nex, mais quand tu n'as plus besoin de ces variables il faut les virer avec un free (en c) ou un delete (en c++)
Les références (c++ seulement)
En c++ on travaille plutôt avec des références. Il faut voir une référence comme un pointeur, sauf que tout ce passe comme si on manipulait directement la variable (en terme de
Voilà si tu as des questions n'hésites pas ;-)
Bonne chance
Je ne sais pas si ca va t'aider mais une declaration de pointeur ce lit de deux façons :
int *p
*p est un int
p est un int * (pointeur sur un entier).
Personnellement je trouve que pointeur, bien que ce soit parlant, occulte un peu ce qui se passe en réalité. En fait tous les pointeurs sans exception et -quel que soit leur type- sont une adresse mémoire, donc une valeur qui tient toujours 4 octets (il me semble que c'est 4), et ce complètement indépendamment de ce qui se trouve à cette adresse. Le type associé à un pointeur caractérise uniquement la manière dont on va interpréter ce qui est à cette adresse.
Bref, int *p=0x1234566 est une adresse.
A cette adresse se trouve la valeur de l'entier *p si le pointeur a été fabriqué correctement.
Tu noteras que tu déclares une adresse comme une variable classique donc
int * p=NULL; //l'adresse stockée dans p recoit l'adresse nulle
Rien ne t'empeche de changer le type d'un pointeur puisque c'est une adresse. Tu ne fais que changer la manière dont est interprété ce qui se trouve à cette adresse (cast).
Allocation mémoire
Bien entendu en déclarant un pointeur tu alloues la place nécessaire pour stocker l'adresses (quelques bits), mais encore faut il que cette adresse soit valide. Le role des malloc et calloc du C (et du new en c++) est justement d'allouer un espace memoire et de l'affecter à ton pointeur.
Tu noteras que malloc retourne un pointeur (void *) c'est à dire une adresse sans présumé de ce qui se trouve à cette adresse (un int * présume que ce qui s'y trouve est un int), d où le cast :
int * plop=(int *) malloc(sizeof(i)); //A partir de la la case memoire *plop qui fait la taille d'un int est allouée //je peux donc ecrire dedans (sinon ça aurait fait une erreur de segmentation) *plop=2;
Pointeurs de pointeurs, opérateurs * et &
Rien ne t'empêche de construire des adresses d'adresses (double pointeurs et ainsi de suite). Ainsi :
int *** plop3; int ** plop2=*plop3; //adresse d'un pointeur de type int * int *plop1= *plop2: //adresse d'un entier int *plop1=**plop3; int plop=*plop1
Comme tu le vois * permet de passer d'une adresse à la valeur stockée à cette adresse. mais le C propose l'opérateur réciproque (à savoir quel est l'adresse de ma variable). Ainsi :
plop3==&plop2 plop2==&plop1 plop1==&plop
p *p 0x123456 ---------> 2 0x123456 <--------- 2 &q q
A ce stade tu devrais commencer à maitriser les notations avec des * et des &.
Libérer la mémoire
Tu peux allouer de la mémoire avec des malloc ou des nex, mais quand tu n'as plus besoin de ces variables il faut les virer avec un free (en c) ou un delete (en c++)
P * plop = new P(); delete plop; int * plop2 = (int *) malloc(sizeof(int)); free(plop2);
Les références (c++ seulement)
En c++ on travaille plutôt avec des références. Il faut voir une référence comme un pointeur, sauf que tout ce passe comme si on manipulait directement la variable (en terme de
int i=2; int & k=i; k=3; //i vaut désormais 2 car k e i sont liés par les liens sacré de la reference ! int * p =& i; // pas besoin d'allouer car i a été alloué par le int i=2; *p=4; //i vaut désormais 4
Voilà si tu as des questions n'hésites pas ;-)
Bonne chance
Salut, j'espère ne pas être à côté de la plaque en te répondant
si je fais :
(les espaces n'ont aucune importance) je dis que ma variable P est un pointeur vers un entier.
donc P contient l'adresse de l'entier vers lequel il pointe. Pour connaitre la valeur de cet entier tu fais :
tu vois que dans les deux cas il est écrit " *P " mais un coup tu définis un pointeur, un autre coup tu regarde le contenu de l'objet pointé.
Si tu fais
ca veut dire que P est une classe et que tu dis que toto est un pointeur vers ta classe P. De même *toto est la valeur de l'objet pointé par toto
fais ceci :
#include<iostream>
int main()
{
int * p=NULL; // pour eviter d'avoir un pointeur fou on le met à NULL
int x=3;
p=&x; // p pointe vers la case mémoire de x
// affichage des adresses mémoires
std::cout<<p<<" "<<&x<<std::endl;
// affichage des valeurs des objets pointés
std::cout<<*p<<" "<<x<<std::endl;
*p=7;
// affichage des valeurs des objets pointés
std::cout<<*p<<" "<<x<<std::endl;
// -> x vaut maintenant 7 !!
return 0;
}
si je fais :
int * P;
(les espaces n'ont aucune importance) je dis que ma variable P est un pointeur vers un entier.
donc P contient l'adresse de l'entier vers lequel il pointe. Pour connaitre la valeur de cet entier tu fais :
*P
tu vois que dans les deux cas il est écrit " *P " mais un coup tu définis un pointeur, un autre coup tu regarde le contenu de l'objet pointé.
Si tu fais
P* toto;
ca veut dire que P est une classe et que tu dis que toto est un pointeur vers ta classe P. De même *toto est la valeur de l'objet pointé par toto
fais ceci :
#include<iostream>
int main()
{
int * p=NULL; // pour eviter d'avoir un pointeur fou on le met à NULL
int x=3;
p=&x; // p pointe vers la case mémoire de x
// affichage des adresses mémoires
std::cout<<p<<" "<<&x<<std::endl;
// affichage des valeurs des objets pointés
std::cout<<*p<<" "<<x<<std::endl;
*p=7;
// affichage des valeurs des objets pointés
std::cout<<*p<<" "<<x<<std::endl;
// -> x vaut maintenant 7 !!
return 0;
}
mixtape
Messages postés
18
Date d'inscription
mardi 15 novembre 2005
Statut
Membre
Dernière intervention
22 mai 2006
1
15 nov. 2005 à 21:52
15 nov. 2005 à 21:52
merci ;) ... mais autre chose .. vous pouvez m donner un exemple sur p* toto ....ca m aidra bien j croi
Salut, voici un exemple P* toto;
J'ai donc dis dans le précédent post que P est un type (une classe), par exemple une classe Voiture (ou une struct)
typedef struc ma_Voiture{
unsigned int nb_portes;
char * marque;
} Voiture;
Voiture * v=NULL; (analogie avec P* toto)
v->nb_portes=5;
v->marque="Renault";
version sans les pointeurs :
Voiture v2;
v2.nb_portes=5;
v2.marque="Renault";
J'espère que c'est un peu plus clair...
J'ai donc dis dans le précédent post que P est un type (une classe), par exemple une classe Voiture (ou une struct)
typedef struc ma_Voiture{
unsigned int nb_portes;
char * marque;
} Voiture;
Voiture * v=NULL; (analogie avec P* toto)
v->nb_portes=5;
v->marque="Renault";
version sans les pointeurs :
Voiture v2;
v2.nb_portes=5;
v2.marque="Renault";
J'espère que c'est un peu plus clair...
Salut!
je veux ecrire une fonction mirroir:
A savoir par exemple char*mirroir(char*string)
consiste a reverser un string. Comment puis je reussir avec la fonction strrev?
je veux ecrire une fonction mirroir:
A savoir par exemple char*mirroir(char*string)
consiste a reverser un string. Comment puis je reussir avec la fonction strrev?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
mamiemando
Messages postés
33545
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
25 février 2025
7 829
2 mai 2007 à 02:35
2 mai 2007 à 02:35
Merci d'ouvrir un nouveau post vu que ce problème n'a rien à voir avec le problème initial. La solution ;
Donne :
Bonne chance
#include <string.h> #include <stdio.h> #include <stdlib.h> void strrev(const char *str1,char *str2){ unsigned int i,n=strlen(str1); for(i=0;i<n;++i) str2[i] = str1[n-i-1]; } int main(){ const char *str1="tapir"; char *str2 = (char*)malloc(strlen(str1)*sizeof(char)); strrev(str1,str2); printf("%s --> %s\n",str1,str2); free(str2); return 0; }
Donne :
(mando@aldur) (~) $ gcc -W -Wall plop.c (mando@aldur) (~) $ ./a.out tapir --> ripat
Bonne chance