Rigolo.
Déjà, tu devrais avoir au moins un avertissement. Dans la norme, il n’est pas écrit que les pointeurs sont compatibles entre eux (sauf pour char*
et void*
). Tu dois caster en void*
pour signifier que tu souhaites réellement faire cette conversion.
Bref, peu importe ce que dit la norme, les compilo laissent un warning et compilent. C’est un peu la philosophie du C.
Ici, le résultat est vraiment dépendant de là où tu exécutes le code. Tu es très certainement sur une architecture little-endian. C’est pour ça que ça marche. Sur une autre architecture, ça ne devrait pas marcher.
L’idée, c’est que 'E'
est stocké sur le premier octet du int
et donc quand le pointeur sur char*
accède à cet endroit, il accède à la bonne valeur.
Dans le sens contraire, quand c
est de type char
, quand le pointeur sur int déréférence ce pointeur, il déréférence le int
stocké ici. C’est-à-dire, autant d’octets dont il a besoin (certainement 4 octets). Mais seul le premier est finalement affiché car tu utilises %c
.
Dans les deux cas, en big endian, tu aurais eu un comportement différent (la première fois, ça aurait affiché 0, la seconde un nombre au hasard).
Dans tous les cas, dans le second cas, tu accèdes à de la mémoire non allouée donc il est tout à fait possible que le programme segfault.
Pour répondre à ta question, le type d’un pointeur est nécessaire pour plusieurs choses.
- Au déréférencement. Un
char*
ne va déréférencer que 1 octet alors qu’un double en déréférencera certainement 8.
- Pour l’arithmétique des pointeurs. Incrémenté un
char*
va augmenter sa valeur de 1. Alors qu’incrémenté un int*
va augmenter sa valeur de sizeof(int)
. C’est cohérent, quand j’incrémente un pointeur de char, je veux le prochain char. Quand j’incrémente un pointeur de int*
, je veux le prochain int
, pas un truc bizarre qui est entre les deux.
En espérant t’avoir éclairé.e