lvalue als Inkrementoperand erforderlich

Lesezeit: 6 Minuten

Benutzeravatar von ant2009
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.

  • Arrays sind keine Zeiger.

    – Michael Foukarakis

    29. Juli 2010 um 16:22 Uhr


Benutzeravatar von naivnomore
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 constjedenfalls) 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


Benutzeravatar von Sushil Kadu
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.

Benutzeravatar von Jacob
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.

Benutzeravatar von user2959760
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.

Benutzeravatar von Jerry Coffin
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

1386300cookie-checklvalue als Inkrementoperand erforderlich

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy