Ceci est plus une requête curieuse qu'une question importante, mais pourquoi lors de l'impression hexadécimale avec un nombre à 8 chiffres avec des zéros non significatifs, est-ce que %#08X
ne présente pas le même résultat que 0x%08X
?
Lorsque j'essaie d'utiliser l'ancien, l'indicateur de formatage 08
est supprimé et il ne fonctionne pas uniquement avec 8
.
Encore une fois j'étais simplement curieux.
La partie #
vous donne un 0x
dans la chaîne de sortie. Le 0
et le x
comptent dans vos "8" caractères énumérés dans la partie 08
. Vous devez demander 10 caractères si vous voulez que ce soit la même chose.
int i = 7;
printf("%#010x\n", i); // gives 0x00000007
printf("0x%08x\n", i); // gives 0x00000007
printf("%#08x\n", i); // gives 0x000007
Changer également la casse de x
affecte le casse des caractères sortis.
printf("%04x", 4779); // gives 12ab
printf("%04X", 4779); // gives 12AB
Le "0x" compte pour le compte de huit caractères. Vous avez besoin de "%#010x"
.
Notez que #
ne pas ajoute le 0x à 0 - le résultat sera 0000000000
- alors vous devriez probablement utiliser "0x%08x"
de toute façon.
La conversion %#08X
doit précéder la valeur avec 0X
; cela est requis par la norme. Rien dans la norme n'indique que le #
doive modifier le comportement de la partie 08
de la spécification, si ce n'est que le préfixe 0X
est compté comme faisant partie de la longueur (vous pourriez donc vouloir/devez utiliser %#010X
. Si, comme moi, vous aimez votre hexagone présenté sous la forme 0x1234CDEF
, vous devez utiliser 0x%08X
pour obtenir le résultat souhaité. Vous pouvez aussi utiliser %#.8X
. et cela devrait également insérer les zéros au début.
Essayez des variantes du code suivant:
#include <stdio.h>
int main(void)
{
int j = 0;
printf("0x%.8X = %#08X = %#.8X = %#010x\n", j, j, j, j);
for (int i = 0; i < 8; i++)
{
j = (j << 4) | (i + 6);
printf("0x%.8X = %#08X = %#.8X = %#010x\n", j, j, j, j);
}
return(0);
}
Sur une machine RHEL 5, ainsi que sur Mac OS X (10.7.5), le résultat était:
0x00000000 = 00000000 = 00000000 = 0000000000
0x00000006 = 0X000006 = 0X00000006 = 0x00000006
0x00000067 = 0X000067 = 0X00000067 = 0x00000067
0x00000678 = 0X000678 = 0X00000678 = 0x00000678
0x00006789 = 0X006789 = 0X00006789 = 0x00006789
0x0006789A = 0X06789A = 0X0006789A = 0x0006789a
0x006789AB = 0X6789AB = 0X006789AB = 0x006789ab
0x06789ABC = 0X6789ABC = 0X06789ABC = 0x06789abc
0x6789ABCD = 0X6789ABCD = 0X6789ABCD = 0x6789abcd
Je suis un peu surpris par le traitement de 0; Je ne comprends pas pourquoi le préfixe 0X
est omis, mais avec deux systèmes distincts, il doit être standard. Cela confirme mes préjugés contre l'option #
.
Le traitement de zéro est conforme à la norme.
ISO/CEI 9899: 2011 §7.21.6.1 La fonction
fprintf
¶6 Les drapeaux et leur signification sont les suivants:
...#
Le résultat est converti en une "forme alternative". ... Pour la conversionx
(ouX
), a non nulle résultat a le préfixe0x
(ou0X
). ...
(Soulignement ajouté.)
Notez que l'utilisation de %#X
utilisera des lettres majuscules pour les chiffres hexadécimaux et 0X
comme préfixe; utiliser %#x
utilisera des lettres minuscules pour les chiffres hexadécimaux et 0x
comme préfixe. Si vous préférez 0x
comme préfixe et lettres majuscules, vous devez coder le 0x
séparément: 0x%X
. Bien entendu, d'autres modificateurs de format peuvent être ajoutés.
Pour imprimer les adresses, utilisez l'en-tête <inttypes.h>
, le type uintptr_t
et la macro de formatage PRIXPTR
:
#include <inttypes.h>
#include <stdio.h>
int main(void)
{
void *address = &address; // &address has type void ** but it converts to void *
printf("Address 0x%.12" PRIXPTR "\n", (uintptr_t)address);
return 0;
}
Exemple de sortie:
Address 0x7FFEE5B29428
Choisissez votre poison sur la longueur - Je trouve qu’une précision de 12 convient bien aux adresses des Mac fonctionnant sous MacOS. Associé au .
pour spécifier la précision minimale (chiffres), il formate les adresses de manière fiable. Si vous définissez la précision sur 16, les 4 chiffres supplémentaires sont toujours égaux à 0 dans mon expérience sur Mac, mais il est certainement judicieux d'utiliser 16 dans le code portable 64 bits au lieu de 12 (mais vous utiliseriez 8 pour Code 32 bits).