Beste svaret
Hvis du trenger å skrive ut en adresse til noe , eller innholdet i en pekervariabel, er den eneste virkelig bærbare måten å gjøre det på\% p-formatet. C-standarden sier at tegnene som er skrevet ut er implementeringsdefinerte, men i praksis genererer de fleste C-biblioteksimplementeringer en sekvens med heksadesimale sifre som representerer adressen.
\% u- og\% x-formatsspesifikatorene forventer et usignert heltall og skriv ut verdien i henholdsvis desimal og heksadesimal. De forventer ikke en adresse .
Hvis du bruker\% u eller\% x (eller noe annet enn\% p) for å prøve å skrive ut en adresse, det kan se ut til å fungere i noen miljøer, men vil faktisk være udefinert oppførsel og ikke-bærbar . Du kan ikke anta at størrelsen på en peker er den samme som størrelsen på et usignert heltall (eller en hvilken som helst annen heltal datatype). For eksempel, i mange 64-bits miljøer, er et usignert heltall 32 bits. Hvis antall biter i en peker ikke samsvarer med antall biter i et usignert heltall i miljøet ditt, og du prøver å bruke\% u eller\% x til å skrive ut en adresse, får du feil utdata og utdata fra påfølgende elementer i samme kall til printf kan også være feil.
Så hvis du skal skrive ut en adresse, må du alltid bruke formatet\% p for å få bærbar kode som unngår udefinert oppførsel. Anta aldri at størrelsen på en peker er den samme som størrelsen på noen annen C-datatype.
Svar
Bare \%p
konvertering forstår riktig en peker. \%p
konverteringen skriver ut en peker på en implementeringsspesifikk måte.
\%u
og \%x
konverteringer er for unsigned int
eller int
-typer, som kanskje eller ikke har samme størrelse som en pekertype. \%u
konvertering skriver ut et usignert desimaltall, mens \%x
skriver ut et usignert heksadesimalt heltall med små bokstaver.
Til skriv ut en peker med enten \%u
eller \%x
, må du kaste pekeren til en int
eller unsigned int
. Denne rollebesetningen kan miste informasjon hvis sizeof(void *) > sizeof(int)
.
Se også: printf, fprintf, sprintf, snprintf, printf\_s , fprintf\_s