gcc 4.4.4
Was mache ich falsch?
char x[10];
char y[] = "Hello";
while(y != NULL)
*x++ = *y++;
Vielen Dank für jeden Rat.
Ameise2009
gcc 4.4.4
Was mache ich falsch?
char x[10];
char y[] = "Hello";
while(y != NULL)
*x++ = *y++;
Vielen Dank für jeden Rat.
naivnomore
x++
ist die Kurzform von x = x + 1
. Jedoch, x
Hier ist ein Array und Sie können die Adresse eines Arrays nicht ändern. So ist es bei deiner Variablen y
zu.
Anstatt zu versuchen, Arrays zu inkrementieren, können Sie eine Ganzzahl deklarieren i
und erhöhen Sie das, dann greifen Sie auf die zu i
‘ten Index eines Arrays.
char x[10], y[5] = "Hello";
int i = 0;
while (y[i] != 0)
{
x[i] = *y[i];
i++;
}
x[i] = 0;
Warum mischst du das *(x+i)
und x[i]
Formen im gleichen Code?
– Café
30. Juli 2010 um 8:33 Uhr
@caf Um die Beziehung zwischen den beiden zu demonstrieren.
– John Roberts
25. Dezember 2012 um 17:19 Uhr
warum darfst du dann argv++ machen? was ist das besondere an argv?
– David
7. Februar 2014 um 2:21 Uhr
@David Ich bin selbst ein Anfänger in C, also könnte ich mich irren, ist es aber nicht argv
deklariert als char *argv[]
(im Gegensatz zu char buf[]
in diesen Beispielen)? Das würde also nicht die Basisadresse des Arrays selbst ändern, sondern nur einen Zeiger relativ zu diesem Array. Oder?
– Benutzer966939
24. November 2015 um 6:07 Uhr
@David argv
ist nichts Besonderes; es ist ein Argument. Argumente (na ja, Argumente, die keine sind const
jedenfalls) sind vollständig änderbar, weil sie es sind Kopien der ursprünglichen Variablen. Deshalb eine Funktion, die modifiziert int x
muss so definiert werden void modifyX(int *x){ ... }
und so aufgerufen modifyX(&x)
. Folglich hat mich das hierher geführt, weil ich es so gewohnt bin, an einem vorbeizukommen char[]
in eine Funktion umwandeln und direkt ändern, dass ich verwirrt war, als ich diesen Kompilierfehler nach der Definition von a bekam char[]
in derselben Funktion, die die Basisadresse geändert hat. BIS
– Braden Best
13. Juli 2016 um 3:43 Uhr
Höchstwahrscheinlich sind Sie Opfer eines weitverbreiteten Missverständnisses geworden, dass “Array ein Zeiger” ist, dh wenn Sie ein Array definieren, erhalten Sie eigentlich einen gewöhnlichen Zeiger, der auf einen irgendwo zugewiesenen Speicherblock zeigt. In Ihrem Code versuchen Sie, diesen Zeiger zu erhöhen.
Der Code “funktioniert” nicht, weil Arrays in Wirklichkeit keine Zeiger sind. Arrays sind Arrays. Arrays können nicht inkrementiert werden. Es gibt keine Operation wie “ein Array inkrementieren” in der Sprache C. Tatsächlich sind Arrays von sich aus in C nicht veränderbar lWerte. Es gibt keine Operationen in C, die das Array selbst modifizieren können (nur einzelne Elemente können modifizierbar sein).
Wenn Sie Ihre Arrays mit der “Gleitzeiger”-Technik durchlaufen möchten (was Sie eigentlich versuchen), müssen Sie die Zeiger explizit erstellen und sie auf die Startelemente Ihrer Arrays zeigen lassen
char *px = x;
char *py = y;
Danach können Sie diese Zeiger beliebig weit erhöhen.
In “Wirklichkeit” Arrays sind Zeiger. Es ist wahr, dass stapelweise zugewiesene Arrays wie char myString[]
sind in dem Sinne unveränderlich, dass Sie die Adresse des Zeigers nicht ändern können. Aber das ändert nichts an der Tatsache, dass sie immer noch Zeiger auf den Anfang eines Speicherblocks sind, der sich im Stack befindet. Wenn Sie also sagen “Arrays sind keine Zeiger”, widersprechen Sie direkt grundlegenden Implementierungsdetails, die zum Verständnis von C erforderlich sind.
– Braden Best
13. Juli 2016 um 5:08 Uhr
@Braden Best: Falsch. Arrays sind KEINE Zeiger. Und dies ist in der Tat ein grundlegendes Detail, dessen Verständnis erforderlich ist, um C zu verstehen. Diese Angelegenheit wurde bereits zu Tode erklärt (c-faq.com/aryptr/index.html) und es ist höchst ungewöhnlich, dass heute, im Jahr 2016, noch jemand mit dem Konzept zu kämpfen hat. Dennis Ritchies Entscheidung, Zeiger für die Implementierung von Arrays aufzugeben, war einer der entscheidenden Schritte in der Entwicklung der Sprache. Und Sie wiederholen diesen „Arrays sind Zeiger“-Unsinn heute immer noch?
– AnT steht zu Russland
13. Juli 2016 um 6:09 Uhr
okay, dann was tut printf("%p", myString)
drucken? Oh, richtig, eine Speicheradresse. Ursache p ist für Zeiger. Weil sie als Zeiger implementiert sind, weil kein Typfehler ausgelöst wird, wenn Sie ein Array an eine Funktion senden, die einen Zeiger erwartet. Auch in einem C++-Compiler mit -Wall -pedantic
. Warum sollte jemand glauben, dass es ein Zeiger ist? Vielleicht, weil es so ist. Vielleicht weil *myString
dereferenziert die Adresse und gibt den Wert zurück, auf den der Zeiger zeigt. Zeiger sind Rechtecke und Arrays sind Quadrate. Alle Arrays sind Zeiger, aber nicht alle Zeiger sind Arrays. Sie schließen sich NICHT gegenseitig aus.
– Braden Best
13. Juli 2016 um 6:49 Uhr
array[n]
ist Syntaxzucker für *(pointer + n)
. Sie werden es vielleicht überraschend finden, in Ihrem Wahn ist alles auf hohem Niveau, Maschinencode existiert nicht in einer Fantasiewelt, das n[array]
gibt genau dasselbe zurück und erzeugt keinen einzigen Fehler oder keine Warnung von einem C- oder C++-Compiler, der mit ausgeführt wird -Wall -pedantic
. ALLE in der Praxis beobachtbaren Beweise deuten darauf hin, dass Arrays Syntaxzucker für Zeiger sind. Der einzige Widerspruch, dass die Adresse eines Arrays nicht innerhalb desselben Bereichs geändert werden kann, in dem sie definiert wurde, bedeutet nichts, wenn sie ohnehin einfach an eine andere Funktion übergeben werden kann.
– Braden Best
13. Juli 2016 um 6:59 Uhr
@Braden Best: Nein. Dein printf
druckt die Speicheradresse einfach deshalb korrekt, weil sie im C-Spracharray enthalten ist myString
in diesem Zusammenhang wird sofort sog. unterworfen Array-zu-Zeiger-Konvertierung (auch bekannt als “Array-Typ-Zerfall”). Das temporäre Ergebnis dieser Konvertierung – tatsächlich ein Zeiger – wird an gesendet printf
anstelle des Arrays. Dasselbe gilt für alle Ihre kleinen Experimente, die alle, wie gesagt, bereits totgeschlagen sind. Der FAQ-Link, den ich Ihnen gegeben habe, erklärt all dies.
– AnT steht zu Russland
13. Juli 2016 um 15:42 Uhr
Sushil Kadu
Arrays in C sind zwar Zeiger, aber konstante Zeiger, was bedeutet, dass ihre Werte nach der Deklaration nicht mehr geändert werden können.
int arr[] = {1, 2, 3};
// arr is declared as const pointer.
(arr + 1)
ist aber möglich arr++
ist nicht möglich, weil arr
kann keine andere Adresse speichern, da sie konstant ist.
Jacob
char x[10];
char y[] = "Hello";
char *p_x = &x[0];
char *p_y = &y[0];
while(*p_y != '\0') *p_x++ = *p_y++;
Da Sie die Array-Adressen nicht ändern können (erledigt von x++
und y++
in Ihrem Code) und Sie kann Ändern Sie die Zeigeradresse, ich kopierte über die Adresse des Arrays in separate Zeiger und dann erhöhte sie.
Wenn Sie möchten, können Sie die Notation sicher reduzieren, aber ich hoffe, Sie haben den Punkt verstanden.
x
und y
sind Arrays, keine Zeiger.
Sie zerfallen in den meisten Ausdruckskontexten in Zeiger, z. B. in Ihrem Inkrementausdruck, aber sie zerfallen in Rvalues, nicht in Lvalues, und Sie können Inkrementoperatoren nur auf Lvalues anwenden.
Benutzer2959760
In den meisten Fällen ist ein Array wie ein Zeiger.
Denken Sie daran, dass Sie das Array nicht ändern können!
Und y++
ist y = y + 1
.
char y[] = "Hello";
Sie ändern also das Array, wenn Sie y++
!!
Es wird produzieren error: lvalue required as increment operand
.
Jerry Sarg
Da Sie beide definiert haben x
und y
als Arrays können Sie sie nicht ändern. Eine Möglichkeit wäre, stattdessen Zeiger zu verwenden:
char x[10];
char *xx = x;
char *y = "Hello";
while (*y != '\0')
*xx++ = *y++;
Beachten Sie, dass ich auch Ihre Beendigungsbedingung korrigiert habe – ein Zeiger wird nicht NULL
nur weil es das Ende einer Zeichenfolge erreicht hat.
Ich denke, eine Null ist besser als eine Null.
– Ameise2009
29. Juli 2010 um 16:13 Uhr
Arrays sind keine Zeiger.
– Michael Foukarakis
29. Juli 2010 um 16:22 Uhr