Verständniss frage zu Zeigern
-
Hallo Leute,
ich bin gerade dabei c++ zu lernen und vorab es macht mir viel Spass
nur ich habe noch des öfteren Probleme wenn ich zb. Beispiele oder tuts lese. Da sehe ich immer das manche so ihre Zeiger anlegennur als beispiel:
Typ* pZeigerjetzt meine Frage dazu. Ich habe in meinen Büchern immer nur solche Statements zum anlegen von Zeigern gesehen
Typ *pZeigerwas ist den da der Unterschied ? Ist das ein Problem wenn ich das falsch mache? Wie weip ich ob ich den Stern vorne oder hinten schreiben muss ?
lg
Chris
-
Es gibt keinen inhaltlichen Unterschied -> Geschmacksache...
Ich mal gelesen, dass dies eher C++ Style ist:
Typ* pZeigerwährend das C Style ist
Typ *pZeigerFrag mich nicht warum...
(Kann auch sein, dass ich es genau vertauscht habe
)
-
Dem Compiler ist das völlig egal.
Typ * pZeiger;funktioniert auch.
Lars
-
Interessant wir des dann, wenn du mehrere Zeiger gleichzeitig deklarierst:
Type *pMyType1, *pMyType2; Type* pMyType3, pMyType4;Was sind das jetzt für Variablen??? Das * ist rechtsassoziativ, das heißt es hängt an dem was rechts davon steht mehr als an dem, was links davon steht (oder war es linksassoziativ???). pMyType4 ist daher kein Pointer, sonder vom Typ 'Type'. Insofern macht es schon Sinn, das * nach C-Style zu schreiben, so vermeidet man Flüchtigkeitsfehler.
Übrigens könnte man das auch so schreiben:Type * pMyType;PS: Misst, Manni war schneller
-
Heimelchen schrieb:
Insofern macht es schon Sinn, das * nach C-Style zu schreiben, so vermeidet man Flüchtigkeitsfehler.
Oder man definiert auf einer Zeile nur eine Variable. In C musste man früher alle Variablen im Kopf der Funktion definieren, daher mag das vielleicht etwas kompakter gewirkt haben, wenn man mehrere Variablen auf einer Zeile definiert hat. In neuerem C und auch in C++ definiert man die Variablen sowieso erst bei der ersten Verwendung, daher sind es meistens sehr wenig auf einmal, und man kann pro Zeile eine Variable hinschreiben, ohne dass man nun 20 Zeilen Variablendefinitionen hat

Grüssli
-
Hallo,
zwischen operatoren und operanden dürfen 0 bis n Whitespaces stehen. Das gilt auch für die Deklaration von Zeigern. Es ist also völlig gleichgültig ob Du
TYPE*zeiger; TYPE * zeiger; TYPE* zeiger; oder TYPE *zeiger;schreibst.
Nur: Die Lesbarkeit des Codes für menschliche Leser sollte gewährleistet sein. Auch sollte innerhalb eines Quelltextes die verschiedenen Schreibweisen nicht gemischt werden. Dem Compiler ist das aber wurscht.
mfg Martin
-
Oh wow danke leute für die Antworten

also ist es völlig egal ob ich es links oder rechts schreibe. Ich habe mir es in der kurzen Zeit nämlich so angewohnt es rechts beim Pointer und nicht beim Typ zu schreiben.danke euch

-
Dravere schrieb:
Oder man definiert auf einer Zeile nur eine Variable. In C musste man früher alle Variablen im Kopf der Funktion definieren, daher mag das vielleicht etwas kompakter gewirkt haben, wenn man mehrere Variablen auf einer Zeile definiert hat. In neuerem C und auch in C++ definiert man die Variablen sowieso erst bei der ersten Verwendung, daher sind es meistens sehr wenig auf einmal, und man kann pro Zeile eine Variable hinschreiben, ohne dass man nun 20 Zeilen Variablendefinitionen hat

