Variable über Zeiger verändern
-
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++.
-
Das erschließt sich aus der Bedeutung des Begriffs Rangfolge. Wenn Postfix-++ stärker bindet als *, dann ist *y++ dasselbe wie *(y++).
-
Also das finde ich ein wenig verwirrend.
da (y++) aufgrund der Klammern eine höhere Rangfolge hat wie * wird zuerst der Zeiger erhöht
und dann wird doch eigentlich der * ausgeführt oder ignoriert , was passiert denn dann.Nur aufgrund der Rangfolge ignoriert der Compiler das dereferenzieren.
Wozu ist diese Rangfolge überhaupt da?
-
Er ignoriert es doch gar nicht. Er wirft es nur wieder weg, weil du das Ergebnis nicht verwendest. Vielleicht ist das mit der Rangfolge noch nicht ganz klar ... erinnere dich an die Grundschulzeit. Punktrechnung vor Strichrechnung. D.h. bei 3 + 4 * 5 wird zuerst 4*5 gerechnet, dann 3 + 20. Also mit Klammern geschrieben 3 + (4 * 5). Hier ist es das gleiche. Ohne Rangfolge wär nicht klar, ob bei *y++ zuerst ++ oder zuerst * angewendet wird. Also ob dieser ausdruck gleichbedeutend mit (*y)++ oder mit *(y++) ist. Da ++ stärker bindet, ist es die zweite Variante.
-
Garnicht so einfach die Regeln der Mathematik auf die Syntax von C,C++
anzuwenden.Wäre es nicht sinnvoller, das * eine höhere Rangfolge wie ++ hat?