Pointer und Adressen
-
Ja hallo, ich hab da mal ne frage bezueglich zeigern: Wenn man einen deklariert, besteht da ein unterschied wo das * hinkommt?
Quasi besteht ein unterschied zwischen:int* zeiger;
oder
int * zeiger;
oder
int *zeiger;
???
Und dann wollte ich noch wissen wieso manche Funktionen einen Zeiger auf eine Variable erwarten und andere die Variable selber???Thx vor antworten!
-
1. das ist egal aber viele unter diesen auch ich bevorzugen die erste Schreibwese
2. schau dir mal call by value und call by referenz an
-
1. Ahja klar, um zu signalisieren, dass es ein int-zeiger ist. OK.
2. Ja klar die beiden sachen kenn ich schon, also brauchen die Funktionen die Call by Reference nutzen, um sie z.B. mit werten zu fuellen!? und bei Call by Value nur um mit ihnen rechnen!? Aber manchmal muss ich trotzdem meine variablen mit cbr uebergeben obwohl die eh nur gelesen wird: uebrigens zeigt pointer auf ein struct! Warum? es wuerde doch reichen diese mit call by value zu uebergeben oder?
-
Hi!
Gerade wenn ein Parameter nur zum lesen benutzt wird bietet es sich an die Variable per Referenz zu übergeben. Wenn du eine Kopie übergibst dann kann man diesen Parameter auch ruhig verändern, z.B. um Zwischenergebnisse zu speichern oder so. Eine Übergabe per Referenz wird meistens zum Übergeben von Feldern verwendet, da ein Kopieren bei großen Feldern doch ziemlich aufwendig wäre.
Code-Hacker
-
@CodeHacker
du bist aber nicht bei Siemens.......?
-
Hi!
Nein, aber wenn du was auszusetzen hast, werde deutlich.
Code-Hacker
-
1. Da bevorzuge ich Variante 3, denn bei "int* a, b;" ist nur a der Zeiger.
2. Wenn die Variable in der Funktion verändert wird, aber die Original-Variable unverändert bleiben soll, dann Call-by-Value, ansonsten Call-by-Reference weil das schneller ist.Gruß WoWe
-
1. Da bevorzuge ich Variante 3, denn bei "int* a, b;" ist nur a der Zeiger.
2. Wenn die Variable in der Funktion verändert wird, aber die Original-Variable unverändert bleiben soll, dann Call-by-Value, ansonsten Call-by-Reference weil das schneller ist.Gruß WoWe
-
Hi!
Stimmt, also wenn man Zeiger- und Variablendeklaration nicht trennt ist die dritte Methode zu bevorzugen:
int* a, b; // undurchsichtig int *a, b; //imho durchsichtiger int b, *a; //Zeiger ans Ende und jeder erkennt was Zeiger ist und was nicht
Code-Hacker
-
WoWe schrieb:
2. Wenn die Variable in der Funktion verändert wird, aber die Original-Variable unverändert bleiben soll, dann Call-by-Value, ansonsten Call-by-Reference weil das schneller ist.
Aber z.B. bei Socket-Funktionen, muss ich manchmal structs by reference uebergeben, die imho nur gelesen werden!???? Kann mir da einer helfen?
-
Naja, das hat Code-Hacker ja schon erklärt, weil das evtl. bei großen struct's (Feldern) zu aufwendig ist.
-
Hi!
Bei größeren Datenstrukturen ist es besser diese per Referenz zu übergeben, gerade weil nur gelesen werden soll, wo ist dein Problem? Wenn sie nicht verändert wird und als Referenz übergeben wird ist das doch nur von Vorteil. Besser als wenn sie nicht verändert wird und by Value übergeben wird.
Ich glaube du hast irgendwo ein Verständnisproblem. Das hört sich so an als wenn es schlecht wäre das eine Struktur als Referenz übergeben wird und nicht verändert wird, gerade dann lohnt es sich aber.
Allerdings einen char oder int (keine Fehler) als Refernz zu übergeben ist sicher etwas doof, in diesem Fall sollte es per Value schneller gehen. Du solltest mal Assembler programmieren, dann siehst du wie eine Adresse (by Reference) übergeben wird und wie ein Wert (by Value) übergeben wird.
Code-Hacker
-
Also muss man das ja quasi immer auswendig lernen wann man die parameter bei welcher funktion by value oder by reference uebergeben muss
!
//e: @Code-Hacker: Ja hatte ein Verstaendnisproblem
Aber nun wo du es so sagst, klingt es einleutend dieses grosse struct/array oder what ever nicht extra nochmal zu kopieren und dann der Funktion zu uebergeben!!
-
Hi!
Noe, jede Funktion sollte eine Beschreibung mit sich bringen oder man sieht sich den Funktionskopf im jeweiligen Header an, dann sieht man doch ob einer der Parameter ein Zeiger ist oder nicht.
Code-Hacker
-
Ja schon klar, aber ich meinte doch, dass es keine einheitliche Regel gibt, wann by reference und wann by value uebergeben wird! Aber ich erzaehl schon wieder mist...wat fuer ne kranke idee ne einheitl. regel dafuer zu ham...naja is schon spaet!!! Naja hab halt zuvor VB programmiert und grad erst mit C angefangen und da war noch nix so mit Pointern und Variabelnadressen...
MfG Code-Hacker und WoWe
-
Code-Hacker schrieb:
Eine Übergabe per Referenz wird meistens zum Übergeben von Feldern verwendet, da ein Kopieren bei großen Feldern doch ziemlich aufwendig wäre.
Du kannst Felder (Arrays) sowieso nicht by-value übergeben (sofern du es vorher nicht irgendwie verpackst, zB mit struct), da der Compiler standardmässig eine Typumwandlung von T[N] nach T* vornimmt.
XFame schrieb:
Aber manchmal muss ich trotzdem meine variablen mit cbr uebergeben obwohl die eh nur gelesen wird
Für solche Sachen gibt es ua const.
WoWe schrieb:
1. Da bevorzuge ich Variante 3, denn bei "int* a, b;" ist nur a der Zeiger.
Das ist aber imo eine Designschwäche von C/C++, nach der man seinen Code nicht ausrichten sollte. Den Stern (*) sollte man eher zum Typ schreiben, da er dort besser aufgehoben ist, denn es ist ein Typmodifizierer und hat mit dem Bezeichner nix zu tun.
-
Hi!
groovemaster schrieb:
Code-Hacker schrieb:
Eine Übergabe per Referenz wird meistens zum Übergeben von Feldern verwendet, da ein Kopieren bei großen Feldern doch ziemlich aufwendig wäre.
Du kannst Felder (Arrays) sowieso nicht by-value übergeben (sofern du es vorher nicht irgendwie verpackst, zB mit struct), da der Compiler standardmässig eine Typumwandlung von T[N] nach T* vornimmt.
Weiß ich alles (hatte im Sommer C in der Schule und C++ progge ich auch schon etwas länger).
Code-Hacker
-
groovemaster schrieb:
WoWe schrieb:
1. Da bevorzuge ich Variante 3, denn bei "int* a, b;" ist nur a der Zeiger.
Das ist aber imo eine Designschwäche von C/C++, nach der man seinen Code nicht ausrichten sollte. Den Stern (*) sollte man eher zum Typ schreiben, da er dort besser aufgehoben ist, denn es ist ein Typmodifizierer und hat mit dem Bezeichner nix zu tun.
Aber so gesehen koennte man bei Variante:
int* a, b;
denken, dass beide Variablen Zeiger sind! Ach ja: Sind Arraynamen nicht einfach nur Zeiger aufs erste Element und werden deswegen immer by Reference uebergeben?
Naja, und was meintest du nun mit Konstanten?? Hab ich den Zusammenhang nicht ganz verstanden sry.
-
Hi!
Eine Variable wird als const deklariert, wenn diese nicht verändert werden soll bzw. darf (in C sind es aber keine echten Konstaten, echte Konstanten sind nur mit #define möglich).
Felder und Zeiger sind eng miteinander verwandt, aber nicht ganz das selbe (such mal im Forum, da findest du sicher was zu diesem Thema). Aber du hast insofern recht das der Name eines Feldes als Zeiger auf sein erstes Element benutzt werden kann (was nicht heißt das der Name wirklich ein Pointer ist).Code-Hacker
-
XFame schrieb:
Aber so gesehen koennte man bei Variante:
int* a, b;
denken, dass beide Variablen Zeiger sind!
Wie ich schon sagte, ist das imo eine Designschwäche. Wenn ich sowas als Anfänger sehe, würde ich auch darauf tippen, dass beide Variablen Zeiger sind. Machst du zB folgendes
typedef int* int_zeiger; int_zeiger a, b;
sind plötzlich beide Variablen auch Zeiger.
XFame schrieb:
Ach ja: Sind Arraynamen nicht einfach nur Zeiger aufs erste Element
Nein, sind sie nicht. Darüber gabs aber schon einige Diskussionen hier im Forum.
Guck mal hier http://www.c-plusplus.net/forum/viewtopic.php?t=91822 und lies dir die Beiträge von Bashar und mir durch.XFame schrieb:
Naja, und was meintest du nun mit Konstanten?? Hab ich den Zusammenhang nicht ganz verstanden sry
.
Bei Variablen, die by-value übergeben werden, brauchst du dir keine Sorgen machen, dass ihr Wert verändert wird. Du arbeitest ja mit Kopien, die nach dem Ende der Funktion wieder zerstört werden. Sachen wie
void foo(const int x)
sind deshalb auch recht sinnfrei.
Wenn du hingegen eine Variable hast, die du by-reference übergibst, arbeitest du mit dem ursprünglichen Wert. Wenn du dort etwas veränderst, wird sich das auch ausserhalb der Funktion auswirken. Ist dies nicht erwünscht, machst du die "Referenz" einfach const, zBvoid foo(const bar* x)
.
Damit wird sichergestellt (sofern du keine Casts benutzt), dass lesender Zugriff möglich ist, aber kein schreibender.