A %#08X
conversão deve preceder o valor com 0X
; isso é exigido pelo padrão. Não há nenhuma evidência no padrão de que isso #
deva alterar o comportamento da 08
parte da especificação, exceto que o 0X
prefixo é contado como parte do comprimento (então você pode querer / precisar usar %#010X
. Se, como eu, você gosta do seu hexadecimal apresentado como 0x1234CDEF
, você precisa usar 0x%08X
para obter o resultado desejado.Você pode usar %#.8X
e isso também deve inserir os zeros à esquerda.
Tente variações no seguinte código:
#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);
}
Em uma máquina RHEL 5 e também no Mac OS X (10.7.5), a saída era:
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
Estou um pouco surpreso com o tratamento de 0; Não sei por que o 0X
prefixo foi omitido, mas com dois sistemas separados, ele deve ser padrão. Isso confirma meus preconceitos contra a #
opção.
O tratamento do zero é de acordo com o padrão.
¶6 Os caracteres da bandeira e seus significados são:
...
#
O resultado é convertido em uma "forma alternativa". ... Parax
(ou X
) conversão, um resultado diferente de zero tem 0x
(ou 0X
) um prefixo para ele. ...
(Enfase adicionada.)
Observe que usar %#X
usará letras maiúsculas para os dígitos hexadecimais e 0X
como prefixo; use %#x
usará letras minúsculas para os dígitos hexadecimais e 0x
como prefixo. Se você preferir 0x
que as letras de prefixo e maiúsculas, você tem que código 0x
separadamente: 0x%X
. Outros modificadores de formato podem ser adicionados conforme necessário, é claro.
Para imprimir endereços, use o <inttypes.h>
cabeçalho, o uintptr_t
tipo e a PRIXPTR
macro de formato:
#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;
}
Exemplo de saída:
Address 0x7FFEE5B29428
Escolha seu veneno no comprimento - acho que uma precisão de 12 funciona bem para endereços em um Mac executando o macOS. Combinado com o .
para especificar a precisão mínima (dígitos), ele formata os endereços de maneira confiável. Se você definir a precisão como 16, os 4 dígitos extras serão sempre 0 na minha experiência no Mac, mas certamente há um argumento a ser usado para usar 16 em vez de 12 no código portátil de 64 bits (mas você usaria 8 para Código de 32 bits).
0x%.8X
? Isso irá preencher com zeros. (o0x
é apenas um preâmbulo, mas você provavelmente já está ciente disso).