Waarom geeft %#08X
niethetzelfde resultaat weer als 0x%08X
?
Als ik de eerste probeer te gebruiken, wordt de opmaakvlag 08
verwijderd en werkt het niet alleen met 8
.
Antwoord 1, autoriteit 100%
Het #
gedeelte geeft je een 0x
in de output string. De 0
en de x
tellen mee voor uw “8”-tekens in het 08
-gedeelte. Je moet om 10 tekens vragen als je wilt dat het hetzelfde is.
int i = 7;
printf("%#010x\n", i); // gives 0x00000007
printf("0x%08x\n", i); // gives 0x00000007
printf("%#08x\n", i); // gives 0x000007
Ook het wijzigen van de hoofdletters van x
heeft invloed op de hoofdletters van de uitgevoerde tekens.
printf("%04x", 4779); // gives 12ab
printf("%04X", 4779); // gives 12AB
Antwoord 2, autoriteit 19%
De “0x” telt mee voor het aantal tekens van acht tekens. Je hebt "%#010x"
nodig.
Merk op dat #
nietde 0x aan 0 toevoegt – het resultaat zal 0000000000
zijn – dus u moet waarschijnlijk gewoon "0x%08x"
toch.
Antwoord 3, autoriteit 12%
De %#08X
conversie moet voorafgaan aan de waarde met 0x
; dat vereist de norm. Er is geen bewijs in de standaard dat het #
het gedrag van het 08
deel van de specificatie zou moeten veranderen, behalve dat het 0x
voorvoegsel als onderdeel wordt geteld van de lengte (dus misschien wil/moet je %#010X
gebruiken. Als je, net als ik, je hex wilt presenteren als 0x1234CDEF
, dan moet je 0x%08X
om het gewenste resultaat te bereiken. Je zou %#.8X
kunnen gebruiken en dat zou ook de voorloopnullen moeten invoegen.
Probeer variaties op de volgende code:
#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);
}
Op een RHEL5-machine, en ook op Mac OS X v10.7.5(Lion), de output was:
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
Ik ben een beetje verbaasd over de behandeling van 0; Ik ben niet duidelijk waarom de 0x
voorvoegsel wordt weggelaten, maar met twee gescheiden systemen te doen, het moet standaard zijn. Het bevestigt mijn vooroordelen tegen de #
optie.
De behandeling van nul komt overeen met de standaard.
ISO / IEC 9899: 2011 §7.21.6.1 De
fprintf
¶6 De vlag personages en hun betekenis zijn:
…
#
Het resultaat wordt omgezet in een “variant”. Voor …x
(ofx
)
conversie, een niet-nul resultaat moet0x
(of0x
) vooraf aan. …
(nadruk toegevoegd).
Merk op dat met %#X
gebruiken hoofdletters voor hexadecimale cijfers en 0x
als voorvoegsel; met %#X
gebruiken kleine letters voor hexadecimale cijfers en 0x
als voorvoegsel. Als u liever 0x
als voorvoegsel en hoofdletters, moet u de code van de 0x
afzonderlijk: 0x%X
. Andere formaat modifiers kunnen worden toegevoegd als nodig is, natuurlijk.
Voor het afdrukken van adressen, gebruikt u de <inttypes.h>
header en de uintptr_t
type en de PRIXPTR
formaat macro:
#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;
}
Resultaat:
Address 0x7FFEE5B29428
Kies je gif op de lengte — ik vind dat een precisie van 12 goed werkt voor adressen op een Mac met macOS. Gecombineerd met de .
om de minimale precisie (cijfers) te specificeren, maakt het adressen betrouwbaar op. Als je de precisie instelt op 16, zijn de extra 4 cijfers altijd 0 in mijn ervaring op de Mac, maar er is zeker een argument om 16 te gebruiken in plaats van 12 in draagbare 64-bits code (maar je zou 8 gebruiken voor 32-bits code).
Antwoord 4, autoriteit 2%
#
zorgt ervoor dat 0x
(of 0x
voor %#X
) aan de uitvoer wordt toegevoegd, tenzij de waarde is 0
, dus u moet #
niet gebruiken als u wilt dat 0x
altijd in de uitvoer verschijnt.
U kunt het breedteveld in combinatie met de vlag 0
gebruiken om voorloopnullen te produceren: %08x
vult het getal met voorloopnullen in tot een breedte van 8
. Als u consistente uitvoer wilt voor alle 32-bits waarden, gebruikt u "0x08x"
.
U kunt ook het precisieveld gebruiken: %.8x
vult het getal in met voorloopnullen tot een totaal van 8
cijfers. Daarom kunt u ook "0x%.8x"
gebruiken voor uw doel.
Deze conversiespecificaties zouden verschillen als er een prefix wordt gegenereerd als onderdeel van de conversie, zoals 0x
voor #
of -
voor negatieve getallen in ondertekende conversies, waarvan de lengte wordt meegeteld voor de breedte, maar niet voor de precisiespecificatie. Verder kan het precisieveld worden gecombineerd met het breedteveld:
printf("|%10x|", 256) // outputs | 100|
printf("|%010x|", 256) // outputs |0000000100|
printf("|%#010x|", 256) // outputs |0x00000100|
printf("|%10.8x|", 256) // outputs | 00000100|
printf("|%#10.8x|", 256) // outputs |0x00000100|
printf("|0x%.8x|", 256) // outputs |0x00000100|
printf("|%10x|", 0) // outputs | 0|
printf("|%010x|", 0) // outputs |0000000000|
printf("|%#010x|", 0) // outputs |0000000000|
printf("|%10.8x|", 0) // outputs | 00000000|
printf("|%#10.8x|", 0) // outputs | 00000000|
printf("|0x%.8x|", 0) // outputs |0x00000000|
Ik zou aanraden de laatste te gebruiken: "0x%.8x"
.
Antwoord 5
U kunt altijd “%p” gebruiken om 8-bits hexadecimale getallen weer te geven.
int main (void)
{
uint8_t a;
uint32_t b;
a = 15;
b = a << 28;
printf("%p", b);
return 0;
}
Uitvoer:
0xf0000000