7
votes

Qu'est-ce qui arrive réellement quand un pointeur entier est jeté à un pointeur à caractère?

int i=40;
char *p;
p=(char *)&i;//What actually happens here?
printf("%d",*p);
What will be the output? Please help!

0 commentaires

5 Réponses :


2
votes

ici, vous êtes

int i = 40; // allouant la mémoire pour iTeger I et attribution de la valeur 40 à celle-ci xxx donc Ici, vous définissez une variable de pointeur et vous l'attribuez à l'adresse de i après la jeter à char *

Supposons i est alloué à 1021 adresse de sorte que p aura cette adresse avec la limite de 1 octet afin de pouvoir contenir à 8 bits de la représentation de 40;

tandis que 40 a été couvert Premier 8 bit de 2 octets, il tiendra un équivalendue de 40, mais comme vous l'imprimez avec % d idio shopuld impression 40


2 commentaires

Sauf que la machine pourrait être grosse Endian dans ce cas, vous obtiendrez 0.


Pourquoi est-il nécessaire, quelle est la différence entre char * p = (char *) & i et char * p = & i ?



7
votes
p=(char *)&i;//What actually happens here?
It takes the address of i and casts it to a char pointer. So the value of *p is now the first byte of i. What that value is, is platform dependent.

2 commentaires

Très probablement ce serait 0 ou 40 (selon l'endansion de la machine).


Pourquoi est-il nécessaire, quelle est la différence entre char * p = (char *) & i et char * p = & i ?



1
votes

Cela dépend. Sous Windows, la sortie durera 40 ans, mais cela est juste à cause de beaucoup de coïncidences:

Tout d'abord, Printf ne vérifie pas le type de ses arguments, de sorte que, puisqu'il voit% d dans la chaîne de format, il suppose que l'argument donné est un int. Bien que * p n'est qu'un caractère, le résultat est favorisé à un Int (comme pour chaque argument non spécifié dans le prototype de fonction).

Deuxièmement, P pointera sur la mémoire prise par la variable I, mais comme c'est un pointeur de caractère, il ne prendra qu'un octet de la mémoire de i. Étant donné que Windows / Intel utilise la première convention d'octet moins important-octet, 40 sera stockée comme modèle d'octet "40 0 0 0", car * p prend le premier octet (char), le résultat sera de 40. Si j'aurais le Valeur 256 ou plus grande, le résultat serait incorrect.


1 commentaires

6
votes

Commençons par la recherche de savoir comment le contenu de i code> et p code> serait aménagé en mémoire (en supposant l'ordre de Big-Endian):

Item               Address               0x03  0x02  0x01  0x00
----               -------               ----------------------
   i               0x08000000            0x00  0x00  0x00  0x28
   p               0x08000004            0x08  0x00  0x00  0x00


7 commentaires

Votre description suppose que int * et char * Les pointeurs ont la même taille et la même présentation, mais le comportement visible du programme ne le fait pas. La standard C garantit que tout objet est accessible en tant que réseau de caractères. Le code de l'OP accédera donc au premier octet (adressé le plus bas) de i . La valeur de cet octet, comme d'autres l'ont souligné, dépend de la mise en œuvre.


@Keiththompson Pourquoi est-ce que la diffusion est nécessaire, quelle est la différence entre char * p = (char *) & i et char * p = & i ?


Pourquoi est-il nécessaire, quelle est la différence entre char * p = (char *) & i et char * p = & i ?


@Surajjain: La différence est que char * p = (char *) & i; Islegal et Char * p = & I; n'est pas. Il n'y a pas de conversion implicite entre char * et int * (bien que certains compilateurs puissent le permettre, de préférence avec un avertissement). Les conversions du pointeur peuvent être dangereuses, vous permettant de traiter un objet d'un type comme s'il s'agissait d'un autre type, la langue nécessite donc de telles conversions pour être explicites.


@Keiththompson Si le compilateur le permet avec une guerre, comme "l'initialisation de type incompatible", sont-ils identiques, ils se comportent-ils même. Cela me dérange depuis longtemps.


@Surajjain: Les premières versions de C étaient plus laxistes sur des conversions implicites. Les règles ont été resserrées par la norme ANSI de 1989, mais de nombreux compilateurs permettent de telles conversions pour éviter de casser l'ancien code. Char * p = & I; est une violation de contrainte, nécessitant un diagnostic. Ce diagnostic (malheureusement, IMHO) peut être un avertissement non mortel. Il n'est pas clair si le comportement est défini ou non. Vous devez prendre des avertissements au sérieux; Traitez-les comme des erreurs fatales, sauf si vous êtes sûr que votre code a raison et que le compilateur est faux.


@Keiththompson OK, monsieur, pouvez-vous vérifier cette question, j'ai demandé ce long retour, je lui ai répondu quand les choses étaient claires pour moi, je veux juste m'assurer que je n'éside personne. Stackoverflow.com/questions/34826036/...