[ad_1]
Bonjour !
J’ai une petite question, je me demandais quel type de distribution change. Par exemple :
#include <stdio.h> #include <stdlib.h> int main() { int *x; char *y; float *z; x = (int*)y; y = (char*)z; return 0; }
Je me demandais si quelque chose changeait pour être honnête.
Qu’est ce que je veux dire ? L’arithmétique des pointeurs est basée sur les pointeurs eux-mêmes et non sur la valeur qu’ils ont.
Par exemple, si le pointeur “x” est un entier et qu’il pointe vers un caractère arithmétique x+1 ou x+i, la taille de est basée sur le type de “x” et non sur le type de “y”.
Alors pourquoi devons-nous changer la distribution des autres variables ?
Essentiellement :
#include <stdio.h> #include <stdlib.h> int main() { int *x; char *y; x = (int*)y; x = (char*)y; return 0; }
Cela ne devrait rien changer.
Je suis conscient que mélanger les types n’est pas une bonne idée, mais j’étais un peu mélangé avec le casting des types pour être honnête.
PS.
J’ai trouvé quelques exemples à quoi cela ressemble de changer la conversion de type :
Citation:*(int *)((char *)ptr + 2*sizeof(int))
Je ne savais pas vraiment ce qui se passait ici et pourquoi le type ptr est modifié deux fois. C’est quelque chose à propos de l’arithmétique des pointeurs mais j’ai imaginé que si j’ai ptr + 1 alors c’est (ptr+1*sizeof(int)), et ici j’ai (char*) et un autre (int*) donc j’ai (ptr +1*sizeof(int)) fois sizeof(char) puis fois sizeof(int) ???? Bizarre.
Ce que j’ai essayé :
J’ai essayé de réfléchir principalement à la raison pour laquelle il en est ainsi lorsque le pointeur prend simplement l’adresse, alors pourquoi changer le type.
Solution 2
Les caractères pointus ont des tailles différentes, ce qui rend les choses intéressantes lors de l’exécution de l’arithmétique des pointeurs.
De plus, l’interprétation des modèles de bits des types pointés est différente, donc les choses deviennent encore plus intéressantes lorsque vous essayez de déférencer les pointeurs.
Si vous savez ce que vous faites, cela pourrait être utile. Par exemple, le code suivant
#include <stdio.h> int main() { float f = -0.25; printf("%04X", *(unsigned int *) &f); }
les sorties
BE800000
C’est le modèle de bits du float
selon le IEEE 754
standard.
Solution 3
Une distribution n’apporte aucune modification aux données. Cela peut être considéré comme un signal au compilateur indiquant que “oui, je sais que x et y sont de types différents, mais faites quand même la mission !”. Le compilateur organise ensuite une copie bit par bit de x vers y. Si vous obtenez un changement de valeur, ce sera à cause de la différence de taille de la source et de la cible, par exemple
int i = 256; /* 0x100 */ char c = i; /* c will be assigned 0x00 ie. last byte of i */
Vous devez être prudent lors de la diffusion entre des pointeurs de différents types. En général, un pointeur char (un pointeur vers un seul octet) n’a aucune exigence d’alignement, mais d’autres types, par exemple un int, peuvent exiger qu’il soit aligné sur une limite de 4 octets (ou 2, 8 ou 16, etc. selon le type). Dans ce cas, vous pourriez obtenir une erreur de segmentation lorsque vous essayez de déréférencer un pointeur. par exemple
char str[5] = { 0x00, 0x00, 0x00, 0x00, 0x0 }; /* a 5 byte string, all zeros */ int *i = (int *)&(str[0]); printf("*i = %d\n", *i); i = (int*)(&str[1]); printf("*i = %d\n", *i);
Compte tenu des contraintes ci-dessus, l’une des deux instructions printf produira une erreur de segmentation, car l’un ou l’autre des pointeurs int est mal aligné selon les exigences du processeur. Vous devez donc faire attention à ce que vous faites lorsque vous transmettez des pointeurs d’un type à un autre. Noter que malloc()
et les appels associés sont garantis de renvoyer un pointeur correctement aligné pour n’importe quel type, vous n’avez donc aucun problème à le faire type *ptr = (type*)malloc(sizeof(*ptr) * 42)
Solution 1
Si vous faites +1 sur un pointeur, cela déplace le pointeur vers l’adresse suivante après le type.
Si vous faites +1 sur un pointeur vers un flottant de 4 octets, alors l’adresse augmentera de 4 octets.
Si vous faites +1 sur un pointeur vers un double de 8 octets, cela augmentera de 8 octets.
pour comprendre pourquoi il y a 2 castings, il faut regarder les parenthèses.
La conversion en char est généralement effectuée car elle oblige toute arithmétique de pointeur à utiliser « 1 » comme taille avec laquelle compter.
Donc traiter ptr comme un char* puis ajouter 2 fois la taille d’un int (qui serait 4 dans un système 32 ou 64 bits par défaut). cela signifie que vous essayez de lire un int, 8 octets supprimés de ptr.
Une façon beaucoup plus simple d’écrire cela serait
*((int *)ptr + 2)
Ou si ptr est déjà de type int*, faites simplement
*(ptr + 2)
[ad_2]
コメント