Problem mit einfach verkette listen

hi erstmal,

„Vorwort“ :

  • eine Schulaufgabe
  • keine ausgabe der daten

Nun wir haben in der Schule versucht eine einfach verkettete liste zu erstellen, und dieser wollten wir min 2 Kunden aufnehmen.
Dazu haben wir uns auch noch einen neuen datentyp ( struct …) names tKunde ( char „Kundenname“ , int „Kundennummer“) erstellt.
Zur „anhaengung“ neuer Kunden haben wir eine neue funktion erstellt, namens anhaengen( char *sName, int nNr) .

Nun giebt es das problem das schon genannte problem das wir keine ausgabe der kunden haben.

Würde mich freuen wenn mir bei dieser aufgabe geholfenb werden könnte^^ .

#include
#include
#include
#include

// Vorwärtsdeklaration eigener Kt. ( Prototypen)
void anhaengen(char *,int);

/*typedef*/ struct tKunde
{
char sName[20];
int nNr;
struct tKunde *ptr; //soll auf die Adresse des nächsten zeigen
};

//Globale Deklaration

struct tKunde *pAnker = NULL; //Anker der Liste deklarieren und auf NULL

/*** Hauptprogramm ***/
int main(int argc, char* argv[])
{
struct tKunde *next = pAnker;

anhaengen(„Maier“,2);
anhaengen(„Fano“,007);

if(next != NULL)
{
do
{
printf(„Name: %s \tKundennummer: %d“, next->sName ,next->nNr );
next=next->ptr;

}while(next != NULL);
}

getchar();
return 0;
}

void anhaengen(char *sName, int nNr)
{
// Deklaration Lokaler Variablen
struct tKunde *hPtr; //Hilfszeiger
struct tKunde *tail; //speichert Adresse des letzten Kunden

if(pAnker!=NULL)
{
tail = pAnker;

while(tail->ptr != NULL)
tail = tail->ptr;
}

//Speicherreservieruzng fürt den nächsten kunden
hPtr = malloc(sizeof(struct tKunde));

strcpy(hPtr->sName, sName); //Übergabe des kundennames an die Struktur-Komponente
hPtr->nNr = nNr;
hPtr->ptr = NULL; //Letzter Listen-Eintrag

//Verkettung der Listen-Einträge
if(pAnker == NULL) pAnker=hPtr;
else tail->ptr = hPtr;

}

hoffe es ist nicht zu unübersichtlich^^.

