C Language
Formatierte Eingabe / Ausgabe
Suche…
Den Wert eines Zeigers auf ein Objekt drucken
Um den Wert eines Zeigers auf ein Objekt zu drucken (im Gegensatz zu einem Funktionszeiger), verwenden Sie den p
Konvertierungsspezifizierer. Es ist definiert, nur void
Zeiger auszudrucken. Um den Wert eines nicht void
Zeigers auszudrucken, muss er explizit ("casted *") in void*
konvertiert werden.
#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;
}
Verwenden von <inttypes.h>
und uintptr_t
Eine andere Möglichkeit, Zeiger in C99 oder höher zu drucken, verwendet den Typ uintptr_t
und die Makros aus <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;
}
Theoretisch gibt es möglicherweise keinen Integer-Typ, der einen in eine Integer-Zahl konvertierten Zeiger enthalten kann (daher ist der Typ uintptr_t
möglicherweise nicht vorhanden). In der Praxis existiert es. Zeiger auf Funktionen müssen nicht in den Typ uintptr_t
konvertierbar sein - auch wenn sie meistens konvertierbar sind.
Wenn der Typ uintptr_t
vorhanden ist, gilt auch der Typ intptr_t
. Es ist jedoch nicht klar, warum Sie Adressen jemals als signierte Ganzzahlen behandeln möchten.
Vorgeschichte:
Während der K & R-C-Zeiten vor C89 gab es weder einen Typ void*
(noch Header <stdlib.h>
) noch Prototypen und daher keine int main(void)
Notation int main(void)
Notation). Daher wurde der Zeiger in ein long unsigned int
und mit der long unsigned int
lx
Längenmodifizierer / Konvertierungsspezifizierer.
Das folgende Beispiel dient nur zu Informationszwecken. Heutzutage handelt es sich um ungültigen Code, der das berüchtigte undefinierte Verhalten sehr wohl provozieren könnte.
#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;
}
Drucken der Differenz der Werte zweier Zeiger auf ein Objekt
Das Abziehen der Werte von zwei Zeigern auf ein Objekt führt zu einer vorzeichenbehafteten Ganzzahl * 1 . Es würde also mindestens mit dem d
Konvertierungsspezifizierer gedruckt.
Um sicherzustellen, dass ein Typ breit genug ist, um eine solche "Zeigerdifferenz" aufzunehmen, da C99 <stddef.h>
den Typ ptrdiff_t
definiert. Um ein ptrdiff_t
zu drucken, verwenden Sie den Modifikator t
length.
#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;
}
Das Ergebnis könnte so aussehen:
p1 = 0x7fff6679f430
p2 = 0x7fff6679f434
p2 - p1 = 1
Bitte beachten Sie, dass der sich ergebende Wert der Differenz durch die Größe des Typs skaliert wird, auf den der Zeiger, auf den hier subtrahiert wird, ein int
Wert ist. Die Größe eines int
für dieses Beispiel ist 4.
* 1 Wenn die zwei zu subtrahierenden Zeiger nicht auf dasselbe Objekt zeigen, ist das Verhalten undefiniert.
Konvertierungsspezifikationen für den Druck
Conversion Specifier | Art des Arguments | Beschreibung |
---|---|---|
i , d | int | druckt dezimal |
u | unsigned int | druckt dezimal |
o | unsigned int | druckt oktal |
x | unsigned int | druckt hexadezimal und in Kleinbuchstaben |
X | unsigned int | druckt hexadezimal in Großbuchstaben |
f | doppelt | druckt Float mit einer Standardgenauigkeit von 6, wenn keine Genauigkeit angegeben ist (Kleinbuchstaben werden für spezielle Zahlen nan und inf oder infinity ) |
F | doppelt | druckt Float mit einer Standardgenauigkeit von 6, wenn keine Genauigkeit angegeben ist (Großbuchstaben werden für die Sondernummern NAN und INF oder INFINITY ) |
e | doppelt | druckt Float mit einer Standardgenauigkeit von 6, wenn keine Genauigkeit angegeben wird, unter Verwendung der wissenschaftlichen Notation mit Mantisse / Exponent; Exponent- und Sondernummern für Kleinbuchstaben |
E | doppelt | druckt Float mit einer Standardgenauigkeit von 6, wenn keine Genauigkeit angegeben wird, unter Verwendung der wissenschaftlichen Notation mit Mantisse / Exponent; Exponent- und Sondernummern für Großbuchstaben |
g | doppelt | verwendet entweder f oder e [siehe unten] |
G | doppelt | verwendet entweder F oder E [siehe unten] |
a | doppelt | druckt hexadezimal und in Kleinbuchstaben |
A | doppelt | druckt hexadezimal in Großbuchstaben |
c | verkohlen | druckt ein einzelnes Zeichen |
s | verkohlen* | gibt eine Zeichenfolge bis zu einem NUL Terminator aus oder wird auf die durch die Genauigkeit angegebene Länge gekürzt, sofern angegeben |
p | Leere* | druckt einen void Zeigerwert; Ein nicht void pointer sollte explizit in void* umgewandelt werden ("cast"); Zeiger nur auf Objekt, nicht Funktionszeiger |
% | n / a | gibt das Zeichen % |
n | int * | schreibe die Anzahl der Bytes, die bisher gedruckt wurden, in das int auf das gezeigt wird. |
Beachten Sie, dass %hhn
auf %n
angewendet werden können (z. B. bedeutet %hhn
, dass ein nachfolgender n
Konvertierungsspezifizierer auf einen Zeiger auf ein signed char
Argument gemäß ISO / IEC 9899: 2011 (§7.21.6.1 ¶7 angewendet wird).
Beachten Sie, dass die Fließkomma-Konvertierungen aufgrund von Standard-Promotion-Regeln für die Typen float
und double
gelten . Die Standardargument-Promotions werden für nachfolgende Argumente ausgeführt. ) Funktionen wie printf()
werden also immer nur mit double
, auch wenn die referenzierte Variable vom Typ float
.
Bei den Formaten g
und G
ist die Wahl zwischen der Notation e
und f
(oder E
und F
) im C-Standard und in der POSIX-Spezifikation für printf()
dokumentiert:
Das Doppelargument, das eine Gleitkommazahl darstellt, wird abhängig von dem umgesetzten Wert und der Genauigkeit in den Stil
f
odere
(oder im Fall einesG
Konvertierungsspezifizierers inF
oderE
) konvertiert. SeiP
gleich der Genauigkeit, falls nicht Null, 6, wenn die Genauigkeit ausgelassen wird, oder 1, wenn die Genauigkeit Null ist. Dann, wenn eine Konvertierung mit StilE
einen Exponenten vonX
:
- Wenn P> X> = -4, muss die Konvertierung mit dem Stil
f
(oderF
) und der GenauigkeitP - (X+1)
.- Andernfalls erfolgt die Konvertierung mit dem Stil
e
(oderE
) und der GenauigkeitP - 1
.
Wenn das Flag '#' nicht verwendet wird, werden abschließende Nullen aus dem gebrochenen Teil des Ergebnisses entfernt und das Dezimalzeichen wird entfernt, wenn kein verbleibender Bruchteil vorhanden ist.
Die Funktion printf ()
Die Funktion printf()
ist das wichtigste Werkzeug, das zum Drucken von Text an die Konsole in C verwendet wird, indem <stdio.h>
printf()
wird.
printf("Hello world!");
// Hello world!
Normale, unformatierte Zeichen-Arrays können selbst gedruckt werden, indem sie direkt zwischen den Klammern platziert werden.
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
Alternativ können ganze Zahlen, Gleitkommazahlen, Zeichen und mehr mit dem Escape-Zeichen %
gedruckt werden, gefolgt von einem Zeichen oder einer Zeichenfolge, die das Format angibt (Formatbezeichner) .
Alle zusätzlichen Argumente für die Funktion printf()
werden durch Kommas getrennt. Diese Argumente sollten in derselben Reihenfolge wie die Formatbezeichner stehen. Zusätzliche Argumente werden ignoriert, während falsch eingegebene Argumente oder fehlende Argumente Fehler oder undefiniertes Verhalten verursachen. Jedes Argument kann entweder ein Literalwert oder eine Variable sein.
Nach erfolgreicher Ausführung wird die Anzahl der gedruckten Zeichen mit dem Typ int
. Andernfalls liefert ein Fehler einen negativen Wert.
Längenmodifikatoren
Die Standards C99 und C11 geben die folgenden Längenmodifizierer für printf()
. ihre Bedeutungen sind:
Modifikator | Ändert | Gilt für |
---|---|---|
hh | d, i, o, u, x oder X | char , signed char oder unsigned char |
h | d, i, o, u, x oder X | short int oder unsigned short int |
l | d, i, o, u, x oder X | long int oder unsigned long int |
l | a, A, e, E, f, F, g oder G | double (zur Kompatibilität mit scanf() ; undefiniert in C90) |
ll | d, i, o, u, x oder X | long long int oder unsigned long long int |
j | d, i, o, u, x oder X | intmax_t oder uintmax_t |
z | d, i, o, u, x oder X | size_t oder der entsprechende signierte Typ ( ssize_t in POSIX) |
t | d, i, o, u, x oder X | ptrdiff_t oder der entsprechende Integer-Typ ohne Vorzeichen |
L | a, A, e, E, f, F, g oder G | long double |
Wenn ein Längenmodifikator mit einem anderen als dem oben angegebenen Konvertierungsspezifizierer angezeigt wird, ist das Verhalten undefiniert.
Microsoft gibt einige andere Längenmodifizierer an und unterstützt hh
, j
, z
oder t
nicht explizit.
Modifikator | Ändert | Gilt für |
---|---|---|
I32 | d, i, o, x oder X | __int32 |
I32 | o, u, x oder X | unsigned __int32 |
I64 | d, i, o, x oder X | __int64 |
I64 | o, u, x oder X | unsigned __int64 |
ich | d, i, o, x oder X | ptrdiff_t ( __int32 auf 32-Bit-Plattformen, __int64 auf 64-Bit-Plattformen) |
ich | o, u, x oder X | size_t ( unsigned __int32 auf 32-Bit-Plattformen unsigned __int64 auf 64-Bit-Plattformen unsigned __int64 ) |
l oder l | a, A, e, E, f, g oder G | long double (In Visual C ++ ist, obwohl long double ein eindeutiger Typ ist, er dieselbe interne Darstellung wie double .) |
l oder w | c oder c | Breites Zeichen mit Funktionen printf und wprintf . (Ein wC lc , lC , wc oder wC ist gleichbedeutend mit C in printf Funktionen und mit c in wprintf Funktionen.) |
l oder w | s, S oder Z | wprintf Funktionen printf und wprintf . (Ein ls , lS , ws oder wS Typbezeichner ist gleichbedeutend mit S in printf Funktionen und mit s in wprintf Funktionen.) |
Beachten Sie, dass die C
, S
und Z
Konvertierungsspezifizierer und die I32
I
, I32
, I64
und w
Microsoft-Erweiterungen sind. Die Behandlung von l
als Modifikator für long double
anstelle von double
unterscheidet sich vom Standard, obwohl Sie den Unterschied kaum erkennen können, es sei denn, long double
hat eine andere Darstellung als double
.
Formatflags drucken
Der C-Standard (auch C11 und C99) definiert die folgenden Flags für printf()
:
Flagge | Konvertierungen | Bedeutung |
---|---|---|
- | alles | Das Ergebnis der Konvertierung ist innerhalb des Feldes linksbündig. Die Konvertierung ist rechtsbündig, wenn dieses Flag nicht angegeben ist. |
+ | signiert numerisch | Das Ergebnis einer signierten Konvertierung beginnt immer mit einem Zeichen ('+' oder '-'). Die Konvertierung darf nur dann mit einem Vorzeichen beginnen, wenn ein negativer Wert konvertiert wird, wenn dieses Flag nicht angegeben ist. |
<space> | signiert numerisch | Ist das erste Zeichen einer signierten Konvertierung kein Vorzeichen oder führt eine signierte Konvertierung zu keinen Zeichen, wird dem Ergebnis ein <space> vorangestellt. Das bedeutet, wenn das <space> und das ' + ' Flag beide erscheinen, wird das <space> Flag ignoriert. |
# | alles | Gibt an, dass der Wert in ein alternatives Formular konvertiert werden soll. Für o Umwandlung, so hat er die Genauigkeit zu erhöhen, wenn und nur wenn notwendig, um die erste Ziffer des Ergebnisses zu zwingen , eine Null zu sein (wenn der Wert und Präzision beide 0 ist, wird eine einzelne 0 gedruckt). Für x oder X Konvertierungsbezeichner wird einem Ergebnis ungleich Null ein 0x (oder 0X ) vorangestellt. Für a , A , e , E , f , F , g , und G Konvertierungsspezifizierer, wird das Ergebnis immer ein Radix - Zeichen enthalten, auch wenn keine Ziffern stellen den radix Zeichen folgen. Ohne dieses Flag erscheint im Ergebnis dieser Konvertierungen nur ein Radix-Zeichen, wenn eine Ziffer darauf folgt. Bei g und G Konvertierungsspezifizierern werden nachfolgende Nullen nicht wie üblich aus dem Ergebnis entfernt. Bei anderen Konvertierungsspezifizierern ist das Verhalten undefiniert. |
0 | numerisch | Für d, i, o, u, x, a, a, e, f, g, g und G-Konvertierungsspezifizierer werden führende Nullen (nach beliebigen Zeichen- oder Basisangaben) zum Auffüllen auf das Feld verwendet Breite anstelle von Leerzeichen, außer bei der Konvertierung einer Unendlichkeit oder eines NaN. Wenn die Flag '0' und '-' beide erscheinen, wird das Flag '0' ignoriert. Wenn für die Konvertierungskennungen d, i, o, u, x und X eine Genauigkeit angegeben wird, wird das Flag '0' ignoriert. ⌦ Wenn die Flags '0' und <apostrophe> angezeigt werden, werden die Gruppierungszeichen vor dem Auffüllen mit Nullen eingefügt. Bei anderen Konvertierungen ist das Verhalten undefiniert. ⌫ |
Diese Flags werden auch von Microsoft mit den gleichen Bedeutungen unterstützt.
Die POSIX-Spezifikation für printf()
fügt hinzu:
Flagge | Konvertierungen | Bedeutung |
---|---|---|
' | i, d, u, f, F, g, G | Der ganzzahlige Teil des Ergebnisses einer Dezimalkonvertierung wird mit Gruppierungszeichen von Tausenden formatiert. Bei anderen Konvertierungen ist das Verhalten undefiniert. Das nicht monetäre Gruppierungszeichen wird verwendet. |