Da kommt noch hinzu, dass lokale Zeiger kaum bis gar nicht vorkommen. In C++ hat man Referenzen, Iteratoren und Smartpointer, rohe Zeiger aber fast nie.
Lediglich bei Klassen findet man die noch gelegentlich und bei Klassendeklaration ist eine Variable pro Zeile ohnehin allgemein üblich.Also kann man den Stern getrost da hinsetzen, wo er hingehört: zum Typen. :p
-
Athar schrieb:
Da kommt noch hinzu, dass lokale Zeiger kaum bis gar nicht vorkommen. In C++ hat man Referenzen, Iteratoren und Smartpointer, rohe Zeiger aber fast nie.
Lediglich bei Klassen findet man die noch gelegentlich und bei Klassendeklaration ist eine Variable pro Zeile ohnehin allgemein üblich.Also kann man den Stern getrost da hinsetzen, wo er hingehört: zum Typen. :p
Referenzen benutze ich nur, wenn es unbedingt sein muß oder der Lesbarkeit dient. Normalerweise also gar nicht.
void func1( TYPE *pointer ); void func2( TYPE &pointer ); void func3( void ) { TYPE value; func1( &value ); // hier sehe ich sofort, daß der Parameter by reference übergeben wird func2( value ); // hier muß ich mir die Funktionsdeklaration anschauen }Der Stern gehört nicht zum Typen sondern zur Variable, da er sich nur dort auswirkt;
TYPE *pointer, value; // Hier wird ein Zeiger und ein Objekt deklariert.mfg Martin
-
@mgaeckler: Da bist du aber ziemlich alleine mit deinem Geschmack. Überhaupt ist auch call-by-(nicht konstanter)-reference eher ungewöhnlich in C++, wenn man es nicht mit dehr großen Objekten zu tun hat.
-
mgaeckler schrieb:
void func1( TYPE *pointer ); void func2( TYPE &pointer ); void func3( void ) { TYPE value; func1( &value ); // hier sehe ich sofort, daß der Parameter by reference übergeben wird func2( value ); // hier muß ich mir die Funktionsdeklaration anschauen }Hmm eine frage zu diesem Code. Habe ich das richtig verstanden das beide Funktionen den gleichen Parameter haben ? also ist es egal ob bei der Funktion
Funktion (TYPE *Pointer)definiere und dann beim Aufruf
Funktion( &value ).
oder es so mache
Funktion (TYPE &Pointer)und beim aufruf dann so
Funktion( value )??
lg chris
-
mgaeckler schrieb:
[...]
func1( &value ); // hier sehe ich sofort, daß der Parameter by reference[...]
Und was hilft Dir dieses Wissen? Du weisst immer noch nicht, ob der Wert geändert wird, oder nicht oder ob es ein Zeiger auf const ist, oder nicht. Ergo hasst Du keine Ahnung, was mit dem Wert passiert...
-
Tachyon schrieb:
mgaeckler schrieb:
[...]
func1( &value ); // hier sehe ich sofort, daß der Parameter by reference[...]
Und was hilft Dir dieses Wissen? Du weisst immer noch nicht, ob der Wert geändert wird, oder nicht oder ob es ein Zeiger auf const ist, oder nicht. Ergo hasst Du keine Ahnung, was mit dem Wert passiert...
In C++ hilft es mir tatsächlich wenig, weil es ja eine Referenz sein könnte. In C sehe ich durch die Parameterübergabe by value sofort beim Aufrufer, daß der Wert nicht verändert werden kann. In C++ ist beim Aufruf kein Unterschied zwischen der Parameterübergabe by value und by referenz.
mfg Martin
-
CodeBase schrieb:
Hmm eine frage zu diesem Code. Habe ich das richtig verstanden das beide Funktionen den gleichen Parameter haben ? also ist es egal ob bei der Funktion
Funktion (TYPE *Pointer)definiere und dann beim Aufruf
Funktion( &value ).
oder es so mache
Funktion (TYPE &Pointer)und beim aufruf dann so
Funktion( value )??
lg chris
Semantisch ist beides das gleiche. func1 und func2 bekommen beide die Adresse von value.
mfg Martin
-
mgaeckler schrieb:
Semantisch ist beides das gleiche. func1 und func2 bekommen beide die Adresse von value.
mfg Martin
Das stimmt nicht. Im ersten Fall hat man eine Übergabe per Wert (der Wert des Zeigers).
Im zweiten Fall hat man eine Übergabe per Referenz, also das Objekt selbst unter dem Namen des formalen Parameters. Hinter der Referenz kann zwar Zeigermechanik am werkeln sein, muss aber nicht.
-
Der Stern gehört logisch zum Typen, da ändert es auch nichts, dass die C-Designer raffiniert sein wollten.
Warum man diese Eigenheit ignorieren kann, haben Dravere und ich schon erläutert.Wenn du eine Funktion aufrufst, wär's übrigens nicht ganz verkehrt, wenn du weißt, was für Parameter sie erwartet und wozu sie verwendet werden. Woraus sich alles weitere ergibt.
Wenn du gerade fremden Code liest, gibt es notfalls Calltips zur schnellen Aufklärung, wenn etwas mal nicht eindeutig sein sollte.
-
Tachyon schrieb:
Das stimmt nicht. Im ersten Fall hat man eine Übergabe per Wert (der Wert des Zeigers).
Im zweiten Fall hat man eine Übergabe per Referenz, also das Objekt selbst unter dem Namen des formalen Parameters. Hinter der Referenz kann zwar Zeigermechanik am werkeln sein, muss aber nicht.Das sind Implementierungsdetails, die den Compilerbauer interessieren. Für den C++-Programmierer ist es Jacke wie Hose. Deswegen schrieb ich ja auch "semantisch".
void func1( TYPE *pointer ) { *pointer = value: } void main( void ) { TYPE variable; func1( &variable ); }und
void func1( TYPE &reference ) { reference = value: } void main( void ) { TYPE variable; func1( variable ); }machen exakt das gleiche.
mfg Martin
-
Athar schrieb:
Der Stern gehört logisch zum Typen, da ändert es auch nichts, dass die C-Designer raffiniert sein wollten.
Warum man diese Eigenheit ignorieren kann, haben Dravere und ich schon erläutert.Wer war eher da, Huhn oder Ei?
Vom Bauchgefühl würd ich dir ja recht geben. Aber mein Kopf stellt sich die Frage, warum der * logisch zum Typen gehört, wenn die Assoziativität ihn an die Variable bindet? Vielleicht hatte the god father of C da eine andere Logik...
-
typedef int * pint; pint p;lese ich als
int * p;Damit gehört für mich der * zum Typ.
Klappt natürlich nur, wenn man für jede Variable eine eigene Zeile opfert, aber das mache ich gerne. Im Weiteren schließe ich mich Dravere an.
-
SeppJ schrieb:
@mgaeckler: Da bist du aber ziemlich alleine mit deinem Geschmack. Überhaupt ist auch call-by-(nicht konstanter)-reference eher ungewöhnlich in C++, wenn man es nicht mit dehr großen Objekten zu tun hat.
Das mag sein. Jahrelange Arbeit mit C hat natürlich meinen Stil geprägt. Mag sein, daß er anders wäre, wenn ich gleich mit C++ angefangen hätte. Das gab's damals aber noch nicht.
Ich habe mir es so angewöhnt:
Funktionen, die größere Objekte erhalten ohne sie verändern zu wollen, definiere ich mit const referenzen. Funktionen, die die Werte verändern wollen, bekommen einen Zeiger.
mfg Martin