C++ Ich bekomm schon die Beispielaufgabe nicht kompiliert...

Mollfred

Cadet 3rd Year
Registriert
Mai 2013
Beiträge
43
Hallo!

Ich habe folgendes Problem ein Freund hat mir ein paar c++ Aufgaben gegeben, die ich jetzt eigentlich lösen wollte. Bei der einen Aufgabe ist ein Code, der noch erweitert werden soll.
Aber das Problem ist der BeispielCode war schon so fehlerhaft, das ich gar nicht dazu komme die eigentliche Aufgabe anzugehen. Ich habe jetzt soweit alle Fehler beseitigt bekomme aber beim Kompilieren die Fehlermeldund "'temp' : undeclared identifier", wobei mir klar ist das ich temp deklarieren muss. Aber ich steh auf dem Schlauch wie ich es Deklarieren soll. Wäre toll wenn mir jemand helfen könnte damit ich dann die Aufgabe erweitern kann damit der Benutzer belieb viele Integer Zahlen eingeben kann und noch eine Suchfunktion implementieren kann. Hier erstmal der Code für die Beispielaufgabe:
Code:
#include <iostream>
#include <string>
#include "Dlink.h"

using namespace std;

DLink::DLink(int iAContent):

	iContent (iAContent), 
	pre (NULL),
	suc (NULL)
	{};

DLink::~DLink()
{
	if( suc != NULL )
	delete suc;
};




void DLink::insert(DLink* newDLink)
{
	if (this-suc != NULL)
	{
		this->suc->pre = newDLink;
	}

	newDLink->suc = this->suc;
	newDLink->pre = this;
	this->suc = newDLink;
};

void DLink::outputDLink() 
{	
	DLink* temp = this;
	while( temp != NULL ) 
	{
		cout << temp->iContent << endl;
		temp = temp->suc;
	}
};

void DLink::outputDLinkReverse() 
{	
	for( DLink* temp = this; temp->suc != NULL; temp = temp -> suc);
	while( temp != NULL ) 
	{
		cout<< temp->iContent <<endl;
		temp = temp->pre;
	};
};

Was ich auch nicht verstehe ist das der fehler erst in Zeile 48 auftritt....und nicht schon vorher
 
Zuletzt bearbeitet:
Strichpunkt am Ende der for weg...aber auch ansonsten is der Code ziemlich "kreativ"...

edit: bzw. zu schnell geschossen: einfach Zeilen 47 und 48 genau anschauen und überlegen was du eigentlich haben willst. temp in Zeile 48 is jedenfalls in dem Block nirgends vorher deklariert.
 
Code:
void DLink::outputDLinkReverse() 
{	
	for( DLink* temp = this; temp->suc != NULL; temp = temp -> suc);
	while( temp != NULL ) 
	{
		cout<< temp->iContent <<endl;
		temp = temp->pre;
	};
};

Entweder oder, aber nicht so.

Du bekommst die Fehlermeldung weil du die Variable temp nur lokal für die for-Schleife(ohne Rumpf :rolleyes:) deklariert hast, sie aber danach in der while-Schleife nutzen willst.
Da du ja auch schon in outputDLink die while Variante nutzt, lösche die for-Schleife und deklariere temp wie in outputDLink.

Alternativ eben die while-Schleife weg, die for-Schleife anpassen, dass sie rückwärts läuft und den Rumpf füllen.

Edit: Es ist übrigens hilfreich die Zeile anzugeben die mit dem Fehler angegeben wurde, so lässt sich schneller und besser helfen. So musste man erstmal ganz drüber sehen wo temp steht usw.
Merks dir für die Zukunft ;)
 
Zuletzt bearbeitet:
Hi,
die for schleife in line 47 ist irgendwie sinnlos oder?
1. Sie hat keinen Rumpf. (Keinen Inhalt da direkt ein Semikolon danach kommt.
2. Dei Deklaration von temp erfolgt hier inm Schleifenkopf der For-Schleife und ist somit nur in der schleife verfügbar.

Eigentlich sollte wie bei outputDLink() bei outputDLinkReverse() ein DLink* temp = this; anstelle der FOr-Schleife ausreichen.
Edit: Oder die While mit folgender For-Schleife ersetzen:

Code:
for( DLink* temp = this; temp->suc != NULL; temp = temp -> suc)
              {
		cout<< temp->iContent <<endl;
	}

Edit: zu Spät ^^
 
Zuletzt bearbeitet:
ok vielen dank, das der Code so "Kreativ" ist hab ich auch bemerkt den hab ich aus paar Uni Folien die ein Freund mal in der Uni bekommen hat und da waren echt super viele Fehler drin am Anfang ging gar nichts, ich wunder mich was die damals in der Uni bekommen haben....
Vielen Dank für eure hilfe jetzt kann ich mich an die eigentliche Aufgaben machen.
 
Und danach das hier mal ansehen, was nämlich zu 99% sinnfrei ist:

Code:
DLink* temp = this;
while( temp != NULL )
{
...
 
...Das war bestimmt die Absicht des Dozenten. Fehlersuche und Debugging kann gut 50% der Zeit der Softwareentwicklung in Anspruch nehmen. :)

@Cordless:
Meinst Du ne Do-While wäre besser gewesen?
Naja vielleicht etwas logischer aber ich finde der Vorteil von Kopfgesteuerten Schleifen ist, dass man beim Lesen des Codes eher erkennt was das Abbruchkriterium ist.
 
Zuletzt bearbeitet:
@Cordless: Nein, es ist zu 100% nicht sinnfrei. Er iteriert doch über die gesamte Liste und überschreibt temp immer mit dem Nachfolger. Sollte der Nachfolger Null sein bricht die Schleife erfolgreich und richtig ab. Der aufrufende DLink(this) ist nie Null und so darf auch dessen Inhalt ausgegeben werden.
Du bist wirklich voreilig.
 
Hier, so müßte es aussehen:

Code:
#include <iostream>
#include <string>
using namespace std;

#include "Dlink.h"
 
/*
class DLink {
   int iContent;
   DLink *pre, *suc;
public:
   DLink(int iAContent);
  ~DLink();
   void insert(DLink* newDLink);
   void outputDLink(void);
   void outputDLinkReverse(void);
};
*/

DLink::DLink(int iAContent): iContent (iAContent),pre (NULL), suc (NULL) {

}
 
DLink::~DLink() {
 if( suc != NULL )
    delete suc;
}
 
void DLink::insert(DLink* newDLink) {
 if( this->suc != NULL ) {
    this->suc->pre = newDLink;
 }
 newDLink->suc = this->suc;
 newDLink->pre = this;
 this->suc = newDLink;
}

void DLink::outputDLink(void) {	
 DLink* temp = this;
 while( temp != NULL ) {
    cout << temp->iContent << endl;
    temp = temp->suc;
 }
}
 
void DLink::outputDLinkReverse() {	
 DLink* temp= this;
 for( ; temp->suc!=NULL; temp=temp->suc )
     ;
 while( temp != NULL ) {
    cout << temp->iContent <<endl;
    temp = temp->pre;
 }
}
 
ja stimmt das mit der Absicht kann ich mir Vorstellen, wobei ich ja auch nicht weiß was damals in den Vorlesungen zu den Folien gesagt wurde. Evtl wurde ja auch sowas auch hingewiesen ich hab hier halt echt nur die alten Folien. So ich versuch jetzt mal meinen Morgen zu retten in dem ich die Aufgabe löse.

Zumindest geht der Beispiel Code jetzt....:) danke noch mal für eure Hilfe
Ergänzung ()

