Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Parameterübergabe bei Zeigern (inkl. EVL)

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
15.06.2006, 11:13 Uhr
TypusM



Hallo, folgendes Problem. Ich arbeite mit einfach verketteten Listen. Ich möchte hier im Beispiel eine Person eingeben, die anschließend wieder ausgeben. Ich wird ein NULL-Zeiger ("anker") am Anfang in der Main angelegt. Die schiebt sich weiter nach vorne, wenn eine neue Person angelegt wird. Das Programm compiliert einwandfrei, aber leider wird nach der Eingabe ausgegeben, dass keine Person eingegeben wurde. Ich glaube es liegt an der Parameterübergabe. Ich hoffe ich könnt mir helfen.

Hier mein Code:


C++:
#include <iostream.h>
#include <conio.h>

struct person
{
  int mnr;
  char name[20];
  struct person *next;
};

//allg. Fkt. zum Einlesen
void eingeben(struct person *temp)
{
char text[20];
cout<<"MatrikelNR:"; cin>>temp->mnr;
cout<<"NAME:"; cin>>text; strcpy(temp->name,text);
}

void eingabe_vorne(struct person *anker)
{
clrscr();
char text[20];
struct person *temp = new person;
eingeben(temp);
//dem Neuen wird als Nächsten der Anfang zugewiesen
temp->next = anker;
//der Anfang ist nun der Neue
anker = temp;
}

//allg. Fkt. zum Auslesen
void ausgeben(struct person *temp)
{
cout<<"MatrikelNR: "<<temp->mnr<<endl;
cout<<"NAMED: "<<temp->name<<endl;
}

void ausgabe_all(struct person *anker)
{
clrscr();
if (anker!=NULL)
  {
  struct person *temp;
  temp = anker;
  while(temp!=NULL)
    {
    ausgeben(temp);
    temp = temp->next;
    }
  }
  else cout << "Keine Daten gespeichert." << endl;
cout << "Alle Operationen ausgefuehrt. Bitte Taste druecken.";
getch();
}

main()
{
struct person *anker;
anker = NULL;
eingabe_vorne(anker);
ausgabe_all(anker);
}



Lege ich den Anker global an und entferne die Parameter in den bedeutenden Funktionen, funtkioniert es. Ist aber nicht Sinn der Sache, es wird gefordert, dass der Anker in der Main angelegt und fleißig mit Parameterübergabe gearbeitet wird.


C++:
#include <iostream.h>
#include <conio.h>

struct person
{
  int mnr;
  char name[20];
  struct person *next;
};

struct person *anker;

//allg. Fkt. zum Einlesen
struct person eingeben(struct person *temp)
{
char text[20];
cout<<"MatrikelNR:"; cin>>temp->mnr;
cout<<"NAME:"; cin>>text; strcpy(temp->name,text);
return *temp;
}

void eingabe_vorne()
{
clrscr();
char text[20];
struct person *temp = new person;
eingeben(temp);
//dem Neuen wird als Nächsten der Anfang zugewiesen
temp->next = anker;
//der Anfang ist nun der Neue
anker = temp;
}

//allg. Fkt. zum Auslesen
void ausgeben(struct person *temp)
{
cout<<"MatrikelNR: "<<temp->mnr<<endl;
cout<<"NAMED: "<<temp->name<<endl;
}

void ausgabe_all()
{
clrscr();
if (anker!=NULL)
  {
  struct person *temp;
  temp = anker;
  while(temp!=NULL)
    {
    ausgeben(temp);
    temp = temp->next;
    }
  }
  else cout << "Keine Daten gespeichert." << endl;
cout << "Alle Operationen ausgefuehrt. Bitte Taste druecken.";
getch();
}

main()
{
anker = NULL;
eingabe_vorne();
ausgabe_all();
}


Dieser Post wurde am 15.06.2006 um 11:30 Uhr von TypusM editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
15.06.2006, 11:57 Uhr
Spacelord
Hoffnungsloser Fall


