Besoin d'aide sur les pointeurs

Fermé
aladhia - 19 juin 2005 à 21:04
mamiemando Messages postés 33407 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 29 novembre 2024 - 20 juin 2005 à 00:06
bonjour a tous,

je suis étudiant en première année d'université,donc débutant en programmation, et je ne comprend pas l'utilisation des pointeurs,ni comment on peu redimensionne un tableau.Je souhaiterais avoir un petit d'aide sur les pointeur surtout au niveau de l'utilisation,et une réponse si possible a ma question sur les tableau.

Merci beaucoup .

2 réponses

bah mettons que tu declare un tableau:


main()
{
char tableau[80];
char *pointeur;
pointeur=&tableau;
fonction(pointeur);
}

le pointeur te permet de sauveagrder l'adresse d'un tableau ou de tout autre structure allouée dynamiquement et de la renvoyer sans la perdre.mettons que tu alloue dynamiquement une structure dans une fonction, en retournant le pointeur :


pointeur=(char*)malloc(80*sizeof(char));
return pointeur;

ainsi tu peux retourner l'adresse de cette structure , car si tu declarer un tableau normal, comme char tableau[80],tu perdrais le tableau alloué à la fin de ta fonction.
0
mamiemando Messages postés 33407 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 29 novembre 2024 7 806
20 juin 2005 à 00:06
Pour compléter ce qui est dit...

LA THEORIE

Un pointeur c'est une adresse. Comme en informatique le vide n'existe pas, si tu n'initialise pas cette adresse, elle contient une valeur aléatoire qui n'a aucun sens. Il s'agit de l'initialiser.

Or comme tu t'en doutes, on ne peut pas s'allouer de la mémoire n'importe où ! Sinon les autres programmes vont faire la tête. C'est pourquoi en C il y a la fonction malloc (et la petite soeur calloc) qui sert à trover une plage de mémoire libre et à la réserver.

Ainsi, si je reprends l'exemple :
char *pointeur=(char*)malloc(80*sizeof(char));

malloc cherche une zone mémoire de taille égale à 80 caractères. Il retourne la valeur. Mais malloc renvoie une adresse générique (void *), or dans cette exemple on alloue un tableau de caractère (en vue stocker une chaine de caractère ici). Il faut donc caster cette adresse : c'est le rôle du (char*).

Ok donc à ce stade, pointeur contient l'adresse du début de cette plage. On peut donc écrire sur les 80chars qui suivent ils sont reservés. Si ont ne les avait pas alloué on aurait eu le droit à une belle segmentation fault ;) Si d'ailleurs par la suite on sort de cette plage, on aura egalement une segmentation fault.

Cependant, il faudra penser à libérer cette zone mémoire qu'en tu n'en auras plus besoin (genre à la fin de ton programme mais peut-être pourras-tu le faire avant, auquel cas ne t'en prives pas ;o)). Tu le fait grâce à la fonction free :

free(pointeur);

LA PRATIQUE

Mais si c'est pour allouer 80 caractères, pourquoi ne pas directement faire un :
char[80] machaine;

En effet tu peux le faire ;) Comme en plus tu alloues ta variable de manière statique, le compilateur sait exactement ce qu'il aura à désallouer à la fin de la fonction ou tu l'as déclaré.

En fait en fait des malloc car bien souvent on ne connait pas la taille de se qu'on aura à stocker. On alloue la mémoire dynamiquement et ça on ne peut le faire qu'avec des malloc (inutile d'allouer une matrice 10000*10000 si une matrice 5*5 suffit ;o))

De plus allouer matrice[10000][10000] revient allouer 10000*10000 cases d'entiers contigues et c'est pas dit que ça le fasse ;o)

Autre interêts des pointeurs :
- quand tu stockes un pointeur, tu ne stocke qu'une adresse (qq octets) et non une copie de ce qui est pointé.
- tu sis qu'en C modifier un paramètre d'une fonction ne peut pas se faire (car on fait une copie des paramètre lors de l'appel d'une fonction). En gros si modifies un paramètre de fonction, la portée de la modification sera l'appel de cette fonction. Mais si tu passes l'adresse, tu peux modifier ce qui est pointé ;) Je m'explique

void f(int i){
i++; //l'incrémentation de l'entier i ne sera effective que dans f !!
}

void g(int *i){
(*i)++; //l'entier *i n'est pas paramètre de g() (c'est i) donc la modification aura bien lieu
}

Je te laisse jeter un oeil à ce topic ou on aborde le cas des matrices pour t'exercer :
http://www.commentcamarche.net/forum/affich-1612051-%5BC%5D-Pointeur-vers-tableau-Multidimensionnel?CCMSESSID=277ceb595d805053be9ddf5d4d394113

LES POINTEURS DE POINTEURS

Les pointeurs vont te permettre de définir des structures de données (liste chainées, matrices, graphes,....). Un pointeur ne pointe pas nécessairement directement vers un type de base (char/int...) : il peut aussi pointer :
- sur une structure : struct mystruct * pstruct;
- sur un pointeur : int * pint; int ** p_pint;

En effet une matrice n'est qu'en fait un tableau de tableau

matrice (int**) [ .....  matrice[i]=adresse d'un tableau d'int (int *) .....]
                                     |
                               matrice[i] (int*) [............... matrice[i][j]=int ...........]

En résumé :
dimension 0 : un entier : int
dimension 1 : liste d'entier : int *
dimension 2 : matrice d'entier (ie un tableau de pointeurs de type int *) : int **
...
0