Ich bin ein bisschen verwirrt über etwas. Ich hatte den Eindruck, dass die richtige Art, eine C-Saite mit zu lesen, scanf()
nach dem Vorbild von
(egal der mögliche Pufferüberlauf, es ist nur ein einfaches Beispiel)
char string[256];
scanf( "%s" , string );
Das Folgende scheint jedoch auch zu funktionieren:
scanf( "%s" , &string );
Ist das nur mein Compiler (gcc), reines Glück oder etwas anderes?
scanf
, und dass sich sowohl die Frage als auch die akzeptierte Antwort darauf konzentrieren das, und lassen Sie die kritisch wichtigen Einschränkungen für die maximale Eingabelänge weg, die in echtem Code verwendet werden sollten (sind aber neben dem Punkt für diese Frage).Antworten:
Ein Array "zerfällt" in einen Zeiger auf sein erstes Element,
scanf("%s", string)
entspricht alsoscanf("%s", &string[0])
. Auf der anderen Seite wirdscanf("%s", &string)
ein Zeiger auf- übergebenchar[256]
, der jedoch auf dieselbe Stelle zeigt.Dann
scanf
, wenn das Heck seines Arguments Listenverarbeitung wird versuchen , ein zu ziehenchar *
. Das ist das Richtige, wenn Sie übergeben habenstring
oder&string[0]
, aber wenn Sie übergeben haben, hängen&string
Sie von etwas ab, das der Sprachstandard nicht garantiert, nämlich dass die Zeiger&string
und&string[0]
- Zeiger auf Objekte unterschiedlicher Typen und Größen, die am selben Ort beginnen - werden auf die gleiche Weise dargestellt.Ich glaube nicht, dass ich jemals auf ein System gestoßen bin, auf dem das nicht funktioniert, und in der Praxis sind Sie wahrscheinlich sicher. Trotzdem ist es falsch und es könnte auf einigen Plattformen fehlschlagen. (Hypothetisches Beispiel: Eine "Debugging" -Implementierung, die Typinformationen zu jedem Zeiger enthält. Ich denke, die C-Implementierung auf den Symbolics "Lisp Machines" hat so etwas getan.)
quelle
&string
genauso funktioniert wiestring
(anstatt zu einer zufälligen Speicherbeschädigung zu führen, wie andere Antworten fälschlicherweise behaupten):printf("%x\n%x\n", string, &string);
string
handelt es sich um einen Zeiger und&string
die Adresse dieses Zeigers, sodass die beiden NICHT austauschbar sind. Wie Gareth erklärt, auch für den Fall der Anordnung Verfall,string
und&string
sind technisch nicht die gleichen Typen (auch wenn sie für die meisten Architekturen austauschbar passieren) und gcc eine Warnung für Ihr zweites Beispiel geben , wenn Sie einschalten-Wall
.Ich denke, dass dies unten korrekt ist und es helfen kann. Fühlen Sie sich frei, es zu korrigieren, wenn Sie Fehler finden. Ich bin neu bei C.
einschließlich der Beendigung Nullzeichen
'\0'
&str
,&str[0]
undstr
alle drei repräsentieren den gleichen Speicherort, der die Adresse des ersten Elements des Arrays iststr
char * strPtr = & str [0]; // Deklaration und Initialisierung
Alternativ können Sie dies in zwei Teile teilen:
strPtr
ist ein Zeiger auf achar
strPtr
Punkte auf Arraystr
strPtr
ist eine Variable mit einer eigenen Adresse im SpeicherstrPtr
ist eine Variable, die den Adresswert speichert&str[0]
strPtr
Die eigene Adresse im Speicher unterscheidet sich von der Speicheradresse, die sie speichert (Adresse des Arrays im Speicher aka & str [0]).&strPtr
repräsentiert die Adresse von strPtr selbstIch denke, dass Sie einen Zeiger auf einen Zeiger deklarieren könnten als:
deklariert und initialisiert mit der Adresse des strPtr-Zeigers
Alternativ können Sie sich in zwei Teile teilen:
*vPtr
zeigt auf den strPtr-Zeiger*vPtr
ist eine Variable mit einer eigenen Adresse im Speicher*vPtr
ist eine Variable, die den Wert von address & strPtr speichertstr++
,str
Adresse ist eineconst
, aber Sie können tunstrPtr++
quelle