Pourquoi ne pouvons-nous pas utiliser “%d”, en langage C, au lieu de “%u” avec des pointeurs?
%u
est utilisé pour les nombres non signés.
J'obtiens les mêmes résultats si j'utilise %d
au lieu de %u
pour afficher l'adresse d'une variable.
Nous utilisons %u
juste pour l'éthique ou faut-il faire une différence trop.
Regardez:
int i=5;
printf("Address of i: %d", &i);
est la même que:
printf("Again, address: %u" ,&i);
[EDIT] Un exemple où il génère un résultat différent serait appréciée.
- Eh bien, je ne peux pas imaginer un négatif d'adressage virtuel. Et ne devriez-vous pas être à l'aide de
%p
? - Comment imprimer une adresse à l'aide
%d
? N'êtes-vous pas d'impression de la valeur d'ordures? - Suis en train de lire le livre "Laissez-nous C" Il utilisé '%u' tout le temps
- Mauvais livre, plein d'erreurs. à éviter.
- La valeur de
&i
va varier comme vous le compiler/exécuter le code. Ce n'est pas nécessairement déterministe. - Les résultats de l'un ne sont pas définis par la norme du langage C.
Vous devez vous connecter pour publier un commentaire.
%d
affichera une valeur négative pour les adresses avec le bit le plus significatif (haut adresses)%u
sera toujours montrer l'interprétation positive de l'bits%p
est le meilleur, car il est explicitement réservée pour l'impression des adresses.Considérez ceci, en supposant une adresse de
0xffffffff
.Et, il est de sortie:
%d
et%u
sont juste totalement faux.Vous pouvez traverser la rue sans regarder de nombreuses fois, et vous pourriez ne pas être frappé par une voiture. Cela ne veut pas dire que c'est une bonne idée.
Lors de l'impression des pointeurs en C, vous devez utiliser
%p
, pas%u
ou%d
.%u
et%d
sont destinés à l'affichage des valeurs entières. Vous êtes implicitement le moulage de votre pointeurs vers des entiers quand vous utilisez ces options pour imprimer les pointeurs et il y a pas mal d'architectures ont été cela peut causer beaucoup de problèmes (en particulier dans les architectures 64 bits).La différence entre
%d
et%u
est comme vous l'avez mentionné,%u
traite de la valeur non signée et%d
signé. Les résultats seront différents si l'ordre le plus élevé bit est à 1. Vous pouvez le voir facilement lors de l'utilisation de -1.De sortie:
En fait, même
"%u"
l'est pas; pour les pointeurs, vous devez utiliser"%p"
Encore,
%d
-au lieu de%u
fonctionne parce que votre architecture signés et non signés nombres ont le même représentation autant que nous sommes à la recherche à un nombre positif. Donc, si vous passez un pointeur vers%d
,printf
va essayer de interprète le paramètre comme un entier signé, et vous obtiendrez le même résultat de%u
tant que le bit en position haute de l'aiguille n'est pas définie (ce qui est généralement la norme pour le mode utilisateur pointeurs); sinon, vous obtiendrez un nombre négatif avec%d
et positive avec%u
(en supposant que votre machine emploie 2 en complément de l'arithmétique).Fait intéressant, l'erreur la plus importante n'est pas la désadaptation ce paramètre, mais à l'aide d'entiers specificators (
%d
et%u
) au lieu du pointeur specificator (%p
); dans les faits, sur la plupart des architectures 64 bitsint
est de 32 bits, maisvoid *
est de 64 bits, donc à l'aide de%u
au lieu de%p
permettra d'imprimer seulement la moitié de l'adresse (la moitié inférieure sur little-endian architectures, comme x86_64).Avis: tout cette explication provient de "typique des implémentations" du langage C; dans la mesure où la norme est concerné, si vous incompatibilité de type de format specificator et des données réelles, vous allez dans "un comportement indéfini" (=tout à partir d'un crash de rose licornes volant de votre imprimante).
Des architectures des processeurs où un pointeur a une représentation différente ou que la taille d'un nombre non signé.
Un exemple commun est de 32 bits x86 code écrit en segmenté mode, où une adresse se compose d'un segment de 16 bits avec un numéro de segment de 32 bits à décalage. (Avertissement: cela fait des années depuis que j'ai regardé ça, donc j'ai peut-être oublié les détails.)
Un autre cas est une machine 64 bits configuré pour l'utilisation de pointeurs 64-bit et 32-bit ints.