Question

Disons que nous avons le code suivant:

int main(){
    int a[3]={1,2,3};
    printf("      E: 0x%x\n", a);
    printf("  &E[2]: 0x%x\n", &a[2]);
    printf("&E[2]-E: 0x%x\n", &a[2] - a);
    return 1;
}

Une fois compilés et exécutés, les résultats sont les suivants:

      E: 0xbf8231f8
  &E[2]: 0xbf823200
&E[2]-E: 0x2

Je comprends le résultat de & amp; E [2] qui correspond à 8 plus l'adresse du tableau, car indexé par 2 et de type int (4 octets sur mon système 32 bits), mais je Vous ne pouvez pas comprendre pourquoi la dernière ligne est 2 au lieu de 8?

De plus, quel type de la dernière ligne devrait être - un entier ou un pointeur d'entier?

Je me demande si c’est le système de type C (un peu de casting) qui fait cette bizarrerie?

Était-ce utile?

La solution

Vous devez vous rappeler ce que l'expression a [2] signifie vraiment. C'est exactement équivalent à * (a + 2) . À tel point qu'il est parfaitement légal d'écrire 2 [a] à la place, avec un effet identique.

Pour que cela fonctionne et qu’il ait un sens, l’arithmétique de pointeur prend en compte le type de la chose pointée. Mais cela est pris en charge dans les coulisses. Vous devez simplement utiliser des décalages naturels dans vos tableaux, et tous les détails sont calculés.

La même logique s'applique aux différences de pointeur, ce qui explique votre résultat de 2 .

Sous le capot, dans votre exemple, l'index est multiplié par sizeof (int) pour obtenir un décalage d'octet ajouté à l'adresse de base du tableau. Vous exposez ce détail dans vos deux empreintes d'adresses.

Autres conseils

Lorsque vous soustrayez des pointeurs du même type, le résultat est le nombre d'éléments et non le nombre d'octets. Ceci est voulu par la conception de sorte que vous puissiez facilement indexer des tableaux de tout type. Si vous voulez le nombre d'octets, convertissez les adresses en char *.

Lorsque vous incrémentez le pointeur de 1 (p + 1), celui-ci pointe sur la prochaine adresse valide en ajoutant (p + sizeof (Type)) octets à p. (si Type est int, alors p + sizeof (int))

Une logique similaire est également valable pour p-1 (bien sûr, soustrayez dans ce cas).

Si vous appliquez simplement ces principes ici:

En termes simples:

a[2] can be represented as (a+2)
a[2]-a      ==>  (a+2) - (a)    ==> 2

Donc, derrière la scène,

a[2] - a[0]  
==> {(a+ (2* sizeof(int)) ) - (a+0) }  / sizeof(int) 
==> 2 * sizeof(int) / sizeof(int) ==> 2

La ligne & E [2] -2 effectue une soustraction de pointeur, pas une soustraction d’entier. La soustraction de pointeur (lorsque les deux pointeurs pointent sur des données du même type) renvoie la différence des adresses divisée par la taille du type qu’elles pointent. La valeur de retour est un int.

Pour répondre à votre " mise à jour " question, encore une fois arithmétique de pointeur (cette addition de pointeur de temps) est en cours d'exécution. C’est fait de cette façon en C pour faciliter la " index " un bloc de données contiguë pointé par le pointeur.

Vous pourriez être intéressé par la arithmétique de pointeur en C et ses réponses.

En gros, les opérateurs + et - tiennent compte de la taille de l’élément lorsqu’ils sont utilisés sur des pointeurs.

Lors de l'ajout et de la soustraction de pointeurs en C, vous utilisez la taille du type de données plutôt que des adresses absolues.

Si vous avez un pointeur int auquel vous ajoutez le nombre 2, il avancera de 2 * sizeof (int). De la même manière, si vous soustrayez deux pointeurs int, vous obtiendrez le résultat en unités de sizeof (int) plutôt que la différence des adresses absolues.

(Avoir des pointeurs utilisant la taille du type de données est très pratique, vous pouvez par exemple simplement utiliser p ++ au lieu d'avoir à spécifier la taille du type à chaque fois: p + = sizeof (int) .)

un entier / nombre. du même coup que: Aujourd'hui - 1er avril = nombre. pas date

Si vous voulez voir la différence d'octet, vous devez définir un type de taille égale à 1 octet, comme ceci:

printf("&E[2]-E:\t0x%x\n",(char*)(&a[2])-(char*)(&a[0]))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top