Char Zeiger und die printf-Funktion
War ich versucht zu lernen, Zeiger und ich schrieb Sie den folgenden code zum drucken der Wert des Zeigers:
#include <stdio.h>
int main(void) {
char *p = "abc";
printf("%c",*p);
return 0;
}
Ausgabe:
einen
jedoch, wenn ich den obigen code:
#include <stdio.h>
int main(void) {
char *p = "abc";
printf(p);
return 0;
}
Bekomme ich die Ausgabe:
abc
Ich verstehe nicht, die folgenden 2 Dinge:
- warum printf nicht verlangen, ein Formatbezeichner im zweiten Fall? Ist
printf(pointer_name)
genug, um drucken Sie den Wert des Zeigers? - gemäß meinem Verständnis (das ist sehr wenig), *p Punkte zu einem zusammenhängenden block von Speicher, die enthält
abc
. Ich erwartet, dass beide Ausgänge gleich sein, d.h.
abc
sind die verschiedenen Ausgänge aufgrund der unterschiedlichen weisen des Druckens?
Bearbeiten 1
Darüber hinaus der folgende code erzeugt einen Laufzeitfehler. Warum ist das so?
#include <stdio.h>
int main(void) {
char *p = "abc";
printf(*p);
return 0;
}
"
*p
Punkte zu einem zusammenhängenden block von Speicher" zeigt es nirgends, wie *p
ist kein Zeiger, sondern wertet eine char
.InformationsquelleAutor Fabulous | 2016-10-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
Für die erste Frage, die
printf ()
- Funktion (und Familie) nimmt einen string als erstes argument (d.h. eineconst char *
). Diese Zeichenfolge enthalten können format-codes, dieprintf
Funktion ersetzt mit dem entsprechenden argument. Der rest des Textes gedruckt ist, wörtlich. Und das ist, was passiert, wenn Sie passierenp
wie das erste argument.Tun, beachten Sie, dass die Verwendung
printf
diese Weise ist sehr unrecommended, vor allem, wenn der string enthält eine Eingabe von einem Benutzer. Wenn der Benutzer fügt steuerzeichen in der Zeichenkette, und Sie nicht die richtigen Argumente haben, dann wird der Undefiniertes Verhalten. Es könnte sogar zu Sicherheitsproblemen führen, Löcher.Ihre zweite Frage, die variable
p
Punkte zu einigen Speicher. Der Ausdruck*p
dereferenziert den Zeiger, geben Sie ein einzelnes Zeichen, nämlich die, diep
ist tatsächlich verweist diep[0]
.Denken
p
wie diese:Die variable
p
nicht wirklich Punkt für ein "string", es verweist nur auf einige einzelne Position in Erinnerung, nämlich das erste Zeichen in der Zeichenfolge"abc"
. Es ist die Funktionen, die mitp
behandeln, dass der Speicher als eine Folge von Zeichen.Darüber hinaus Konstante string-Literale sind eigentlich gespeichert (read-only) arrays die Anzahl der Zeichen in der Zeichenfolge plus einem für den string-terminator.
Auch, damit Sie verstehen, warum
*p
ist das gleiche wiep[0]
Sie müssen wissen, dass für jeden Zeiger oder arrayp
und gültigen indexi
ist, sind die Ausdrückep[i]
gleich*(p + i)
. Den ersten Charakter, den Sie haben index0
, das heißt, Sie habenp[0]
soll und dann gleich*(p + 0)
. Hinzufügen null auf etwas ist ein no-op, so*(p + 0)
ist das gleiche wie*(p)
das ist das gleiche wie*p
. Daherp[0]
gleich*p
.Bezüglich Ihrer Bearbeiten (wo Sie
printf(*p)
), da*p
gibt den Wert des ersten "element" verweistp
(d.h.p[0]
) übergeben Sie ein einzelnes Zeichen als die Zeiger auf den format-string. Das wird dazu führen, dass der compiler die Konvertierung in einen Zeiger, die zeigen, auf was auch immer-Adresse hat den Wert der einzelnen Zeichen (die es nicht konvertieren die Zeichen auf einen Zeiger zu den Charakter). Diese Adresse ist nicht eine sehr gültige Adresse (in der ASCII-alphabet'a'
hat den Wert97
das ist die Adresse, wo das Programm sucht nach der Zeichenfolge zu drucken) und Sie haben Undefiniertes Verhalten.p[0]
behandelt werden als format-string selbst?ist das nicht ein "string", sondern ein Zeichen, nur ein
char
. Es gibt einen Unterschied zwischen'A'
und"A"
. Die erstere ist einechar
-literal, das letztere ist ein "string"-Literale, die in der Tat ist ein '0'-terminiertes array vonchar
.InformationsquelleAutor Some programmer dude
p
ist der format-string.ist das gleiche wie
Dies ist sehr schlechte Praxis, weil Sie nicht wissen, was die variable
enthalten sein wird, und wenn es enthält Formatierungszeichen, ruft
printf
tun können, die sehr böse Dinge.Der Grund, warum der erste Fall (mit
"%c"
) nur das erste Zeichen gedrucktist, dass
%c
bedeutet ein byte und*p
bedeutet, dass der (erste) Wert, derp
gerichtet ist.%s
drucken würde die gesamte Zeichenfolge.char
, wird ein Zeichen gedruckt wird.Das Wort "Charakter" ist zweideutig, es ist ein unsigned integer mit einer Breite von mindestens 8 bits, oder ist es ein (ggf. codiert) Unicode-Codepunkt ist. Ex. "å" in UTF-8 ist eine Zeichen/Buchstaben und zwei Zeichen/bytes.
InformationsquelleAutor Oskar Skog
Mit Ihrem code, den Sie erzählt von printf zu verwenden, die Ihren Text als format-string. Was bedeutet Ihr code aktiviert entspricht
printf("abc")
.Wenn Sie
%c
erhalten Sie ein Zeichen gedruckt, wenn Sie%s
bekommen Sie eine ganze Zeichenfolge. Aber wenn Sie sagen, printf zu verwenden, die string als format-string, dann wird es das auch tun.char *p = "abc";
printf(*p);
Dieser code stürzt ab, da der Inhalt
p
, den Charakter'a'
ist nicht ein Zeiger auf ein format-string, es ist nicht mal ein Mauszeiger. Dass code nicht selbst kompilieren, ohne Warnungen.Angesichts
printf("%d", 1)
, die"%d"
ist der format-string.InformationsquelleAutor Lundin
Sie sind Missverständnis, in der Tat, wenn Sie tun
p
Punkte auf die Start-Adresse, wo literal "Hallo" wird gespeichert. Dies ist, wie Sie erklären Zeiger. Jedoch wenn danach, Sie tunbedeutet es dereferenzieren
p
und erhalten Objekt, wop
Punkte. In unserem obigen Beispiel wäre dies die Ausbeute 'H'. Dies sollte klären, Ihre zweite Frage.Im Fall von printf nur versuchen
ist auch in Ordnung, das beantwortet deine erste Frage, denn es ist effektiv das gleiche, was du getan hast, wenn bestanden nur
p
zu printf.Endlich zu Bearbeiten, in der Tat
obige Zeile ist nicht korrekt, da printf erwartet
const char *
und mit*p
Sie übergeben es einemchar
- oder in anderen Worten " H " angenommen, unser Beispiel. Lesen Sie mehr, was die Dereferenzierung bedeutet.InformationsquelleAutor giorgi moniava
"abc" ist Ihre Formatbezeichner. Das ist, warum es drucken "abc". Wenn der string beinhaltet hatte
%
, dann würden die Dinge verhielt sich seltsam, hat Sie aber nicht.%c
ist der Charakter umwandlungsspezifikator. Es weistprintf
zu drucken nur das erste byte. Wenn Sie wollen, es zu drucken die Zeichenfolge, verwenden Sie...Den
%s
scheint überflüssig, aber es kann nützlich sein, für das drucken von steuerzeichen oder wenn Sie Breite Spezifizierer.Der beste Weg, um das zu verstehen, wirklich zu versuchen, und drucken Sie die Zeichenfolge
abc%def
mitprintf
.InformationsquelleAutor QuestionC
Den
%c
Formatbezeichner erwartet einechar
geben, und ausgegeben wird singlechar
Wert.Dem ersten parameter
printf
muss einconst char*
(achar*
umwandeln kann implizit in einenconst char*
) und verweist auf die start einer string von Zeichen. Es Stoppt den Druckvorgang, wenn es auf eine\0
in diesem string. Wenn es nicht ein\0
die in diesem string dann das Verhalten der Funktion ist undefined. Da"abc"
enthalten nicht alle Formatierungszeichen, die Sie nicht passieren keine zusätzlichen Argumente an, umprintf
in diesem Fall.InformationsquelleAutor Bathsheba