ok ich bin jetzt soweit das ich beliebig viele Zahlen in myList eintragen kann und diese werden dann vorwärts und rückwärts ausgegeben....
alles soweit gut....was ich nur nicht kapiere ist ich muss in DLink *myList = new DLink( 0 ) eine Zahl in den Klammern eingeben aber ich bekomme das nicht Sinnvoll und Sauber aus der Schleife gelöst der erste Wert soll ja nicht immer der selbe sein....
Vielleicht kann mich jemand von euch in die richtige Richtung schubsen....hier der Code meiner Main

Code:
        #include <iostream>
        #include "DLink.h"
         
        using namespace std;
         
        int main()
        {
        int zahl;
        DLink *myList = new DLink( 0 );
        do
        {
        cout <<"Bitte Zahl eingeben (0 fuer Beenden): ";
        cin >> zahl;
        myList->insert( new DLink( zahl ));
        }
        while(zahl != 0);
         
        cout << "Ausgabe vorwaerts:" << endl;
        myList->outputDLink();
         
        cout << "Ausgabe rueckaerts:" << endl;
        myList->outputDLinkReverse();
         
        delete myList;
        cout << "Liste geloescht" << endl;
         
        return 0;
        }
ohne einen Wert vor der Schleife anzugeben erhalte ich folgenden Fehler :"'DLink' : no appropriate default constructor available"

Aber ich muss ja DLink deklarieren bevor ich es in der do while Schleife betanken kann....hmmm
Ergänzung ()

ich kapier es nicht...
 
Zuletzt bearbeitet:
Code:
 DLink *myList = NULL;
do
{
cout <<"Bitte Zahl eingeben (0 fuer Beenden): ";
cin >> zahl;
if(myList)
myList->insert( new DLink( zahl ));
else
myList=new DLink( zahl );
}
while(zahl != 0);

Ist aber m.E. ein ziemliches Gefriggel. Eine einfachere und hübschere Alternative wäre es, das ganze nocheinmal abzukapseln:

Code:
class List
{
   DLink* FirstElment;
public:
   List()
   {
   FirstElement = NULL;
   }
  
void Insert(int Zahl)
{
if (FirstElement ) 
....
else
....
}
}
 
ah ok vielen Dank für deine Hilfe! Ich werd mich erstmal an die erste Variante halten da ich mir bisschen mehr Zeit nehmen muss um deine zweite Variante überhaupt zu verstehen...
Ergänzung ()

als ich angefangen hab mit der Aufgabe dachte ich das es sehr viel einfacher wäre, da ich da noch dachte ich könnte das mit dem Sortieren der Liste und danach das Suchen und ersetzen eines Wertes ähnlich wie bei Arrays lösen aber da steh ich jetzt endgültig auf dem Schlauch....
Ergänzung ()

ich verzieh mich jetzt erstmal schmollend in die Sonne und les etwas in meinem C++ buch vielleicht nutzt es ja was falls jemand Tipps für das Sotieren der Liste hat bzw für das nach einem Wert suchen und ersetzen wäre ich dankbar und versuch es dann heute Abend um zu setzen.
 
Sortieren würde ich über den Umweg eines Arrays lösen:

Code:
DLink* List = . . . . // Zu sortierende Liste
DLink* Temp = List;
int Count = 0 

while( temp != NULL ) //Findet Listenlänge
{
Count++;
Temp = Temp ->suc;
}

DLink** ElementArray = new DLink*[Count]; //Legt Array an, welches Pointer auf alle ListenElemente enthält
Temp = List;
for(int i =0; i< Count ; i++) //Speichert Pointer der Elemente im Array ab
{
ElementArray[i] = Temp;
Temp = Temp -> Suc;
}

.....
Sortiere ElementArray wie ein normales Array
.....

for(int i =0; i< Count ; i++) //Aktualisiert die Verweise
{
if(i!=0)
ElementArray[i]->Pre= ElementArray[i-1];
else
ElementArray[i]->Pre=NULL;
if(i!=Count-1)
ElementArray[i]->Suc = ElementArray[i+1];
else
ElementArray[i]->Suc = NULL;
}

List = ElementArray[0];
 
Zuletzt bearbeitet:
ja das ist sehr gut dann kann ich mit herrsche und teile weiter machen.....das war echt ein super tip vielen dank und wenn ich es schon in ein array mache kann ich ja eigentlich auch suchen und ersetzen....
Ergänzung ()

ich wollte das hier von ner alten aufgabe jetzt eigentlich benutzen um das Array zu sortieren, aber irgendwie gibt es beim kompilieren immer den fehler das er array nicht kennt wenn ich ElementArray anstatt array eingebe meckert er 'initializing' : cannot convert from 'DLink' to 'int'
hier mal der Code den ich bei dem Beispiel von Nai ab zeile 19 eingefügt habe

Code:
int links = 0;
	int rechts = Count - 1;
	// Die Mitte wird bestimmt in dem die Variablen links und rechts addiert werden und dieser Wert durch 2 geteilt wird
	int mitte = array[(links + rechts) / 2];
	// Die Variable temp braucht man später noch
	int tempray;

	// so lange links kleiner gleich rechts ist wird Links nach einem größerem Wert als in der Mitte gesucht und Rechts nach einem kleinerem als den Mittelwert
	while (links <= rechts) 
	{
		while (array[links] < mitte) 
		{
			links++;
		}
		
		while (mitte < array [rechts]) 
		{
			rechts--;

		}
		// Die Werte werden getauscht dies geschieht in dem temp erst den Wert von links animmt, dann nimmt links den Wert von rechts an und zum schluss rechts von temp  
		if (links <= rechts) 
		{		   
			tempray = array[links];
			array[links] = array[rechts];
			array[rechts] = temp;
			links++;
			rechts--;
		}  else if (links == rechts) 
		{
			links++;
			rechts--;
		}
	}
	// Links von der Mitte sind alle Werte die kleiner als die Mitte sind und Rechts die größeren, das Array wird weiter aufgeteilt und sortiert
	if (0 < rechts) 
	{
			sort(array, Count - rechts);
	}
	if (links < size) 
	{
		int *pointerarrayrechts = &array[links];
		sort(pointerarrayrechts, size - links);
	}
 
Hi!
Das war mir zu mühsam mich gerade durch den ganzen Thread zu arbeiten aber hier vielleicht ein paar Hinweise:
Wonach willst du denn die Liste sortieren? Bin ich jetzt auf die schnelle nicht drauf gekommen.... evtl. ist es gar nicht nötig da erst ein array draus zu basteln.

Mollfred schrieb:
Code:
	// Die Mitte wird bestimmt in dem die Variablen links und rechts addiert werden und dieser Wert durch 2 geteilt wird
	int mitte = array[(links + rechts) / 2];
Das ergibt keinen Sinn. Ich glaube du meinst :
Code:
         int mitte = (array[links] + array[rechts])/2;
Außerdem wird nicht wirklich verständlich was mit mitte gemeint ist!? Was stehen denn für Werte in der Liste bzw dem Array?
Code:
	// Die Variable temp braucht man später noch
	int tempray;
komische Bezeichnung :)
 
Ergänzung vom 21.06.2013 13:41 Uhr: ich wollte das hier von ner alten aufgabe jetzt eigentlich benutzen um das Array zu sortieren, aber irgendwie gibt es beim kompilieren immer den fehler das er array nicht kennt wenn ich ElementArray anstatt array eingebe meckert er 'initializing' : cannot convert from 'DLink' to 'int'
hier mal der Code den ich bei dem Beispiel von Nai ab zeile 19 eingefügt habe

Das direkte Einfügen wird nicht klappen, da dein Sortieralgorithmus rekursiv ist. Und wegen dem Fehler: Das Array enthält eine Menge an Zeigern auf die einzelnen Listenelemente. Du willst das Array ja nicht nach dem Wert der Zeiger sortieren, sondern nach dem Wert (iContent) der Listenelemente. Auf diesen kannst du mit dem "->" Operator zugreifen.
 
Zurück
Oben