C Language
Formaterad ingång / utgång
Sök…
Skriva ut värdet på en pekare till ett objekt
För att skriva ut värdet på en pekare till ett objekt (i motsats till en funktionspekare) använd p
konverteringsspecifikationen. Det definieras för att skriva ut void
-pointers bara, så att skriva ut värdet av en icke void
-pointer det måste uttryckligen omvandlas ( "gjuten *") till void*
.
#include <stdlib.h> /* for EXIT_SUCCESS */
#include <stdio.h> /* for printf() */
int main(void)
{
int i;
int * p = &i;
printf("The address of i is %p.\n", (void*) p);
return EXIT_SUCCESS;
}
Använd <inttypes.h>
och uintptr_t
Ett annat sätt att skriva ut pekare i C99 eller senare använder uintptr_t
typen och makron från <inttypes.h>
:
#include <inttypes.h> /* for uintptr_t and PRIXPTR */
#include <stdio.h> /* for printf() */
int main(void)
{
int i;
int *p = &i;
printf("The address of i is 0x%" PRIXPTR ".\n", (uintptr_t)p);
return 0;
}
I teorin kan det inte vara ett heltal typ som kan hålla någon pekaren omvandlas till ett heltal (så typen uintptr_t
kanske inte existerar). I praktiken existerar det. Pekare till funktioner behöver inte vara konvertibla till typen uintptr_t
- men återigen är de ofta konvertibla.
Om uintptr_t
typen finns, gör intptr_t
typen det också. Det är dock inte klart varför du någonsin vill behandla adresser som signerade heltal.
Pre-Standard History:
Före C89 under K & R-C-tider fanns det ingen typ av void*
(inte heller rubrik <stdlib.h>
, inte heller prototyper, och följaktligen ingen int main(void)
notation), så pekaren gjordes till long unsigned int
och tryckt med lx
längd modifierare / konverteringsspecifikation.
Exemplet nedan är bara för informationssyfte. För närvarande är detta ogiltig kod, vilket mycket väl kan provocera det ökända odefinierade beteendet .
#include <stdio.h> /* optional in pre-standard C - for printf() */
int main()
{
int i;
int *p = &i;
printf("The address of i is 0x%lx.\n", (long unsigned) p);
return 0;
}
Skriva ut skillnaden mellan värdena för två pekare till ett objekt
Att subtrahera värdena för två pekare till ett objekt resulterar i ett signerat heltal * 1 . Så det skulle skrivas ut med åtminstone d
konverteringsspecifikationen.
För att se till att det finns en typ som är tillräckligt bred för att hålla en sådan "pekarskillnad", eftersom C99 <stddef.h>
definierar typen ptrdiff_t
. För att skriva ut en ptrdiff_t
använd t
längdmodifieraren.
#include <stdlib.h> /* for EXIT_SUCCESS */
#include <stdio.h> /* for printf() */
#include <stddef.h> /* for ptrdiff_t */
int main(void)
{
int a[2];
int * p1 = &a[0], * p2 = &a[1];
ptrdiff_t pd = p2 - p1;
printf("p1 = %p\n", (void*) p1);
printf("p2 = %p\n", (void*) p2);
printf("p2 - p1 = %td\n", pd);
return EXIT_SUCCESS;
}
Resultatet kan se ut så här:
p1 = 0x7fff6679f430
p2 = 0x7fff6679f434
p2 - p1 = 1
Observera att det resulterande värdet på skillnaden skalas efter storleken på den typ som pekarna subtraherade pekar till, int
här. Storleken på en int
för detta exempel är 4.
* 1 Om de två pekarna som ska subtraheras inte pekar på samma objekt är beteendet odefinierat.
Konverteringsspecifikationer för utskrift
Konverteringsspecifikation | Typ av argument | Beskrivning |
---|---|---|
i , d | int | skriver ut decimal |
u | osignerad int | skriver ut decimal |
o | osignerad int | skriver ut oktal |
x | osignerad int | skriver ut hexadecimal, små bokstäver |
X | osignerad int | skriver ut hexadecimal, versaler |
f | dubbel- | utskrifter flyter med en standardprecision på 6, om ingen precision ges (små bokstäver används för specialnummer nan och inf eller infinity ) |
F | dubbel- | utskrifter flyter med en standardprecision på 6, om ingen precision ges (stor bokstav används för specialnummer NAN och INF eller INFINITY ) |
e | dubbel- | utskrifter flyter med en standardprecision på 6, om ingen precision ges, med hjälp av vetenskaplig notation med mantissa / exponent; små bokstäver och specialnummer |
E | dubbel- | utskrifter flyter med en standardprecision på 6, om ingen precision ges, med hjälp av vetenskaplig notation med mantissa / exponent; stora bokstäver och specialnummer |
g | dubbel- | använder antingen f eller e [se nedan] |
G | dubbel- | använder antingen F eller E [se nedan] |
a | dubbel- | skriver ut hexadecimal, små bokstäver |
A | dubbel- | skriver ut hexadecimal, versaler |
c | röding | skriver ut enstaka tecken |
s | röding* | skriver ut sträng med tecken upp till en NUL terminator, eller avkortas till längd som ges med precision, om det anges |
p | tomhet* | skriver ut void -pointervärde; en icke- void pointer bör uttryckligen konverteras ("cast") till void* ; pekaren endast till objekt, inte en funktionspekare |
% | n / a | skriver ut % -tecknet |
n | int * | skriva antalet byte som skrivs ut så långt in i int pekade på. |
Observera att längdmodifierare kan tillämpas på %n
(t.ex. %hhn
indikerar att en följande n
konverteringsspecifikator gäller för en pekare på ett signed char
argument , enligt ISO / IEC 9899: 2011 §7.21.6.1 ¶7).
Observera att konvertering av flytande punkt gäller för typer som float
och double
grund av standardpromoteringsregler - §6.5.2.2 Funktionssamtal, ¶7 Noteringen ellips i en prototyp för deklarationsfunktioner gör att konvertering av argumenttyp stannar efter den senaste deklarerade parametern. Standardargumentkampanjer utförs på efterföljande argument. ) Funktioner som printf()
ges alltså bara någonsin double
värden, även om den referensvariabeln är av typen float
.
Med formatet g
och G
dokumenteras valet mellan e
och f
(eller E
och F
) notation i C-standarden och i POSIX-specifikationen för printf()
:
Det dubbla argumentet som representerar ett flytpunktsnummer ska konverteras i stilen
f
ellere
(eller i stilenF
ellerE
i fallet med enG
konverteringsspecifikation), beroende på det konverterade värdet och precisionen. LåtP
lika med precisionen om icke-noll, 6 om precisionen utelämnas, eller 1 om precisionen är noll. Om en konvertering med stilE
skulle ha en exponent förX
:
- Om P> X> = -4, ska konverteringen ske med stil
f
(ellerF
) och precisionP - (X+1)
.- Annars ska konverteringen ske med stil
e
(ellerE
) och precisionP - 1
.
Slutligen, om inte '#' -flaggan används, ska alla efterföljande nollor tas bort från resultatets bråkdel och decimalpunkttecknet tas bort om det inte finns någon bråkdel kvar.
Funktionen printf ()
Åtkomst genom att inkludera <stdio.h>
, funktionen printf()
är det primära verktyget som används för att skriva ut text till konsolen i C.
printf("Hello world!");
// Hello world!
Normala, oformaterade karaktärsuppsättningar kan skrivas ut av sig själva genom att placera dem direkt mellan parenteserna.
printf("%d is the answer to life, the universe, and everything.", 42);
// 42 is the answer to life, the universe, and everything.
int x = 3;
char y = 'Z';
char* z = "Example";
printf("Int: %d, Char: %c, String: %s", x, y, z);
// Int: 3, Char: Z, String: Example
Alternativt kan heltal, flytpunktsnummer, tecken och mer skrivas ut med flyktecken %
, följt av ett tecken eller sekvens av tecken som anger formatet, känt som formatspecifikatorn .
Alla ytterligare argument till funktionen printf()
separeras med kommatecken, och dessa argument bör vara i samma ordning som formatspecifikationerna. Ytterligare argument ignoreras, medan felaktiga argument eller brist på argument orsakar fel eller odefinierat beteende. Varje argument kan vara antingen ett bokstavligt värde eller en variabel.
Efter framgångsrik körning returneras antalet tecken som skrivs ut med typ int
. Annars ger ett fel ett negativt värde.
Längdmodifierare
Standarderna C99 och C11 anger följande längdmodifierare för printf()
; deras betydelse är:
modifier | modifierar | Gäller för |
---|---|---|
hh | d, i, o, u, x eller X | char , signed char eller unsigned char |
h | d, i, o, u, x eller X | short int eller unsigned short int |
l | d, i, o, u, x eller X | long int eller unsigned long int |
l | a, A, e, E, f, F, g eller G | double (för kompatibilitet med scanf() ; odefinierad i C90) |
ll | d, i, o, u, x eller X | long long int eller unsigned long long int |
j | d, i, o, u, x eller X | intmax_t eller uintmax_t |
z | d, i, o, u, x eller X | size_t eller motsvarande signerad typ ( ssize_t i POSIX) |
t | d, i, o, u, x eller X | ptrdiff_t eller motsvarande osignerad heltalstyp |
L | a, A, e, E, f, F, g eller G | long double |
Om en längdmodifierare visas med någon annan konverteringsspecifikation än som anges ovan, är beteendet odefinierat.
Microsoft anger vissa olika längdmodifierare och stöder uttryckligen inte hh
, j
, z
eller t
.
modifier | modifierar | Gäller för |
---|---|---|
I32 | d, i, o, x eller X | __int32 |
I32 | o, u, x eller X | unsigned __int32 |
I64 | d, i, o, x eller X | __int64 |
I64 | o, u, x eller X | unsigned __int64 |
jag | d, i, o, x eller X | ptrdiff_t (det vill säga __int32 på 32-bitars plattformar, __int64 på 64-bitars plattformar) |
jag | o, u, x eller X | size_t (det vill säga unsigned __int32 på 32-bitars plattformar, unsigned __int64 på 64-bitars plattformar) |
l eller L | a, A, e, E, f, g eller G | long double (I Visual C ++, även om long double är en distinkt typ, har den samma interna representation som double .) |
l eller w | c eller C | Brett tecken med printf och wprintf funktioner. (En lc , lC , wc eller wC typspecifikation är synonymt med C i printf funktioner och med c i wprintf funktioner.) |
l eller w | s, S eller Z | Sträng med bred tecken med funktioner för printf och wprintf . (En ls , lS , ws eller wS typspecifikation är synonymt med S i printf funktioner och med s i wprintf funktioner.) |
Observera att konverteringsspecifikationerna för C
, S
och Z
och I32
I
, I32
, I64
och w
längden är Microsoft-tillägg. Att behandla l
som en modifierare för long double
snarare än double
skiljer sig från standarden, men du kommer att vara hårt pressad för att upptäcka skillnaden om inte long double
har en annan representation än double
.
Skriva ut formatflaggor
C-standarden (C11 och C99 också) definierar följande flaggor för printf()
:
Flagga | omvandlingar | Menande |
---|---|---|
- | Allt | Resultatet av konverteringen ska lämnas motiverat inom fältet. Omvandlingen är rättberättigad om denna flagga inte anges. |
+ | signerad numerisk | Resultatet av en signerad konvertering ska alltid börja med ett tecken ('+' eller '-'). Konverteringen börjar med ett tecken endast när ett negativt värde konverteras om denna flagga inte anges. |
<space> | signerad numerisk | Om det första tecknet i en signerad konvertering inte är ett tecken eller om en signerad konvertering resulterar i inga tecken, ska ett <space> förinställas till resultatet. Detta innebär att om <space> och ' + ' flaggorna båda visas, ska <space> -flaggan ignoreras. |
# | Allt | Anger att värdet ska konverteras till en alternativ form. För o konvertering, skall den öka precisionen, om och endast om det är nödvändigt, för att tvinga den första siffran i det resultat att vara en nolla (om värdet och precision är båda 0, är en enda 0 tryckt). För x eller X konverteringsspecifikationer ska ett icke-nollresultat ha 0x (eller 0X ) förinställt till det. För a , A , e , E , f , F , g och G omvandlingsspecifikationer ska resultatet alltid innehålla ett radixtecken, även om inga siffror följer radixtecknet. Utan denna flagga visas ett radixtecken i resultatet av dessa omvandlingar endast om en siffra följer den. För konverteringsspecifikationer för g och G ska släpnollar inte tas bort från resultatet som de normalt är. För andra konverteringsspecifikationer är beteendet odefinierat. |
0 | numerisk | För d, i, o, u, x, X, a, A, e, E, f, F, g och G-omvandlingsspecifikationer används ledande nollor (efter någon indikation på tecken eller bas) för att padda till fältet bredd snarare än att utföra rymdpolstring, utom när du konverterar en oändlighet eller NaN. Om flaggorna '0' och '-' båda visas, ignoreras flaggan '0'. För konverteringsspecifikationerna d, i, o, u, x och X, om en precision specificeras, ska "0" -flaggan ignoreras. ⌦ Om flaggorna '0' och <apostrophe> visas båda, införs grupperingstecken innan noll stoppning. För andra konverteringar är beteendet odefinierat. ⌫ |
Dessa flaggor stöds också av Microsoft med samma betydelse.
POSIX-specifikationen för printf()
lägger till:
Flagga | omvandlingar | Menande |
---|---|---|
' | i, d, u, f, F, g, G | Heltalsdelen av resultatet av en decimalkonvertering ska formateras med tusentals grupperingstecken. För andra konverteringar är beteendet odefinierat. Den icke-monetära grupperingstecken används. |