Gültigkeitsbereich
-
Hallo,
Ich hab dein Programm so modifiziert, dass der Zeiger als Referenz übergeben wird:
#include <iostream> #include <cstdlib> #include <cstring> using namespace std; void array1d(int &n); void array2d(double *&A1, int &n); int main(int argc, char **argv){ int n; double *A1; array1d(n); array2d(A1,n); cout << "n : " << n << endl; cout << "A[0] : " << A1[0] << "A[1] : " << A1[1] << endl; return EXIT_SUCCESS; } void array1d(int &n){ n = 2; } void array2d(double *&A1, int &n){ A1 = new double[n]; A1[0] = 0.1234; A1[1] = 0.5678; }Beachte die Zeilen 8 und 28. Hier wurde die Funktion so verändert, dass nun der Zeiger selbst und nicht eine Kopie des Zeigers an die Funktion übergeben wird.
Bei mir klappt es. Ich hoffe ich konnte dir weiterhelfen.MfG, Jochen
-
Hallo Jochen, danke für die schnelle Hilfe. Hat in jedem Fall weitergeholfen.
Referenzen werden doch intern mit Zeigern realisiert, also müsste es doch eine Zeier auf Zeiger Lösung (**A1) Lösung geben. Vielleicht könnte hier mal jemand auch daszu was posten. Ich möchte wissen was ich hier so lange falsch gemacht habe.
Nachtrag:
Verstehe ich das jetzt richtig dass bei "&A1" die Adresse vom Zeiger genommen wird (nicht worauf er zeigt). Mit "*&A1" wird ein Zeiger auf die Adresse vom Zeiger an die Funktion weitergegeben? Bin ein wenig verwirrt.
-
Ok, dies sieht wenigstens aus, wie C++.
#include <iostream> using namespace std; void foo(int &n){ n = 2; } int main(){ int i = 0; foo(i); cout << "i : " << i << endl; }Guck dir mal dieses Programm an. Wenn man foo() aufruft, wird n auf 2 gesetzt und diese Änderung wird auch im Hauptprogramm bekannt. Die Variable i im Hauptprogramm hat hinterher auch den Wert 2. Du hast selber eine Funktion geschrieben, die genauso aussieht wie foo(), deshalb kannst du diese Fragen beantworten: Warum funktoniert das so? Und was bedeutet dieses &-Zeichen?
Und jetzt ändere diese Funktion mal in:
void foo(int n){ n = 2; }Du wirst sehen, dass dies immer noch compiliert. Aber dieses Mal bleibt der Wert von i im Hauptprogramm gleich 0. Warum ist das so?
Und wenn du diese Fragen beantwortet hast, dann guckst du dir nochmal deine Funktion an:
void array2d(double *A1, int &n){ A1 = new double[n]; A1[0] = 0.1234; A1[1] = 0.5678; }Hier wird der Wert von A1 in der Funktion geändert, aber diese Änderung wird nicht weitergegeben. Warum ist das wohl so?
-
darkfate schrieb:
Hallo Jochen, danke für die schnelle Hilfe. Hat in jedem Fall weitergeholfen.
Referenzen werden doch intern mit Zeigern realisiert, also müsste es doch eine Zeier auf Zeiger Lösung (**A1) Lösung geben. Vielleicht könnte hier mal jemand auch daszu was posten. Ich möchte wissen was ich hier so lange falsch gemacht habe.
Ja, das geht intern (häufig) mit Zeigern. Und das ist auch der Ansatz den du zuerst versucht hast, den du aber nicht umsetzen konntest, weil du ihn nicht verstanden hast. Um das zu erklären, müsstest du verstehen, was Zeiger sind - dieses Wissen fehlt dir aber anscheinend (Was in C++ übrigens nicht so schlimm ist, da man Zeiger eher selten braucht). Ich kann aber an dieser Stelle Zeiger nicht erklären. Das Thema ist nicht zu unrecht in den meisten Lehrbüchern ein dickes Kapitel. Du musst dir so ein Lehrbuch schon erstmal durchlesen, bevor ich dir erklären kann, was man mit Zeigern wie machen kann.
-
Zum Thema Zeiger gibt es doch einen schönen Artikel im Magazin.
http://www.c-plusplus.net/forum/viewtopic-var-t-is-254043.html
-
SeppJ schrieb:
...
Also noch einmal. Verstehen ist nicht mit der Syntax zurechtkommen.
Nachtrag:
Ich weiß deine Hilfe zu schätzen aber du frustrierst mich mit deinen Leseaufforderungen.Du verstehst die Welt auch nicht von Grund auf und trotzdem hältst du dich darin auf. Wenn du Fragen zur Welt hast dann wendest du dich an jemanden der sich auskennt und es dir erklären kann. Als Antwort bekommst du sicherlich nicht eine Seitenzahl genannt obwohl du mehrmals darauf hingewiesen hast dass du es bereits gelesen und nicht ganz verstanden hast.
Wenn ich es so wie du tun wollte würde ich stur das Buch solange durchlesen bis ich es endlich verstanden habe und nicht ein Forum wie dieses anschreiben. Auf ein Buch zu verweisen, welches du selber nicht kennst ist keine Hilfe. Bücher die ich nicht habe aufzulisten ist genau so sinnvoll.
Ich verstehe was ein Zeiger ist, ich weiß wie man damit rechnet und umgeht. Ich weiß wie man auf einfache Arrays Zeiger anwendet und wie man sie als Funktionsparameter übergibt. Auch kenne ich den Unterschied zwischen Call by Value und Call by Reference.
Wie ich schon zehnmal geschrieben habe, beginnen meine Probleme beim "**" und das bei der Syntax. Da mein Buch es offensichtlich nicht klar genug hergibt stelle ich hier eine Frage und möchte kein Rätsel als Antwort. Wenn alle Lehrkräfte so unterrichten würden und jeder für sich selbst alles zerkauen und herleiten musste, wären wir in der Steinzeit.
Nachtrag 2:
Hätte man mir wie Jochen direkt genautwortet, wäre ich schon längst zufrieden und hätte den Grund für meinen Fehler erkannt. Stattdessen habt ihr eure Zeit mit Rätselbau und ich meine Zeit mit Rästelraten verloren.
-
darkfate schrieb:
Wenn alle Lehrkräfte so unterrichten würden und jeder für sich selbst alles zerkauen und herleiten musste, wären wir in der Steinzeit.
Und das andere Extrem sieht man inzwischen in vielen Schulabgängern: Die langsamsten halten alle auf. Nicht, das man nicht auf einzelne eingehen sollte, aber die Frage ist: wie lange?
-
asc schrieb:
Und das andere Extrem sieht man inzwischen in vielen Schulabgängern: Die langsamsten halten alle auf. Nicht, das man nicht auf einzelne eingehen sollte, aber die Frage ist: wie lange?
Wo bitte stellt es ein Extrem da wenn man eine Frage zu einem nicht verstandenen Thema hat?
-
Ein erstes Erfolgserlebnis. Kurz nach Jochens Anwort habe ich das ganze auch auf 2D Arrays usw.. anwenden können. Nicht einmal eine halbe Stunde musste ich opfern um es zu verstehen.
#include <iostream> #include <cstdlib> #include <cstring> using namespace std; void array1d(int &n); void array2d(double *&A1, int &n); void array3d(double **&A2, int &n); int main(int argc, char **argv){ int n; double *A1; double **A2; array1d(n); array2d(A1,n); array3d(A2,n); cout << "n : " << n << endl; cout << "A[0] : " << A1[0] << "\tA[1] : " << A1[1] << endl; cout << "A[0][0] : " << A2[0][0] << "\tA[0][1] : " << A2[0][1] << endl; cout << "A[1][0] : " << A2[1][0] << "\tA[1][1] : " << A2[1][1] << endl; for(int i=0;i<n;i++) delete A2[i]; delete [] A2; return EXIT_SUCCESS; } void array1d(int &n){ n = 2; } void array2d(double *&A1, int &n){ A1 = new double[n]; A1[0] = 0.1234; A1[1] = 0.5678; } void array3d(double **&A2, int &n){ A2 = new double*[n]; for(int i=0;i<n;i++) A2[i] = new double[2]; A2[0][0] = 1234; A2[0][1] = 1234; A2[1][0] = 1234; A2[1][1] = 1234; }Funktioniert einwandfrei. Wenn sich jemand noch die Zeit nehmen könnte und zeigt wie die Syntax aussieht wenn man nur mit Derefferenzierungen arbeitet.
Also nur "**" ohne das "&".Das frustrierende an dieser ganzen Sache ist, dass es mich an meine ersten Monate mit Linux erinnert. Da wird man auch immer gebeten irgend ein unsinniges Manual zu lesen welches für den Leien überhaupt nicht ersichtlich und nachvollziehbar ist.
Immer muss man mind. 10 Leute fragen bis eine sinnvolle Antwort herauskommt.
-
@darkfate: Falls es dich interessiert, Hier ist noch eine Version deines Programms mit Zeigern auf Zeiger:
#include <iostream> #include <cstdlib> #include <cstring> using namespace std; void array1d(int &n); void array2d(double **A1, int &n); int main(int argc, char **argv){ int n; double *A1; array1d(n); array2d(&A1,n); cout << "n : " << n << endl; cout << "A[0] : " << A1[0] << "A[1] : " << A1[1] << endl; return EXIT_SUCCESS; } void array1d(int &n){ n = 2; } void array2d(double **A1, int &n){ double *tmp = new double[n]; *A1 = tmp; tmp[0] = 0.1234; tmp[1] = 0.5678; }Ich hoffe, dass du es jetzt mit den Zeigern auf zeiger besser verstehst, ich kann aber gerne bei Bedarf noch bestimmte Dinge genauer erklären.
Edit: Hab nicht gesehen, dass du schon wieder was neues gepostet hast, allerdings müsste mein Beispiel auch auf dein neues Programm übertragbar sein. Solltest du nicht klar kommen, kann ich das auch mal Einbauen.
MfG, Jochen