(die datei^^ : http://or4ng3.or.funpic.de/Listen2.c )
Mfg OrAnge

Hallo Bartman,

hehe!, es gibt ja tatsächlich wieder mal eine C-Frage
im Forum :wink:

Nun wir haben in der Schule versucht eine einfach verkettete
liste zu erstellen, und dieser wollten wir min 2 Kunden
aufnehmen.

Nun giebt es das problem das schon genannte problem das wir
keine ausgabe der kunden haben.

Das ist relativ einfach zu finden:

1 struct tKunde \ *next = pAnker;
2
3 anhaengen(„Maier“,2);
4 anhaengen(„Fano“,007);
5
6 if( next!= NULL)

In 1 wird next auf NULL gesetzt, über pAnker
soll next „indirekt“ in 3 und 4 mit ‚irgendwas‘
initialisiert werden – was aber nicht gehen
kann.

Denn: in ‚pAnker‘ steht nur eine Zahl (nämlich 0),
es gibt keine „Rückkopplung“ von ‚pAnker‘ zu ‚next‘.

Dazu muss man aus ‚next‘ eine Variable machen,
die eine Referenz (Zeiger) auf die Variable
‚pAnker‘ selbst darstellt:

struct tKunde \*\*next = &pAnker;

Es ist aber hier quark, diese variable ‚next‘ zu nennen,
nennen wir sie besser ‚ppa‘ (Pointer to pointer to anker).

Ausserdem ist es (imho) unschön, den Listenzeiger im
Listenelement ‚ptr‘ zu nennen.

 struct tKunde {
 char sName[20];
 int nNr;
**struct tKunde \*ptr** ; // soll auf die Adresse des nächsten zeigen
 };

Diesen nennt man seit Adam und Eva ‚next‘
oder pnext oder so ähnlich :wink:

Wenn man den ‚**ppa‘ richtig in die Ausgabeschleife
einbaut, dann klappt es auch schon. Ich hänge den
korrigierten Quellext mal an. Zur Programmstruktur
äussere ich mich nicht, ihr sollt das ja lernen :wink:

#include 
#include 
#include 
#include 

 struct tKunde
{
 char sName[20];
 int nNr;
 struct tKunde \*next; // soll auf die Adresse des nächsten zeigen
};

 static struct tKunde \*pAnker; // Anker der Liste deklarieren und auf NULL
 void anhaengen(char \*,int);

 int main(int argc, char\* argv[])
{
 struct tKunde \*\*ppa = &pAnker; // pointer auf anker pointer

 anhaengen("Maier", 2);
 anhaengen("Fano", 7);

 if(\*ppa != NULL) do {
 printf("Name: %s\tKundennummer:\t%d\n", (\*ppa)-\>sName ,(\*ppa)-\>nNr);
 \*ppa = (\*ppa)-\>next;
 } while(\*ppa != NULL);

 getchar();
 return 0;
}

 void anhaengen(char \*sName, int nNr)
{
 struct tKunde \*hPtr; // Hilfszeiger
 struct tKunde \*tail; // speichert Adresse des letzten Kunden

 if(pAnker != NULL) {
 tail = pAnker;
 while(tail-\>next != NULL)
 tail = tail-\>next;
 }

 // Speicherreservieruzng fürt den nächsten kunden
 hPtr = malloc(sizeof(struct tKunde));

 // Übergabe des kundennames an die Struktur-Komponente
 // !! Überschreib-Problem (Name laenger als 20)
 strcpy(hPtr-\>sName, sName); 
 // !!

 hPtr-\>nNr = nNr;
 hPtr-\>next = NULL; //Letzter Listen-Eintrag

 // Verkettung der Listen-Einträge
 if(pAnker == NULL) 
 pAnker = hPtr;
 else 
 tail-\>next = hPtr;
}

Grüße

CMБ

Ja danke schön,

aber warum hast denn vor ppa 2 * gesetzt? --> ’ struct tKunde **ppa = &pAnker; ’ , ( was hat dass denn für ne auswirkung?)

h3h3,
mal nen kleiner hinnweis^^,
heist die include datei nicht alloc.h und nicht malloc.h :wink:

(hoffe das ich das jetzt kapiert habe^^,)

OrAnge

Hallo OrAnge,

h3h3,
mal nen kleiner hinnweis^^,
heist die include datei nicht alloc.h und nicht malloc.h :wink:

alloc.h ist IIRC ‚nonstandard Header‘ von Borland
und einigen anderen.

malloc.h ist ein ‚inzwischen veralteter Header‘
von Ansi-C, wird aber derzeit iirc noch durchgängig
unterstützt.

aber warum hast denn vor ppa 2 * gesetzt? --> ’ struct
tKunde **ppa = &pAnker; ’ , ( was hat dass denn für ne
auswirkung?)

Beispiel:

 int var; wenn:

     pvar = &var;
     ppvar = &pvar;
     pppvar = &ppvar;

gilt, dann kommt man über folgende Operation wieder an var heran:

     int v1 = var; Ein Zeiger "enthält" die Adresse des Objektes, auf das er "zeigt".
    Um wieder an das Objekt zu kommen, 'dereferentiert' man mit
    vorangestelltem '\*'.
    
    Alles klar? Das muss man verstanden haben, um den
    zweiten Schritt zu machen: Das ganze als Rückgabewert
    von Funktionen bzw. Felder von Zeiger-Zeigern etc. :wink:
    
    Grüße
    
    CMБ

h3h3,
hi ( sry kann dein namen net schreiben^^)

zu 1. noa k, wuste ich halt net^^,

  1. der ausdruck Zeiger zeigt auf Zeiger, der auf Zeiger zeigt ist einfach nur geil^^ , wenn man sich das halt mal auf der zunge zergehen läst^^,
    einfach nur geil^, h3h3.

K
also solche komplizierten / abstrakten sachen hat unser lehrer noch net in angriff genommen ( das war ja halt schon hart als er die liste verketten wollte, und denn zeiger ptr oder next, ( ich weis net mehr genau gg ) auf die adresse des nächsten ketten gliedes zeigen lassen wollte. )

naja wenn ich denn mal wieder was habe^^, aber ich hoffe das ich das jetzt soweit einigermaßen durchdrunegen habe^^,

thx nochmal,

OrAnge

sry for doppelpost…

hatte noch vergessen zu fragen ( wie kann es auch anders sein^^)
ob du vill gute lektyre ( hoffe mla das das so geschreiben wird^^ )zum weiterbilden empfehlen könntest ?

Hallo OrAnge

  1. der ausdruck Zeiger zeigt auf Zeiger, der auf Zeiger
    zeigt ist einfach nur geil^^ , wenn man sich das halt mal
    auf der zunge zergehen läst^^, einfach nur geil^, h3h3.

Warte mal, wenn Du auf sowas stößt …

 struct tKunde (\*(\*pFunktion(int,int))())[];

(Zeiger auf eine Funktion, die einen Zeiger
auf ein Array von Strukturen als Rückgabewert liefert :wink:

also solche komplizierten / abstrakten sachen hat unser lehrer
noch net in angriff genommen ( das war ja halt schon hart als
er die liste verketten wollte, und denn zeiger ptr oder next,
( ich weis net mehr genau gg ) auf die adresse des nächsten
ketten gliedes zeigen lassen wollte. )

Simple Listen - wie in Eurem Falle, kann man immer
ohne solche „Zeiger auf Zeiger“ realisieren. Wenn man sie
hier doch braucht, stimmt etwas mit dem Programmkonzept nicht!

Grüße

CMБ