Hallo,
dein Problem ist folgendes.
Du übergibst an eingabe_vorne eine Kopie des Zeigers auf deinen Anker.Innerhalb von eingabe_vorne kannst du problemlos den Inhalt hinter dem Zeiger ändern weil ja die Speicheradresse auf die der Zeiger zeigt die gleiche ist aber wenn du den Zeiger selbst ändern möchtest dann änderst du nur die Kopie!
Angenommen dein Zeiger anker liegt an der Speicherposition 1000.
Dann steht bei der Speicheradresse der Inhalt NULL (0)
Jetzt übergibst du an eingabe_vorne ne Kopie von anker...sagen wird mal diese Kopie liegt ander Adresse 2000 und enthält als Inhalt die Kopie von dem was an 1000 steht also NULL.
Dann weisst du der "Speicherzelle" an der Adresse 2000 innerhalb von eingabe_vorne die Adresse der person zu die du mit new erzeugst(sagen wir mal die liegt bei 3000)
Dann hast du folgendes Speicherbild
anker 1000 -> NULL
Kopie von anker 2000 -> 3000(Person Objekt)

Unglücklicherweise zeigt dann dein Original anker immer noch auf NULL und die Kopie wird beim verlassen von eingabe_vorne wieder vom Stack geschmissen (wodurch dein durch new erzeugtes Objekt komplett verwaist ist-->Speicherloch).

Je nachdem wo ihr im Stoff steht nimmst du also als Parameter einen Zeiger auf den Zeiger,oder,was schöner ist,ne Referenz auf den Zeiger wodurch du den "echten" Anker änderst.

C++:
void eingabe_vorne(struct person *&anker)



Ansonsten ist der Code veraltet,nicht standardkonform und unsicher aber das werden dir wohl gleich noch andere predigen .

Gruss Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.

Dieser Post wurde am 15.06.2006 um 11:58 Uhr von Spacelord editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
15.06.2006, 12:29 Uhr
TypusM



Asso,

Jetz hab ich's verstanden. Wie also auch bei Stino-Funktionen "Call By Value".. Ich ging davon aus, dass er hier automatisch die korrekte Adresse übergibt und nicht zusätzlich nochma mit einer Kopie arbeitet.

Danke

Edit: Unsicher allemal. Hab so meine Probleme mit dem Fach un bald sind auch noch Prüfungen .. aber wieso veraltet und nicht standardkonform?

Dieser Post wurde am 15.06.2006 um 12:31 Uhr von TypusM editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
15.06.2006, 12:35 Uhr
Spacelord
Hoffnungsloser Fall


iostream.h etc. sind die Vorstandard-Header --> veraltet
conio.h(clrscr etc.) ist überhaupt kein Standard --> nicht standardkonform

Gruss Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
15.06.2006, 12:55 Uhr
TypusM



Hm. Asso.

Eine Frage noch für das Verständnis:
Wir übergeben nun also eine Referenz vom Zeiger in die Funktion eingeben_vorne. Dabei wird mit der Originaladresse gearbeitet. Wieso benötigt man dann aber nicht auch für die Funktion eingeben so eine Referenz.. hier genügt nach wie vor: void eingeben(struct person *temp)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
15.06.2006, 13:08 Uhr
Spacelord
Hoffnungsloser Fall


Weil der Inhalt des Zeigers,also die Speicheradresse des Personenobjekts, auch als Kopie auf die korrekte Speicheradresse zeigt und du so auch das "echte" Objekt änderst.
Du musst dir den Unterschied zwischen der Speicheradresse an der der Zeiger selbst liegt und der Speicheradresse die in dieser Speicherzelle gespeichert ist klar machen .

Gruss Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
15.06.2006, 13:47 Uhr
Spacelord
Hoffnungsloser Fall


Nur um es zu verdeutlichen:

C++:
#include <iostream>
using namespace std;

int main()
{
    int* zeiger_auf_int=NULL;
    int a=69;
    cout<<"Adresse von dem Zeiger: "<<&zeiger_auf_int<<endl;
    cout<<"Adresse die im Zeiger gespeichert ist: "<<zeiger_auf_int<<endl<<endl;

    //zeiger_auf_int auf a zeigen lassen
    zeiger_auf_int=&a;
    cout<<"Adresse von a: "<<&a <<endl;
    cout<<"Adresse von dem Zeiger: "<<&zeiger_auf_int<<endl;
    cout<<"Adresse die jetzt im Zeiger gespeichert ist: "<<zeiger_auf_int<<endl;
    cout<<"Wert von dem int auf das zeiger_auf_int zeigt:"<<*zeiger_auf_int<<endl;
    
    return 0;
}



MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: