web-dev-qa-db-fra.com

Pointeurs et tableaux C: l'affectation [Avertissement] crée un pointeur à partir d'un entier sans transtypage

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.

16
user2274889

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]).

23
Dipto

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.

7
halfbit

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.

0
njzk2