Array und Pointer
-
Hallo sitze gerade vor einer Übung und habe ein Problem...
Aufgabe:
*Ermitteln Sie den maximalen Abstand zweier Punkte des Feldes, das Sie mit
neuesPunktFeld() erzeugt haben. Prototyp der Prozedur:
double maxAbstand(Punkt **, Punkt *, Punkt );
Der erste Parameter ist für die Übergabe des Feldes, mit dem zweiten und dritten
Parameter sollen die ermittelten Punkte zurückgegeben werden.Folgendes habe ich ausgearbeitet:
... cout << "\n*dynamische Punkt Feld Erzeugung*\n"; Punkt **arrPunkt = neuesPunktFeld(ARRAY_GROESSE); for(int i=0; i<ARRAY_GROESSE; i++) { printPunkt( *(arrPunkt[i]) ); } cout << "\n*Ermittelter maximaler Abstand zwischen 2 Punkten aus dem Feld*\n"; Punkt *tmp1, *tmp2; cout << tmp1 << "\t" << tmp2 << endl; cout << "Maximaler Abstand ist bei:" << endl; cout << maxAbstand(arrPunkt, tmp1, tmp2) << endl; cout << tmp1 << "\t" << tmp2 << endl; printPunkt(*tmp1); printPunkt(*tmp2); return 0; }double maxAbstand(Punkt **arrPunkt, Punkt *p1, Punkt *p2) { double nMax = 0; double nTempCalc; //arrPunkt ist übergebenes Feld //über p1 und p2 werden die Punkte zurückgegeben welche den größten abstand haben //double abstand(Punkt p1, Punkt p2) for(int x=0; x<ARRAY_GROESSE; x++) { nTempCalc = abstand( *(arrPunkt[x]), *(arrPunkt[ARRAY_GROESSE-1-x]) ); if( nMax < nTempCalc) { p1 = arrPunkt[x]; p2 = arrPunkt[ARRAY_GROESSE-x-1]; nMax = nTempCalc; } } return nMax; }Problem:
Der Inhalt der Punkt Pointer "tmp1" und "tmp2" ist nur Müll auch die Referenzierte Adresse ändert sich nicht von den beiden Variablen.Frage
Muss ich für die Punkt Pointer Variablen tmp1 und tmp2 ein Extra speicher mit new anlegen? Eigentlich will ich die ja nur auf einen bereits vorhandenen Speicher referenzieren
-
Mein aufrichtiges Beileid, dass du dich mit solch bescheuerten Übrungen von Leuten, die offensichtlich wenig C++ Erfahrung haben, beschäftigen musst.
Wie dem auch sei, tmp1 und tmp2 sind bei dir zwei uninitialisierte Zeiger, mit denen du einfach arbeitest, als würden die schon irgendwohin zeigen, wo es POINT-Objekte gibt.
Wie der code unter den Voraussetzungen auszusehen hat, kann ich Dir nicht sagen, weil ich die Aufgabenstellung nicht wirklich verstanden habe. Ich finde sie unpräzise. Vielleicht fehlt mir da auch etwas Kontext.
-
Evtl. zur Ergänzung
typedef struct { double x; double y; } Punkt; double abstand(Punkt p1, Punkt p2) { return sqrt( (p2.y-p1.y)*(p2.y-p1.y) + (p2.x-p1.x)*(p2.x-p1.x) ); }Tja, finde sie auch nicht ganz Toll aber das Semester hat erst begonnen und das ist nun die erste Aufgabe...
-
Kannst du mal die Funktion neuesPunktFeld zeigen?
BTW in C++ schreibt man
struct Punkt { double x; double y; };Die Version mit typedef ist in C notwendig, wenn man den so definierten Datentyp
Punktnennen will statt immer ausführlichstruct Punktschreiben zu müssen, in C++ heißt der Typ von vornherein nurPunkt.
-
Aufruf der Funktion mit Hilfe des Adressoperators:
Punkt tmp1, tmp2; cout << tmp1 << "\t" << tmp2 << endl; cout << "Maximaler Abstand ist bei:" << endl; cout << maxAbstand(arrPunkt, &tmp1, &tmp2) << endl;Besser wären jedoch Referenzen als Parameter (aber die Aufgabenstellung ist ja leider anders).
-
Bashar schrieb:
Die Version mit typedef ist in C notwendig, wenn man den so definierten Datentyp
Punktnennen will statt immer ausführlichstruct Punktschreiben zu müssen, in C++ heißt der Typ von vornherein nurPunkt.Apropos C und C++: Da das einzige an dem Code, was kein typisches* C ist, das cout ist, würde ich doch gerne vom Threadersteller erfahren, ob die couts vielleicht von ihm auf eigene Faust eingebaut wurden. Wenn das nämlich ein C-Kurs ist und die couts vom TE stammen, dann würde das so einiges erklären. Und man könnte auch produktiver helfen, als nur zu sagen, dass das ganz besch...eidenes C++ ist.
*: Damit meine ich nicht "gut". Bloß typisch für C-Anfängerkurse.
-
Bashar schrieb:
Kannst du mal die Funktion neuesPunktFeld zeigen?
BTW in C++ schreibt man
struct Punkt { double x; double y; };Die Version mit typedef ist in C notwendig, wenn man den so definierten Datentyp
Punktnennen will statt immer ausführlichstruct Punktschreiben zu müssen, in C++ heißt der Typ von vornherein nurPunkt.@Bashar
Danke für den Tip mit der "typedef" wusste ich nicht
Punkt **neuesPunktFeld(int nDim) { Punkt **arrPunkt = new Punkt*[nDim]; for(int i=0; i<nDim; i++) { arrPunkt[i] = neuerPunkt(); } return arrPunkt; }@Th6
Leider, gibt es da wohl kein Spielraum für den Funktionsaufbau...aber trotzdem Danke
-
SeppJ schrieb:
Bashar schrieb:
Die Version mit typedef ist in C notwendig, wenn man den so definierten Datentyp
Punktnennen will statt immer ausführlichstruct Punktschreiben zu müssen, in C++ heißt der Typ von vornherein nurPunkt.Apropos C und C++: Da das einzige an dem Code, was kein typisches* C ist, das cout ist, würde ich doch gerne vom Threadersteller erfahren, ob die couts vielleicht von ihm auf eigene Faust eingebaut wurden. Wenn das nämlich ein C-Kurs ist und die couts vom TE stammen, dann würde das so einiges erklären. Und man könnte auch produktiver helfen, als nur zu sagen, dass das ganz besch...eidenes C++ ist.
*: Damit meine ich nicht "gut". Bloß typisch für C-Anfängerkurse.
Ne das ist ein C++ kurs, C hatten wir bereits und du hast recht ausser cout und <iostream> ist hier C++ sehr gering
-
Mit einer einfachen Schleife wirst du kaum alle Punkte miteinander vergleichen können.
Denn du musst ja den
1. mit dem 2. Punkt vergleichen
1. mit dem 3.
1. mit dem 4.
....
1. mit dem ARRAY_GROESSE.
2. mit dem 3.
2. mit dem 4.
...
2. mit dem ARRAY_GROESSE.
...
ARRAY_GROESSE-1 mit dem ARRAY_GROESSE. Punkt vergleichen
-
DirkB schrieb:
Mit einer einfachen Schleife wirst du kaum alle Punkte miteinander vergleichen können.
Denn du musst ja den
1. mit dem 2. Punkt vergleichen
1. mit dem 3.
1. mit dem 4.
....
1. mit dem ARRAY_GROESSE.
2. mit dem 3.
2. mit dem 4.
...
2. mit dem ARRAY_GROESSE.
...
ARRAY_GROESSE-1 mit dem ARRAY_GROESSE. Punkt vergleichenJa ist mir bewusst, habe die Funktion aber aufgrund des Problems nicht mehr weiter ausgebaut...Werde noch ein innere Schleife einbauen die von oben nach unten -1 zählt.
-
Ich habe das nun so gelöst, obwohl ich mit dieser Lösung nicht zufrieden bin, da ich einen neuen Speicher reserviere...
... Punkt *tmp1 = new Punkt; Punkt *tmp2 = new Punkt; cout << "Maximaler Abstand ist bei:" << endl; cout << maxAbstand(arrPunkt, tmp1, tmp2) << endl; printPunkt(*tmp1); printPunkt(*tmp2); return 0; }double maxAbstand(Punkt **arrPunkt, Punkt *p1, Punkt *p2) { double nMax = 0; double nTempCalc; for(int x=0; x<ARRAY_GROESSE; x++) { for(int y=ARRAY_GROESSE-1; y>0; y--) { nTempCalc = abstand( *(arrPunkt[x]), *(arrPunkt[y]) ); if( nMax < nTempCalc) { *p1 = *arrPunkt[x]; *p2 = *arrPunkt[ARRAY_GROESSE-x-1]; nMax = nTempCalc; } } } return nMax; }
-
Th69 hatte dir doch schon eine bessere Lösung vorgeschlagen.
-
Wozu new?
Punkt tmp1, tmp2; cout << "Maximaler Abstand ist bei:" << endl; cout << maxAbstand(arrPunkt, &tmp1, &tmp2) << endl;Ist zwar immer noch grauenhaft, aber wenigstens ohne direktes Speicherloch.
-
Ich habe das nun so gelöst, obwohl ich mit dieser Lösung nicht zufrieden bin, da ich einen neuen Speicher reserviere...
Wieso also reservierst du selbst Speicher? Die richtige Lösung wäre, eine automatische Stack-Variabe zu nehmen:
Punkt tmp1; Punkt tmp2;Edit: Sei verdammt, SeppJ!
-
Sone schrieb:
Ich habe das nun so gelöst, obwohl ich mit dieser Lösung nicht zufrieden bin, da ich einen neuen Speicher reserviere...
Wieso also reservierst du selbst Speicher? Die richtige Lösung wäre, eine automatische Stack-Variabe zu nehmen:
Punkt tmp1; Punkt tmp2;Edit: Sei verdammt, SeppJ!
Stimmt auch wieder, bin irgendwie bei den ganzne Pointer und Adresse Variablen hängengeblieben...Danke

-
@DKlay13:
Nur mal so eine Frage bezüglich des Programmierstils:Ist zufälligerweise der Begriff Jürgen Wolf in deinem Bekanntenkreis gefallen?
Übrigens: Sagt dir der Begriff Speicherloch was?
PS:
Ich bin überhaupt kein Freund von Zeigern auf Zeigern...
-
@Bitte ein Bit
ka wer das sein soll...sollte man Jürgen Wolf kennen? und was ist an meinem Programmierstill nicht in Ordnung?Memoryleaks sagt mir was, aber da das eine "Übung" habe ich mir keine gedanken gemacht über delete von Variablen...
-
DKlay13 schrieb:
@Bitte ein Bit
ka wer das sein soll...sollte man Jürgen Wolf kennen? und was ist an meinem Programmierstill nicht in Ordnung?Nein, Jürgen Wolf sollte man nicht kennen. Der ist Autor von den schlechtesten C/C++* Lehrbüchern überhaupt.
Und was deinen Programmierstil angeht:
In C++ nutzt man beispielsweise Referenzen für pass-by-reference, nicht Pointer.
Und Arrays übergibt man nach dem Iteratorenprinzip, ein Zeiger auf das erste Element und eins hinter das letzte Element, dann kann man folgende Schleifen schreiben:for (; begin != end; ++begin) // tu was mit *beginDann muss man auch nicht viel ändern, um den Code für STL-Container (die man eh bevorzugen sollte) anzupassen.
*Man, meine versteckten Witze werden immer besser.

-
Und Arrays übergibt man nach dem Iteratorenprinzip, ein Zeiger auf das erste Element und eins hinter das letzte Element
Um den Vorteil hier noch ein wenig deutlicher zu machen: Man muss nicht das komplette Array angeben, auch Untermengen sind möglich.
Die Funktion (oder besser das Funktionstemplate) ist so nicht an den Containertyp oder den Iterator gebunden, und kann praktisch über alle Mengen iterieren. Extrem Flexibel.
das erste Element und eins hinter das letzte Element
Beiläufig werfe ich für den TE noch den Begriff rechtsoffenes Intervall ein.
-
Hmm ok das kannte ich zwar aber selten bis nie verwendet, aber wieso wird mein Programmierstill runtergemacht? Die Funktionprototypen sind ja nicht von mir gemacht sondern vorgegeben und evtl. ist das ja auch der Sinn der ganzen Übung

Trotzdem Danke an alle