Vad är skillnaden med att använda\% p,\% u och\% x för att skriva ut variabeladress i C?


Bästa svaret

Om du behöver skriva ut en adress till något , eller innehållet i en pekervariabel, det enda riktigt bärbara sättet att göra det är att använda formatet\% p-format. C-standarden anger att de utskrivna tecknen är implementeringsdefinierade, men i praktiken genererar de flesta C-biblioteksimplementeringarna en sekvens av hexadecimala siffror som representerar adressen.

Formatuppgifterna\% u och\% x förväntar sig ett osignerat heltal och skriv ut värdet i decimal respektive hexadecimal. De förväntar sig inte en adress .

Om du använder\% u eller\% x (eller något annat än\% p) för att försöka skriva ut en adress, det kanske verkar fungera i vissa miljöer, men kommer faktiskt att vara odefinierat beteende och icke-bärbar . Du kan inte anta att storleken på en pekare är densamma som storleken på ett osignerat heltal (eller någon annan heltal datatyp). I många 64-bitars miljöer är till exempel ett osignerat heltal 32 bitar. Om antalet bitar i en pekare inte matchar antalet bitar i ett osignerat heltal i din miljö, och du försöker använda\% u eller\% x för att skriva ut en adress, får du felaktig utmatning och utmatningen från efterföljande objekt i samma anrop till printf kan också vara felaktiga.

Så, om du ska skriva ut en adress, använd alltid\% p-formatspecifikationen för bärbar kod som undviker odefinierat beteende. Antag aldrig att storleken på en pekare är densamma som storleken på någon annan C-datatyp.

Svar

Endast \%p konvertering förstår en pekare korrekt. \%p omvandlingen skriver ut en pekare på ett implementeringsspecifikt sätt.

\%u och \%x omvandlingar är för unsigned int eller int -typer, som kanske eller inte kan ha samma storlek som en pekartyp. \%u -konvertering skriver ut ett osignerat decimaltal, medan \%x skriver ut ett osignerat hexadecimalt heltal med gemener.

Till skriv ut en pekare med antingen \%u eller \%x, du måste kasta pekaren till en int eller unsigned int. Den rollbesättningen kan tappa information om sizeof(void *) > sizeof(int).

Se även: printf, fprintf, sprintf, snprintf, printf\_s , fprintf\_s

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *