3Danke
ERLEDIGT
NEIN
NEIN
ANTWORTEN
8
8
ZUGRIFFE
578
578
EMPFEHLEN
-
13.12.11 15:29 #1
- Registriert seit
- Oct 2008
- Beiträge
- 75
Hey,
ich habe hier eine Lern DVD von video2brain üer C++.
So jetzt hat hier der nette Herr im Video ein Tutorialvideo gezeigt, das ich nciht ganz verstanden habe
Nämlich geht es um Pointer.
Und um das noch zu verschönern, geht es um Pointer auf Pointer...
Ich weiß nciht wirklich wozu man das braucht und verstehe das Beispiel Programm auch nicht sehr. Vor allem bei der "eintragen" funktion mit dem Pointer auf einen Pointer.
Wäre sehr nett wenn mir einer das Schritt für Schritt erklären würde. Hier das BspProgramm:
PHP-Code:#include <iostream>
#include <string>
using namespace std;
// Baumstruktur für Sortierung
struct link_str {
string *pbegriff;
link_str *left;
link_str *right;
};
void eintragen(link_str **pstart, string s1)
{ // einsortieren an bestehende liste
link_str *pliste;
pliste = *pstart; // Startwert
// 1. sonderfall
if (pliste == NULL) {
pliste = (link_str *) malloc(sizeof(link_str));
pliste->pbegriff = new string(s1);
pliste->left = NULL;
pliste->right = NULL;
*pstart = pliste;
return;
}
// suchen nach leerem Eintrag
while (pliste != NULL) {
if (s1 <= *(pliste->pbegriff)) { // lexiographic kleiner oder gleich
if (pliste->left != NULL) {
pliste = pliste->left;
} else {
pliste->left = (link_str *) malloc(sizeof(link_str));
pliste = pliste->left;
pliste->pbegriff = new string(s1);
pliste->left = NULL;
pliste->right = NULL;
pliste = NULL; // schleife zueende
}
} else {// lexigraphisch groesser
if (pliste->right != NULL) {
pliste = pliste->right;
} else {
pliste->right = (link_str *) malloc(sizeof(link_str));
pliste = pliste->right;
pliste->pbegriff = new string(s1);
pliste->left = NULL;
pliste->right = NULL;
pliste = NULL; // schleife zueende
}
}
} // while
// ende
}
void ausgabe(link_str *pliste)
{ // rekursiv
if (pliste == NULL) return;
ausgabe(pliste->left);
cout << "Sortiert: " << *( pliste->pbegriff) << endl;
ausgabe(pliste->right);
}
void freigeben(link_str *pliste)
{
if (pliste == NULL) return;
freigeben(pliste->left);
freigeben(pliste->right);
delete pliste->pbegriff;
free(pliste);
}
int main()
{
link_str *pstart = NULL;
link_str *pliste = NULL;
string s1;
// Fuellen der Liste
do {
getline(cin,s1,'\n');
if (s1 != "QUIT") {
eintragen(&pstart,s1);
}
} while (s1 != "QUIT");
// AUSGABE der Liste
ausgabe(pstart);
// FREIGABE der Liste
freigeben(pstart);
pstart = NULL;
return(0);
}
-
Hi
Ein Pointer ist generell einmal eine Speicheradresse.
Die Speicherplätze im Arbeitsspeicher sind alle durchnummeriert (ganze Zahlen, also 1, 2, 3 usw.)
die Adresse einer Variable ist dann die Nummer von ihrem "Platz".
Ein Pointer wie "link_str *pstart" ist daher in Wirklichkeit eine int-Zahl mit einer Adresse.
Ob es jetzt link_str * oder float * oder... ist entscheidet,
welche Variablenart an dieser Adresse zu finden ist.
Der Pointer selbst ist immer ein int (weil die Adress ja immer eine ganze Zahl ist,
egal ob sie die Adresse iner float-Variable oder sonstwas ist).
Mit "pstart=..." kann man dem int eine neue Adresse zuweisen,
mit "*pstart" auf die Variable dieser Adresse dann zugreifen.
So ein float-Pointer hat drei Möglichkeiten, auf was er zeigen kann:
a) auf NULL, bedeutet: Zeigt auf keine Variable.
b) auf eine existierende Variable wie "float abc;", deren Adresse man mit "&abc" bekommt.
c) oder man besorgt sich mit new eine neue Variable. Damit man auf die auch zugreifen kann
(da sie nicht wie abc einen eigenen Namen hat), kommt die Adresse in einen Pointer.
Ein häufiger Grund für Pointer: Wenn man eine Variable an eine Funktion übergibt,
diese dort geändert wird, und die Änderung auch nach der Funktion noch da sein soll.
Beim Übergeben wird nämlich eine Kopie der Variable gemacht, nur die wird geändert.
Wenn die Funktion fertig ist, ist die Kopie wieder weg,
und das Original hat noch immer den alten Wert.
Eine Lösung wäre der Returnwert.
Problem: Geht nur mit einer Variable.
Was ist, wenn zehn Übergebene geändert werden?
Bessere Lösung: Man übergibt einen Pointer auf die Variable, also die Adresse (&...).
Dann wird eine Kopie von der Adresse gamacht. Ein Original-1234 ist als Kopie aber noch immer 1234 und "zeigt" auf die selbe Speicherstelle. Die eine, unkopierte Speicherstelle.
Warum jetzt Doppelpointer?
Mit dem Übergeben von Normalpointern erreicht man also, dass Änderungen der Variable
nicht verloren gehen. In der Funktion besorgt man sich mit new aber erst eine neue Variable.
Auf einer neuen Adresse. Dh.: Nicht nur die Wertvariable selber, sondern auch die Adresse,
also der int-Wert vom Pointer wird geändert.
Deshalb noch eine Ebene weiter: Ein Pointer auf den Pointer,
damit die neue Adresse nicht nur in der Kopie vom Pointer-int gespeichert wird...
GrußNetiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
13.12.11 15:57 #3
- Registriert seit
- Oct 2008
- Beiträge
- 75
Danke schonmal

Die Grundlagen der Pointer wusste ich schon, aber trotzdem danke
Möchte nun gerne noch wissen, wozu man in der Funktion einen Pointer auf einen Pointer erzeugte?
-
13.12.11 16:01 #4
Also in einer Funktion verwende ich das, um im Funktionskopf einen Pointer zurückzugeben.
Oder um ein Pointer Array zu übergeben.
Also quasie so:
Hoffe ich habe nichts falsches gesagtCode cpp:1 2 3 4 5
void blabla(int eingang, int **ausgang) { int *ausgang; ausgang = &eingang; }

MfGFehlermeldung bitte!
Google - Dein Freund und Helfer
-
13.12.11 16:04 #5
- Registriert seit
- Jun 2007
- Ort
- Passau (Niederbayern)
- Beiträge
- 1.394
Hi,
<klugsch...>Ein Pointer ist nicht immer ein int, die Größe ist je nach Architektur unterschiedlich. Es kann also gut sein, dass ein "int" 32 Bit und ein Pointer 64 Bit hat. Quelle: Klick</klugsch...>

Aber ansonsten eine gute und detaillierte Erklärung des Themas.
Gruß,
BKGeändert von Bratkartoffel (13.12.11 um 16:10 Uhr)
Über eine gute Bewertung freut sich jeder ;)
Bitte erledigte Threads als "Erledigt" markieren.
"Though a program be but three lines long, someday it will have to be maintained.''
-- Geoffrey James, "The Tao of Programming"
-
So, oben den Rest noch dazugeschrieben.
Die Grundlagen waren nur zum besseren Verstehen
@Bk: Sicher, ein int kann unterschiedlich groß sein.
...Geändert von sheel (13.12.11 um 16:11 Uhr) Grund: Teil entfernt, weil ich meinen Text selbst nicht mehr versteh :D
Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
13.12.11 22:33 #7
- Registriert seit
- Oct 2008
- Beiträge
- 75
Ich hab das mit dem Doppelpointer jz so verstanden, das sman ihn braucht, WEIL er eine Adresse eines Pointers erhält(siehe main).
Also erställt man so einen neuen Pointer auf dem Pointer in der "main" der auf NULL steht.
Dann wird der Pointer *pliste mit dem Wert des Doppelpointers versehen.
Und da dann *pliste = NULL ist (s. main) tritt der Sonderfall ein, -->
daher wird der Pointer *pliste mit einem beliebigen freien neuen Speicherpunkt versehen, mit der Art von link_str und erhält den Wert des Strings den man angegeben hat.
Außerdem wird dann der Pointer *pstart mit dem Inhalt oder der Adresse des *plist Pointers versehen (?), weiß nicht genau. Jedenfalls ist dann der Pointer *pstart definiert, welcher auf den Pointer in der main zeigt, der auch *pstart heißt, der jz nciht mehr auf NULL steht.
Danach geht es denke ich so weiter, dass jenachdem der Eingegebene String "größer" oder "kleiner" als der des Ersten ist. Falls kleiner dann wird ein neues Objekt nach "links" erstellt, bei dem der Pointer *links des ersten Objekts zeigt, danach wird der Pointer *pliste dem neu erstelltem Objekt zugeteilt und es fängt von vorne an....
PUUH.
Hoffentlich habe ich das richtig verstanden.
Falls jemand die Zeit hätte den Schrott hier zu lesen (
) und auszuwerten, wäre ich sehr dankbar.
-
Ja, ein**- Pointer ist ein int mit einer Dresse.
An dieser Adresse findet man wieder wieder ein int mit einer Adresse (*-Pointer).
An dieser Adresse ist dann eine Variable.
...Das kann man auch drei- oder viermal verschachteln,
wenns lustig ist (macnhmal auch benötigt).
Das mit dem Wert des Oppelp. in den P.: Hm, nein.
Am Anfang gibts den *Pointer, wird auf NULL gesetzt: Also zeigt er vorerst auf keine Variable.
Und dann will man den Pointer auf etwas zeigen lassen.
Aber nicht auf eine vorhandene Variable, sondern man erzeugt sich mit new eine Neue.
Dazu würde man zunächst mal keine **Pointer brauchen, ein einfaches
würde reichen.Code cpp:1
p = new ...;
new macht eine neue Variable (die im Code aber keinen Namen hat).
Man kann während der Programmlaufzeit beliebig viel Variablen mit new erstellen,
zusätzlich zu den fixen im Code.
Und mit dem "p=" weist man dem Pointer-int die Adresse der neuen Variable zu.
Jetzt soll das new-Zeug aber in einer Funktion passieren.
Falsche Variante:
Man übergibt den Pointer, der auf nichts zeigt.
Beim Übergeben wird eine Kopie gemacht, wie immer beim Übergeben.
Jetzt gibts in der Funktion einen anderen Pointer, der auch auf nichts zeigt,
so wie der Pointer aus main. Aber es sind verschiedene.
Dann wird dem Kopiepointer von new die Adresse der neuen Variable gegeben.
Am Ende der Funktion verschwindet der Kopiepointer mit seiner Adresse wieder.
Und das Original im main zeigt noch immer auf NULL/Nichts.
Richtige Variante:
Man übergibt nicht das Pointer-int, sondern die Adresse vom Pointer-int.
Diese Adresse wird kopiert.
Die Kopie "zeigt" aber noch immer auf das selbe Pointerint, das auf nichts zeigt...
Das selbe Pointerint wie das im main.
Und die new-Adresse geht nicht verloren.Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
16.12.11 20:50 #9
- Registriert seit
- May 2006
- Ort
- There is no place like 127.0.0.1
- Beiträge
- 3.516
Eine Pointer-Variante wurde vergessen: Zeiger auf Funktion. *Wollte auch mal klug******en*
Grüße
--
Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)
Ähnliche Themen
-
[c++] Pointer auf konstanten Pointer-Parameter setzen
Von digitalFreeman im Forum C/C++Antworten: 4Letzter Beitrag: 18.02.09, 11:11 -
Invalid Pointer Addition.. wo is denn da n pointer !
Von GartenUmgraben im Forum Borland CBuilder und VCLAntworten: 3Letzter Beitrag: 29.07.06, 16:48 -
[C] Prüfen, ob Inhalt von Pointer auf Pointer existiert
Von mc_gulasch im Forum C/C++Antworten: 4Letzter Beitrag: 07.07.06, 13:34 -
Aus Zwei Pointer Arrays mache ein Pointer Array
Von janosch im Forum C/C++Antworten: 1Letzter Beitrag: 22.12.05, 09:27 -
[C++] Objekt Pointer zuweisen und Methoden auf Pointer realisieren?
Von Ezzz im Forum C/C++Antworten: 6Letzter Beitrag: 02.11.03, 21:23





Zitieren



Login






