Variable über Zeiger verändern
-
Alexander Kempf schrieb:
++(*y);oder so
*y += 1;
-
Moment mal. Ich wäre in die gleiche Falle getappt.
*y++;Das ist doch post inkrementell. Da sollte ganz klar als *y und dieser Ausduck++ ausgewertet werden, oder nicht?
Bei ++*y könnte ich es noch verstehen. Hier macht er es aber seltsamerweise richtig. x wird 7!!
Ich hätte es definitiv anders herum erwartet! Kann das vielleicht mal jemand mit einem anderen Compiler testen? Respektive kann mir jemand sagen, welchem Denkfehler ich aufsitze.

-
Nach einigem ausprobieren habe ich herausgefunden das es mit *y += 1
klappt.
-
Joe_M. schrieb:
Das ist doch post inkrementell. Da sollte ganz klar als *y und dieser Ausduck++ ausgewertet werden, oder nicht?
Respektive kann mir jemand sagen, welchem Denkfehler ich aufsitze.
Wie ich bereits geschrieben habe, habe ich das mal in meinem kleinen C/C++-Büchlein nachgeschlagen (C/C++ ge-packt).
Darin habe ich eine Tabelle über die Rangfolge (Prioritäten, Auswertungsreihenfolge) von Operatoren gefunden und in dieser
Tabelle stehen * und ++ auf einer Ebene.
Leider weiß ich nicht, in welcher Reihenfolge dann abgearbeitet wird, aber offenbar hat sich der Borland Compiler für ++
zuerst und dann * entschieden.
Beim preinkrement ++ hat der Compiler keine Wahl - er muß erst * auswerten, um überhaupt etwas inkrementieren zu können.
Würde mich aber auch mal interessieren, ob das mit anderen Compilern auch so läuft.Gruß,
Alexander
-
Aber hier wird doch der Zeiger durch *-Op derefenziert. Die Frage ist doch dann, ob die Dereferenzierung eine niedrigere Priorität hat, als das Post-Inkrement?! Oder gilt der *-Op generell als Arithmetischer Op, womit meine Frage dann ins Wasser fällt...

-
PuppetMaster2k schrieb:
Aber hier wird doch der Zeiger durch *-Op derefenziert. Die Frage ist doch dann, ob die Dereferenzierung eine niedrigere Priorität hat, als das Post-Inkrement?! Oder gilt der *-Op generell als Arithmetischer Op, womit meine Frage dann ins Wasser fällt...

Ich habe niemals von dem Multiplikationsoperator gesprochen und auch in dem Büchlein stehen der Dereferenzierungsoperator * und
der Inkrementierungsoperator ++ (egal ob post oder pre) auf einer Ebene.
Der Multipliaktionsoperator * hat sowieso eine niedrigere Priorität.Gruß,
Alexander
-
Alles klar, war ein Missverständnis meinereits

