J'ai des problèmes avec les pointeurs et les tableaux en C. Voici le code:
#include<stdio.h>
int *ap;
int a[5]={41,42,43,44,45};
int x;
int main()
{
ap = a[4];
x = *ap;
printf("%d",x);
return 0;
}
Lorsque je compile et exécute le code, j'obtiens cet avertissement:
L'affectation [Avertissement] crée un pointeur à partir d'un entier sans transtypage [activé par défaut]
Pour la ligne numéro 9 (ap = a [4];) et le terminal plante. Si je change la ligne 9 pour ne pas inclure de position (ap = a;) je ne reçois aucun avertissement et cela fonctionne. Pourquoi cela arrive-t-il? J'ai l'impression que la réponse est évidente mais je ne la vois tout simplement pas.
Dans ce cas, a[4]
Est l'entier 5th
Dans le tableau a
, ap
est un pointeur sur un entier, vous affectez donc un entier à un pointeur et c'est l'avertissement.
Donc ap
contient maintenant 45
Et lorsque vous essayez de le dé-référencer (en faisant *ap
) Vous essayez d'accéder à une mémoire à l'adresse 45, qui est une adresse invalide, donc votre programme plante.
Vous devez faire ap = &(a[4]);
ou ap = a + 4;
Dans c
les noms de tableau se désintègrent en pointeur, donc a
pointe vers le 1er élément du tableau.
De cette façon, a
est équivalent à &(a[0])
.
Que faites-vous: (j'utilise des octets au lieu d'en pour une meilleure lecture)
Vous commencez par int *ap
et ainsi de suite, de sorte que votre mémoire (celle de vos ordinateurs) ressemble à ceci:
-------------- memory used by some one else --------
000: ?
001: ?
...
098: ?
099: ?
-------------- your memory --------
100: something <- here is *ap
101: 41 <- here starts a[]
102: 42
103: 43
104: 44
105: 45
106: something <- here waits x
permet de voir ce qui se passe quand (imprimer un raccourci pour ... imprimer ("$ d", ...)
print a[0] -> 41 //no surprise
print a -> 101 // because a points to the start of the array
print *a -> 41 // again the first element of array
print a+1 -> guess? 102
print *(a+1) -> whats behind 102? 42 (we all love this number)
et ainsi de suite, donc a [0] est identique à * a, a [1] = * (a + 1), ....
a [n] se lit simplement plus facilement.
maintenant, que se passe-t-il à la ligne 9?
ap=a[4] // we know a[4]=*(a+4) somehow *105 ==> 45
// warning! converting int to pointer!
-------------- your memory --------
100: 45 <- here is *ap now 45
x = *ap; // wow ap is 45 -> where is 45 pointing to?
-------------- memory used by some one else --------
bang! // dont touch neighbours garden
Donc, "l'avertissement" n'est pas seulement un avertissement, c'est une grave erreur.
int[]
et int*
sont représentés de la même manière, sauf int [] allocates (IIRC).
ap
est un pointeur, donc lui donner la valeur d'un entier est dangereux, car vous n'avez aucune idée de ce qui se trouve à l'adresse 45.
lorsque vous essayez d'y accéder (x = *ap
), vous essayez d'accéder à l'adresse 45, ce qui provoque le blocage, car il ne fait probablement pas partie de la mémoire à laquelle vous pouvez accéder.