donc on n'utilise pas de free si on a pas utilisé malloc! Oui ! (malloc ou calloc, ou tout autre fonction d'allocation mémoire dynamique).
si le sizeof(int)= 8 oct, donc le pointeur incrémente de 8 oct! Oui (à ceci près que que sizeof(int) = 4 octets soit 32 bits sur une architecture 32 bits)
donc si les tableau sont une imagination pour facilité l'utilisation, Oui
donc le tableau est un char?! Non !
Quand tu écris :
int p[100];
celà signifie que tu alloues un bloc de 100 entiers en tant qu'espace. Cet espace débute à l'adresse p. En mémoire... c'est juste un espace mémoire. La notion de type ne permet au compilateur que de savoir dimensionner un espace mémoire. Par exemple un int est encodé sur 32 bits, un char est codé sur 8 bits etc...
Une fois alloué, tu peux utiliser cet espace mémoire comme tu le souhaites. Par exemple dans l'exemple de mon message précédent, pi était à priori un espace prévu pour accueillir 100 entiers, or avec pc je l'ai détourné pour en faire un espace dans lequel stocker des caractères. Mais en soi, c'est juste un espace mémoire.
Bon mais attention, ne me fais pas dire ce que je n'ai pas dit. Si tu as besoin de stocker un tableau de caractère il est plus logique de déclarer un char[100] ou d'allouer avec un malloc un espace mémoire pointé par un char * :
char *buffer = (char *)malloc(sizeof(char)*100);
...
free(buffer);
À partir de là, tu dois avoir compris qu'écrire char buffer[100] revient à allouer un bloc contigu de mémoire dont la taille fait 100*sizeof(char) et que cet espace est situé à l'adresse p. Ecrire par la suite p[i] revient à évaluer (vu que p est un char *) l'espace de taille sizeof(char) situé à l'adresse p décalée i*sizeof(char).
B o n j o u r \0
0 1 2 3 4 5 6 7
Ici :
p[0] = 'B'
p[1] = 'o'
...
Maintenant pour achever de te convaincre que c'est de la mémoire et vu que sizeof(int) = 4 * sizeof(char), si tu écris :
int * pi = p;
... alors écrire pi[0] revient à évaluer les bits formés par la concaténation des bits formés par les caractères "Bonj" (c'est-à-dire p[0],p[1],p[2],p[3]) en tant qu'un entier. Ok ça va faire une valeur en carton pâte, mais d'un point de vue mémoire c'est la même chose.
Mais bon là je tombe un peu dans le détail, concrètement tu n'as jamais à te poser ce genre de question.
Ce que tu dois retenir c'est que :
- déclarer un tableau équivaut à déclarer un bloc de mémoire contigu
- écrire p[i] équivaut à écire *(p+i)
- qui dit malloc (ou autre fonction d'allocation mémoire) dit free (et uniquement dans ce cas)
- évaluer ce qui se trouve à une adresse mémoire invalide provoque une erreur de segmentation (c'est typiquement ce qui se passe quand tu accèdes à la cases 101 d'un tableau de 100 éléments, tu sors de ton espace mémoire).
- une variable locale est désallouée à la fin du scope
- un paramètre de fonction est une recopie de la variable passée lors de l'appel de cette fonction.
J'en profite pour faire une digression sur ce dernier point :
#include <stdio.h>
int f(int x){ // ce x est une recopie du x du main
++x;
printf("%d\n",x); // la copie est incrémentée
}
int f2(int *x){ // la valeur recopiée est l'adresse de x
++(*x); // ... donc ici, c'est bien la variable x du main que je modifie
printf("%d\n",*x);
}
int main(){
int x = 3;
f(x); // écrit 4 (la copie est incrémentée)
printf("%d\n",x); // écrit 3, car la variable x du main vaut toujours 3
f(*x); // écrit 4 (x est bien incrémenté)
printf("%d\n",x); // écrit 4
return 0;
}
Si tu as tout compris, tu sais tout ce qu'il est important de savoir sur les pointeurs ;-)
Il reste deux trois notions sur les const à voir mais c'est à peu près tout.
Bonne chance