-
Aber sowas wie:
int x=4; int y=x++; cout<<y; //Ausgabe: 4 cout<<x; //Ausgabe: 5Wird doch immer so ausgewertet wie an den kommentaren ersichtlich, oder? Wenn das "++" nach der Variable steht muss doch ein "falsches" Ergebnis rauskommen...
edit: Um ehrlich zu sein versteh ich net was das Programm soll...
-
ness schrieb:
Wird doch immer so ausgewertet wie an den kommentaren ersichtlich, oder?
Das ist ja genau meine Rede. Es sollte zuerst dereferenziert werden und dann ein inkrement durchgeführt werden...
Allerdings ergibt Alexanders Aussage einen scheußlichen Sinn: Bei der Schreibweise *y++ liegt es 'im Ermessen des Compilers', welche Operation zuerst ausgeführt wird -> da gleiche Ausführungsprorität!?!
Im Zweifelsfall dann doch lieber einmal zuviel klammern...
-
Also *x heist ja eigentlich indirekt über den Zeiger, x wäre ja der Zeiger
selbst.Warum aber "*x = 6" in der Funktion test1 und "obj->Text = text" in der Funktion
test2, müsste es nicht eigentlich *obj->Text heissen?void __fastcall TForm1::FormCreate(TObject *Sender) { char z = 0; test1(&z); test2(Edit1,"hallo"); z = z; } //--------------------------------------------------------------------------- void TForm1::test1(char* x) { *x = 6; return; } void TForm1::test2(TEdit* obj,char* text) { obj->Text = text; return; }
-
Weder bin ich der C++-König noch hat das jetzt speziell irgendwas mit dem BCB oder der VCL zu tun.
Aber in test1() verarbeitest Du ein Argument vom Typ char*, also eine Referenz (Zeiger) auf einen char.
Möchtest Du nun den Wert des char ändern, musst Du - wie geschehen - zunächst mit * dereferenzieren.
Würdest Du das nicht tun, würdest Du "den Zeiger verbiegen".In test2() hast Du eine Referenz auf ein TEdit. TEdit hat eine Eigenschaft "Text". Um diese Eigenschaft
ansprechen zu können, muss auch hier mit *dereferenziert werden. Anschließend kann man mit .Text die
entsprechende Eigenschaft lesen/ändern. Die Kurzform von * und . ist ->.Das sind aber eigentlich Grundlagen und falls Dir das klar ist, habe ich die Frage wohl nicht verstanden.
Gruß,
Alexander
-
Mal so nebenbei, warum in jeder Funktion ein return am Ende wo die Funktion doch eh schon abgearbeitet ist?
-
Alexander Kempf schrieb:
Um diese Eigenschaft ansprechen zu können, muss auch hier mit *dereferenziert werden.
Es ist mir schon klar das ich nur eine Referenz auf die Variable/ das Objekt
übergebe und wenn ich nicht dereferenziere wird halt der Zeiger verändert.Das Objekt Edit1 hat seinen eigenenen Speicherbereich für alle seine Eigenschaften der Zeiger wir beim erstellen des Objekts Edit1 erstellt(this).
Das dereferenzieren von obj->Text passiert also mit dem ->.
Das mit Return mache ich aus Gewohnheit, da ich Jahrelang Assembler
programmiert habe und da ist fatal das ret zu vergessen.
Ausserdem sieh es schöner aus.
-
Joe_M. schrieb:
Allerdings ergibt Alexanders Aussage einen scheußlichen Sinn: Bei der Schreibweise *y++ liegt es 'im Ermessen des Compilers', welche Operation zuerst ausgeführt wird -> da gleiche Ausführungsprorität!?!
Im Zweifelsfall dann doch lieber einmal zuviel klammern...Es liegt nicht im Ermessen des Compilers. Der Postfix-++ hat eine höhere Rangfolge als der Dereferenzierungsoperator, siehe FAQ: http://www.c-plusplus.net/forum/viewtopic.php?t=39479
-
Eine Frage noch zu Edit1->Text = " ".
Es wird beim Erstellen des Objekts Edit1 ein Speicherbereich für die
Eigenschaften/Variabeln des Ojekts Edit1 der Klasse TEdit bereitgestellt.Mit TEdit *Edit1 = new TEdit wird ein Zeiger Edit1 erzeugt, nehmen wir an
das Edit1 3 Eigenschaften a,b,c hat die sich im Speicherbereich 10-12 befindena->Adresse10;
b->Adresse11;
c->Adresse12;dann zeigt Edit1->a auf die Adresse 10, auf welche Adresse zeigt nun aber
der Zeiger *Edit1?Bashar schrieb:
Es liegt nicht im Ermessen des Compilers. Der Postfix-++ hat eine höhere Rangfolge als der Dereferenzierungsoperator, siehe FAQ: http://www.c-plusplus.net/forum/viewtopic.php?t=39479
++ postfix increment unärWas heist unär?
-
@Hermes:
Unär bezieht sich auf eine mathematische Operation
mit einem einzelnen Operanden (Objekt).*Edit1 ergibt keinen Zeiger. *ZeigerAufObjekt ergibt das Objekt oder den Wert der sich hinter dem Zeiger verbirgt.
int x; // Integerobjekt erzeugen int* y; // Zeiger auf ein Integerobjekt deklarierenUm nun über y an den Wert von x zu gelangen muss man *y verwenden. Als Parameter von Funkionsaufrufen ergeben sich deutliche Unterschiede.
Test(x); // Hierbei wird eine Kopie des Integers an die Funktion übergeben. Der Wert kann in der Funktion nicht geändert werden, ohne dass eine Zuweisung erfolgt.
Test(&x); // oder Test(y); Hierbei wird ein Zeiger auf den Integer an die Funktion übergeben. Alle Änderungen an x innerhalb der Funktion wirken sich auf den Originalwert aus.
int Test(int x) { x++; return x; } // Funktionsaufruf int y = 5; y = Test(y); // ohne diese Zuweisung wird keine Änderung an y durchgeführt.void Test(int* x) { ++*x; // hier wird direkt die Variable aus der aufrufenden Funktion geändert. } //Funktionsaufruf: int y = 5; int z = &y; Test(&y); // oder Test(z);@Bashar:
Die Tabelle ist im BCB etwas anders:Operatoren Abarbeitungsreihenfolge () [] -> :: . von links nach rechts ! ~ + - ++ -- & * sizeof new delete von rechts nach links .* ->* von links nach rechts * / % von links nach rechts + - von links nach rechts << >> von links nach rechts < <= > >= von links nach rechts == != von links nach rechts & von links nach rechts ^ von links nach rechts | von links nach rechts && von links nach rechts || von rechts nach links ?: von links nach rechts = *= /= %= += -= &= ^= |= <<= >>= von rechts nach links , von links nach rechts
-
Joe: Naja, dann zählt eben "rechts nach links". Kommt auf dasselbe raus.
-
Na ja, ein paar Operatoren haben dann doch eine andere Reihenfolge... z.B. der Scope-Operator :: hat in der Stanley B. Lippman/Josée Lajoie Tabelle die höchste Priorität. In der BCB-Tabelle sind (), [], und -> mit höherer Priorität ausgewiesen. (_grummel_grummel_)
Für das hier geschilderte Problem macht's natürlich keinen Unterschied, da in beiden Fällen ++ die höhere Priorität hat.
Ich bleib dabei: Lieber einmal zuviel klammern, als einmal zu wenig...
-
Joe_M. schrieb:
Ich bleib dabei: Lieber einmal zuviel klammern, als einmal zu wenig...
Allein schon wegen der Lesbarkeit. Natürlich macht es Spaß die Kollegen mit kryptischen Ausdrücken zu quälen, aber
wer andern eine Grube gräbt, versteht nächste Woche den eigenen Code nicht mehr...Gruß,
Alexander
-
! ~ + - ++ -- & *
Ok, das ++ hat eine höhere Abarbeitungsreihenfolge wie *.
Ich verstehe aber deswegen immer noch nicht warum nicht die
Variable sonder der Zeiger selbst erhöht wird.
*y++.