Size: 44201
Comment:
|
Size: 32220
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
== Fragen und Kommentare zur 4. Vorlesung / zum 4. Übungsblatt == [[ProgrammierenCplusplusSS2010/OffTopic|OffTopic]] @Regina: Wie die Warnung sagt, heißt das, dass mit Ihrer Systemuhr etwas nicht stimmt. Oder mit Ihrem Editor, der den Zeitstempel für die Dateien setzt, die er schreibt. Was passiert denn, wenn Sie ''make clean'' machen und dann nochmal ''make build''? Wenn das nicht hilft, kopieren Sie die Datei mit der komischen Änderungszeit doch mal woanders hin, löschen Sie dann die ursprüngliche, und kopieren Sie dann die Kopie wieder zurück. Vielleicht stimmt dann der Zeitstempel? '''Hannah 19Mai10 14:35''' @Jens: Ok danke, funktioniert :) '''Jan 19.Mai2010 14:31''' @Jan: ''const'' davor schreiben. '''Jens 19.Mai2010 13:53''' Was kann man eigentlich gegen diese Warnung tuen? Respektive gibt sie Punktabzug? {{{ ListProcessingTest.cpp:12: Warnung: veraltete Konvertierung von Zeichenkettenkonstante in »char*« }}} In der Zeile initialisiere ich ein char* mit "text".. ''' Jan 19Mai2010 13:51 ''' Hallo, ich bekomme beim make build immer die Meldung: {{{ make: Warnung: Datei 'ListProcessingMain.cpp' hat Änderungszeit 1,5e+03 s in der Zukunft make: Warnung: Mit der Uhr stimmt etwas nicht. Die Bearbeitung könnte unvollständig sein. }}} Deshalb kann ich nichts mehr kompilieren. Was soll ich da tun? '''Regina 19Mai2010 13:41''' @Jan + alle: Ein Feld können Sie übrigens in ''C / C++'' wie folgt initialisieren: {{{ const char* daysOfWeek[7] = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }; int firstTenPrimes[10] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }; }}} Wenn die Anzahl der Elemente in den ''{ ... }'' nicht der Größe des Feldes entspricht, meckert der Compiler. '''Hannah 19Mai10 12:51''' @Jan: Das geht am besten so: {{{ const char* longMessage = "This is a really long message that unfortunately" " does not fit into one line. However, it serves" " as a nice example for how to write down a long" " string without cpplint complaining about it."; }}} '''Hannah 19Mai10 12:48''' Wie kann ich längere char* am besten umbrechen? der linter mag ja keine Zeilen länger als 80 Zeichen. {{{ char* ERROR_CODES[6]; ERROR_CODES[1] = "WARNING: Error in argument %d, at position %d: '%c'.\r\nIllegal char. Only spaces, commata and digits are allowed.\n"; ... }}} Das hier funktioniert leider nicht... wäre ja auch zu schön. {{{ char* ERROR_CODES[6]; ERROR_CODES[1] = "WARNING: Error in argument %d, at position %d: '%c'.\r\n" + "Illegal char. Only spaces, commata and digits are alowed.\n"; ... }}} ''' Jan 19Mai10 12:44 ''' @Betim: Ja, Sie können das schon so machen und bekommen dafür keinen Punktabzug, aber wie ich unten gesagt habe würde ich in dem Fall anstelle von dem ''switch'' lieber ein ''if ... else .. if .. usw.'' verwenden. Und über jedem ''if'' bzw ''else if'' ein Kommentar der sagt was in dem Fall gemacht wird. Diese Kommentare sollten Sie auch haben, wenn Sie bei dem ''switch'' bleiben. '''Hannah 18Mai10 22:09''' Es geht auch so: {{{ switch (listAsString[i]) |
== Fragen und Kommentare zur 5. Vorlesung / zum 5. Übungsblatt == Also ich habe die _capacity variable im Dekonstructor benutzt und damit brauche ich auch nicht die ganze Geschichte von der Verdopplung von _capacity. Gruß '''Dario 27Mai10 21:51''' @Robin: das kommt drauf an, wie du deine Liste initialisierst. Ich initialisiere z.B. mit ''NULL'' somit ist meine _capacity am anfang 0. Im push_back wird die Variable dann beim ersten Element auf 1 gesetzt und bei weiteren Elementen bei größerem Platzbedarf immer verdoppelt (if/else). Die Variable braucht man tatsächlich "nur" im Konstruktor und im push_back(). _capacity muss man erhöhen, wenn die Kapazität voll ist, also _size genau so groß ist wie _capacity und dann ein neues Element hinzu kommen soll. Hoffe, dass konnte helfen Gruß '''Ben 27.Mai10 21:43''' Eine Frage zur der Membervariable _capacity und zwar steht in der Aufgabenstellung : Initialisieren Sie diese Variable im Konstruktor geeignet. Aber was soll dieses "geeignet"? Im Konstruktor hat man die size der Liste noch nicht, deshalb kann man der Variable _capacity diesen Wert nicht zu weisen. Sollen wir nun einen Wert willkürlich wählen z.B: 50, oder wie ist das zu verstehen? Braucht man für die Funktion int pop_back() auch diese Variable _capacity. Sorry aber das mit dieser Variable verursacht bei mir für Schwierigkeiten. So wie ich es jetzt verstanden habe, braucht man die Variable nur in der push_back(int x), und zwar soll dann die _capacity erhöht werden, wenn man die _size überschreitet. Was auch logisch erscheint, denn wenn man ein Integer hinzufügen will, aber die Liste bereits voll ist, so muss man neuen Speicher anfragen, die alte Liste kopieren und dann den Wert von push_back hinzufügen. Danach soll man den alten Speicher, den man nicht mehr brauch wieder freigeben, richtig? Hoffe mir kann jemand helfen. Gruß '''Robin 27 Main 21:22''' Etwas Allgemeineres: Kann es sein, dass Hudson ein Problem mit unseren Ferien hat (es klagt jedenfalls, wenn man die 0 stehen lässt, weil es keinen Ordner uebungsblatt-6 gibt...)? '''SebastianS 27Mai10 02:33''' @Dario Immer wenn du ein neues Element beim "parsen" oder beim "pushen" in die Liste schreibst, erhöhst du _size um 1. '''Ben 26Mai10''' Die ''push-'' und ''pop_back'' Funktionen werden auf ein Objekt vom Typ ListOfIntegers aufgerufen (da ist also logischerweise ein Array mit Integern drin, nämlich _elements). Die _size (und manchmal auch die _capacity) musst du beim Aufruf der Funktionen entsprechend anpassen. '''SebastianD 26Mai10 22:04''' Danke aber was ich nicht wirklich verstehe ist, wie man die Size von der Liste "messen" kann. Bei Parselistofintegers habe ich einfach die Anzahl von komma gezählt, aber hier geht´s nicht. Soll ich davon ausgehen ,dass die List in der Push oder pop function schon geparsed sind oder können auch String sein? '''Dario 26Mai10 21:50''' @Dario Du solltest am Ende 3 Klassenvariablen haben: 1. _elements, diese enthält die Liste, 2. _size, diese enthält die Anzahl der Elemente und 3. _capacity, diese enthält die Größe deines allokierten Speichers. {{{ _elements = new int[20]; _elements[0] = 7; _elements[1] = 8; _elements[2] = 2; // nun müssen die anderen Variablen folgende Werte haben: _size = 3; _capacity = 20; }}} Gruß '''Ben 26Mai10 21:47''' Ich habe so gemacht , weil ich nicht ganau weiß , wie man die Größe von meinem _element in Push oder pop_backfunktion bestimmen kann. '''Dario 26Mai10 20:16''' @Dario: Das verstehe ich nicht, warum wollen Sie der ''push_back'' oder ''pop_back'' Funktion ein Listenobjekt als Argument mitgeben? Die Methoden werden doch immer gerade von einem Listenobjekt aufgerufen, so wie z.B. in ''ListOfIntegers list;'' gefolgt von ''list.push_back(5)''. Die ''_capacity'' Variable brauchen Sie deswegen, weil es einmal die aktuelle Anzahl von Elementen in der Liste gibt (''size'') und einmal, für wieviel Elemente Platz alloziert wurde (''_capacity''). Das macht man deswegen, damit man nicht nach jedem ''push_back'' neu Platz allozieren und umkopieren muss, sondern nur ab und zu. Genauer gesagt kriegt man so eine durchschnittliche (amortisierte) Laufzeit für ''push_back'', die unabhängig von der Listenlänge ist. '''Hannah 26Mai10 20:21''' @Betim: Ja, wie Dario sagt, Ihr ''getElement'' ist ja eine ganz normale Funktion / Methode, und die ruft man mit runden Klammern auf, nicht mit eckigen. '''Hannah 26Mai10 20:16''' @David: Ja, wie in der Vorlesung vorgemacht, soll man die ''-1'' weglassen. Braucht man ja auch nicht mehr wenn man die ''_size'' hat. '''Hannah 26Mai10 20:15''' Bei der 2te Aufgabe darf man die push_back und pop_back mit einem zusätzlichem Argument implementieren? damit brauche ich nicht mehr die _capacity variable. Wie folgendes: {{{ // die list 1 ist schon geparsed. ListOfIntegers push; push.push_back( &list1 , x) }}} Dasselbe auch für pop_back. Grüße '''Dario 26Mai10 20:00''' @Betim.Probier es einfach anstatt[] mit () klammer also getElement(1) anstatt getElement [0] '''Dario 26Mai10 17:52''' @David: Ich hab das mit -1 entfernt und benutze stattdessen _size. Ich glaube auch, man soll das so machen. Aber mal ne andere Frage: Nachdem das mit FRIEND_TEST nicht funktioniert hat, habe ich mir eine getElement(int n) Methode geschrieben, die eben das n-te Element zurückgibt. Die sieht so aus: {{{ int ListOfIntegers::getElement(int n) |
Line 66: | Line 57: |
case ' ' : break; default: printf("Error: Expected digit or comma, found space.\n"); exit(1); break; |
assert(n >= 0); return _elements[n]; |
Line 73: | Line 62: |
'''Daniel 18Mai10 22:06''' Mein Code: {{{ switch (listAsString[i]) |
Der Test schaut so aus: {{{ TEST(ListOfIntegers, parseFromString) |
Line 80: | Line 67: |
case ' ' : if (!digitBegin) { startOfLastNumber = i + 1; break; } else { printf("Error: Expected digit or comma, found space.\n"); exit(1); } }}} Ich benutz switch schon korrekt, es ist ja nicht so, dass da nur 4 cases stehen. '''BetimM 18Mai10 21:57''' Mein Programm beachtet schon MAX_LIST_SIZE und die Mitteilung auf der Hauptseite habe ich auch beachtet, es ging mir nur darum, dass hier zwischen den verschiedensten Fragen nebenher erwähnt wird, dass zusätzlich noch weitere Meldungen ausgegeben werden müssen, mehr nicht. Es stört mich nicht, dass es gemacht werden muss, es hat mich nur gestört, dass es hier fast untergeht und darum die Bitte, ob man zukünftig solche (meines Erachten) wichtige Sachen nicht auch gleich von Anfang an aufschreiben könnte oder spätestens wenn sie aufkommen direkt auf die Hauptseite packen. Danke '''Ben 18Mai10 21:45''' @Betim 2: Wenn in den ''case'' Anweisungen von dem switch größerer Code steht und es wenige cases gibt, sollte das ''switch'' auch besser kein ''switch'' sein, sondern ein gewöhnliches ''if (...) { ... } else if (...) { ... } else if (...) { ... } usw.'' Ein ''switch'' ist ja nur eine Abkürzung für so ein if-else-if-usw. und man verwendet es eigentlich nur wenn die Anweisungen für die verschiedenen ''cases'' kurz und gleichartig sind. '''Hannah 18Mai10 21:52''' @Betim: Posten Sie doch mal das konkrete Stück Code, was Sie da schreiben wollen. Dann sage ich Ihnen ob das ok ist, oder wie man es besser machen kann. '''Hannah 18Mai10 21:49''' Kriege ich Punkte abgezogen, wenn ich in einem switch-Konstrukt kleinere if-else-Abfragen habe? Z.B. {{{ switch(..) case 1: if(..) { ...} else { ... } }}} Ich weiss das ist kein guter Programmierstil, aber imho fällt mir nichts besseres ein. '''BetimM 18Mai2010 21:42''' @Ben: Es steht schon in meinem Programm aus der Vorlesung ''TODO(bast): deal with the case of more than MAX_LIST_SIZE elements.'' Aber sie haben Recht, ich hätte das auch in der Mitteilung nochmal schreiben sollen. Abgesehen davon habe ich die Aufgabe am Donnerstag nach der Vorlesung auf der Hauptseite präzisiert. Die Mitteilungen auf der Hauptseite sollte selbstverständlich jeder lesen. Danach kamen eigentlich nur noch Nachfragen zu Details. Wer sich an die Präzisierung vom Donnerstag hält bekommt keine Punkte abgezogen, keine Sorge. Ich werde zu dem Thema auch morgen in der Vorlesung noch einmal etwas sagen. '''Hannah 18Mai10 21:13''' Änderen sich die Anforderungen an die Aufgabe noch häufiger? Also weder auf dem Arbeitsblatt noch in der Beschreibung auf der Hauptseite steht, dass man eine Fehlermeldung bei einer zu langen Liste ausgeben muss. Hab das gerade nur hier zwischen dem vielen Text zufällig gefunden. Es wäre gut, wenn solche Anforderungen zumindest immer auf dem Arbeitsblatt stehen würden, damit man nicht die Gefahr läuft, dass plötzlich 2 Tage vor der Abgabe sich wieder etwas ändert. Ich schaue zwar meistens täglich hier ins Wiki, trotzdem finde ich es, so wie es gerade abgelaufen ist, recht unglücklich gelöst. Weil, wie gesagt, man laut Arbeitsblatt __keine__ Fehlermeldung ausgeben muss. Da kann man jetzt nur hoffen, dass jeder das Wiki liest. Danke '''Ben 18Mai10 20:44''' @Jonas: Die Fehlermeldung passt in der Tat nicht zu dem Code den Sie hier gepostet haben. Sind Sie sicher, dass sich die Fehlermeldung auf diese Zeilen in Ihrem Code bezieht? Fall ja, posten Sie doch mal ein minimales Programm, in dem sich dieser Fehler zeigt. '''Hannah 18Mai10 20:25''' @Jonathan: Ja, es ist auch ok, wenn Sie im Falle zu langer Listen einfach ''exit(1)'' machen. Und Testen ist auch nicht mandatory, habe ich ja unten schon geschrieben. Wobei es in meinem Code keinen wesentliche Mehrarbeit war diesen Fall auch noch zu behandeln. '''Hannah 18Mai10 20:22''' Hoffe mal die Frage ist nicht zu spezifisch: Ich versuche über die Funktion {{{ bool isValidChar(char n) { ... return true; } }}} herauszufinden ob das momentane Zeichen legal ist. Das Problem ist aber, dass der Compiler "Invalid converison from 'const char' to 'char*'" ausspuckt, wenn ich die Funktion aufrufe: {{{ isValidChar(listAsString[i]) }}} bzw: {{{ if (isValidChar(listAsString[i]) == true) }}} und ich eben nicht ganz nachvollziehen kann, warum er überhaupt versucht zu char* zu konvertieren.. '''JonasH 19:11 18Mai10''' Das heißt für zu lange Listen muss ich auch noch eine Fehlermeldung mir aus denken? Denn der Code wächst und wächst, allein meine Datei ListProcessingTest.cpp hat in Zwischenzeit über 100 Zeilen, und es Fehlen noch mindestens 2 Fälle. Denn den Fall zu lange Liste hatte ich verstanden, dass dieser einfach mit exit(1) beendet werden sollte, also in anderen Wörtern soll auch da das Programm weiter laufen und mit interleaveListsOfIntegers fort fahren? '''JonathanN 18Mai10 16:33''' @Hannah: Alles klar, vielen Dank. '''SebastianS 15:52 18Mai10''' @SebastianS: Gute Frage. So ginge es zum Beispiel: {{{ char tooLongList[2 * MAX_LIST_SIZE + 2]; for (int i = 0; i < MAX_LIST_SIZE; ++i) { tooLongList[2 * i] = '0'; tooLongList[2 * i + 1] = ','; } tooLongList[2 * MAX_LIST_SIZE] = '0'; tooLongList[2 * MAX_LIST_SIZE + 1] = 0; }}} und dann testen ob ''parseListOfIntegers'' die Liste abschneidet bzw. die leere Liste zurückgibt, je nachdem wie Sie es implementiert haben. Es gibt aber keinen Punktabzug wenn Sie diesen Fall nicht testen (ist ja schon nicht so einfach, und habe ich auch vorher nicht dran gedacht), aber wenn Sie möchten, gerne, und jetzt habe ich ja schon den halben Code dazu geschrieben. '''Hannah 18Mai10 15:01''' Wie sollen wir eigentlich im Test das Überschreiten von MAX_SIZE_LIST überprüfen? Weil lint wirft da ja immer einen Fehler, dass die Zeile im Test (also die, in der ich den Teststring initialisiere) zu lange wäre :-) ? '''SebastianS 18Mai10 14:47''' @Daniel: Auf jeden Fall eine Warnung ausgeben. Ob Sie die Liste abschneiden oder die leere Liste zurückgeben, sei Ihnen überlassen. Ich habe sie in meiner Lösung einfach abgeschnitten. Das sollte dann auch in der Warnung stehen. '''Hannah 18Mai10 14:03''' Das MAX_LIST_SIZE soll behandelt werden, wie soll das Ergebnis der behandlung aussehen? Warning? Leere Liste zurückgeben? Oder einfach die Liste abschneiden? '''Daniel 18Mai10 13:56''' @Simson: Schauen Sie doch einmal bei einem unserer Fragetermine oder bei Jens Hoffmann vorbei. Das scheint ein nicht-triviales Problem zu sein, das sich am besten mit dem Rechner lösen lässt, sonst schwierig. '''Hannah 18Mai10 13:55''' Habe seit diesem Blatt Probleme mit GTest. Habe meine Fehler unter [[ProgrammierenCplusplusSS2010/GTest#Fragen_und_Antworten_zur_Installation|GTest]] beschrieben. Vielleicht hat ja wer eine Idee. '''Simson 18Mai2010 12:05''' @Peter + Alle: Ja, wie Dario richtig sagt, beim ersten Mal als ''const char*'' deklarieren, und beim zweiten Mal einfach einen anderen Wert an die selbe Variable zuweisen. Das geht deswegen weil das ''const'' vor einem pointer nicht etwas heißt, dass man den pointer nicht auf einen anderen Wert (also eine andere Adresse) setzen kann, sondern dass man den Inhalt dessen, worauf der pointer zeigt, nicht verändern kann. Das andere wäre ''char const *'', das gibt es auch, braucht man aber praktisch nie. Und ''const char const *'' gibt es auch, braucht man aber auch praktisch nie. Das mit dem ''const'' werde ich in einer der nächsten Vorlesungen noch genauer erklären. '''Hannah 18Mai10 2:27''' wenn du das wieder so schreibst const char* deklarierst du dein listAsString 2mal, du musst also ohne const char* schreiben und setzt einfach die neue werte. '''Dario 18Mai2010 01:52''' Ich hab gerade ein paar Probleme mit der Test Datei aus der Vorlesung. Um weitere Randfälle zu testen, müsste man doch den Wert von "const char* listAsString = ... " ändern im Test der Funktion parseListOfIntegers, dies geht aber nicht weil durch const der Compiler sofort meckert, wenn ich ein anderes Szenario testen möchte. Kann mir jemand helfen? '''Peter 18Mai2010 01:40''' @Hannah: Ich habe jetzt die ''ListProcessing.h'' Datei in der entsprechenden ''.cpp'' includiert und es läuft jetzt alles. Ich dachte das wäre nicht nötig, da es bei den Definitionen für die Funktionen ja auch so klappt. '''Heinke 17Mai 19:13''' @Heinke: Wenn ''MAX_LIST_SIZE'' in der ''.h'' Datei definiert ist (und das sollte es), müssen Sie diese Datei überall da, wo sie ''MAX_LIST_SIZE'' verwenden wollen, includen. Sonst weiß der Compiler nicht, dass es diese Variable gibt. '''Hannah 17Mai10 18:58''' @Hannah: So habe ich es mir auch gedacht und MAX_LIST_SIZE verwendet. Jedoch bekomme ich die Fehlermeldung MAX_LIST_SIZE was not declared in this scope. Woran könnte das liegen? '''Heinke'''''' 17Mai10 18:54''' @Dennis: Wenn Sie sich in einer Arbeitskopie aus dem SVN befinden (das sehen Sie daran, ob es einen ''.svn'' Unterordner gibt), dann sagt Ihnen ''cpplint.py'' wie die header guard aussehen soll. Wenn es den ''.svn'' Unterordner nicht gibt, verlangt er den absoluten Pfad. Ich erkläre das in einer der nächsten Vorlesungen. Solange bekommen Sie ''keinen'' Punktabzug, wenn das mit den header guards nicht stimmt. Aber wäre nett, wenn Sie's trotzdem versuchen hinzukriegen. '''Hannah 17Mai10 18:50''' @Heinke: Zur ersten Frage: ''MAX_LIST_SIZE'' ist eine globale Variable, die brauchen Sie der Funktion nicht extra zu übergeben, Sie können einfach innerhalb der Funktion (und überhaupt überall in Ihrem Code) ''MAX_LIST_SIZE'' verwenden. Zur zweiten Frage: Die ''interleaveListsOfIntegers'' Funktion soll die beiden Listen schon als ''int*'' bekommen (geparsed werden sollen sie vorher). '''Hannah 17Mai10 18:46''' Ich muss die Header Guards an mein Systempfad anpassen damit lint keinen Fehler wirft. Aber wie müssen die dann aussehen, dass das lint auch bei euch auf dem SVN Server keine Fehler wirft? '''Dennis 17Mai10 18:40''' Kann ich der Funktion parseListOfIntegers die Konstante MAX_LIST_SIZE mitgeben, damit ich auf Überlauf testen kann? Und kann ich bei der interleave Funktion davon ausgehen, dass die beiden übergebenen Listen bereits integer sind? Oder müssen sie vorher auch geparsed werden? '''Heinke '''''' 17Mai10 18:40''' @Johannes: Siehe dazu mein Kommentar vom ''9Mai10 18:54'' zum [[ProgrammierenCplusplusSS2010/Blatt3Fragen|3. Übungsblatt]]. '''Hannah 17Mai10 17:30''' @Jonathan: Ja, Fehlermeldungen wie im Beispiel von SebastianS sind perfekt. So viele Fälle sind es nicht. Sobald irgendein Fehler auftritt, können Sie das parsen abbrechen, die entsprechende Fehlermeldung ausgeben und die leere Liste zurück liefern. Sie müssen nichts reparieren oder die wahrscheinlich gemeinte Liste "erraten" und auch nicht alle Fehler finden, der erste reicht. '''Hannah 17Mai10 17:23''' @SebastianD + Alle: Ja, Ihre Fehlermeldungen sind perfekt. Unabhängig davon sollten sie aber noch ''printListOfIntegers'' für die beiden Eingabelisten aufrufen, nachdem sie geparsed worden sind (so wie es auch im Code aus der Vorlesung war). Ihre ersten beiden Übungsblätter sollten längst korrigiert worden sein, ich habe Jens Hoffmann Bescheid gegeben, er wird sich darum kümmern und sich bei Ihnen melden. '''Hannah 17Mai10 17:15''' Zitat von Hannah (Hauptseite): "Und vor und nach einem Komma muss eine Zahl kommen", wenn eine Liste mit einem Komma aufhört, ist das also ein Syntaxfehler. Falls es irgendwen interessieren sollte, so sehen meine Fehlermeldungen aus: {{{ PS C:\Dateien\Studium\6. Semester\c++\sd76\uebungsblatt-4> .\ListProcessingMain.exe "1,2,3" "4,n, 5,8" ERROR in list "4,n, 5,8" at position 2: expected digit or space, found 'n' Result list: "1,2,3" PS C:\Dateien\Studium\6. Semester\c++\sd76\uebungsblatt-4> .\ListProcessingMain.exe "1,5,6,8," "4-5" ERROR in list "1,5,6,8,": The last token of your input is ','. ERROR in list "4-5" at position 1: expected comma, digit or space, found '-' Result list: "" PS C:\Dateien\Studium\6. Semester\c++\sd76\uebungsblatt-4> .\ListProcessingMain.exe "1,5,6,8," "4 5" ERROR in list "1,5,6,8,": The last token of your input is ','. ERROR in list "4 5" at position 2: expected comma or space, found '5' Result list: "" }}} '''SebastianD 17Mai10 17:04''' Dann muss ich ja schon fast für jeden Fehler, eine andere FehlerMeldung ausgeben, also bei folgendem Beispiel an Eingabelisten 1,2,6 4,n , 5,8 müsste ich da als Fehlermeldung ausgeben: Bei der 2 Liste haben Sie als 2. Element ein Buchstaben getippt, oder so genau dann auch wieder nicht? Denn ich habe bisher, nur ne Fehlermeldung wenn in der Liste etwas vorkommt was keine Ziffer, Leerzeichen bzw. Komma ist, gebe ich einfach ne Fehlermeldung, àla : Da ist ein Zeichen was da nicht hin gehört. Dann noch ne Frage, bei Folgender Liste 1,5,6,8, (es geht um das Komma am Ende) soll ich dies als Fehler ansehen, und daraus die leere Liste machen? Oder schluck ich das als das gleiche wie 1,5,6,8 ? Des Weiteren scheint es immer noch welche hier auf der Wiki zu geben die sich nicht an die Konvention halten wie hier unterschrieben werden sollte. Des weiteren, scheint es einig zugeben die sich ein Preis für die meisten Zeilen, bzw die meisten Änderungen erwarten, oder? Mit endlich mal sonnigen Grüßen '''JonathanN 17Mai10 16:46''' Dann muss ich ja schon fast für jeden Fehler, eine andere FehlerMeldung ausgeben, also bei folgendem Beispiel an Eingabelisten 1,2,6 4,n , 5,8 müsste ich da als Fehlermeldung ausgeben: Bei der 2 Liste haben Sie als 2. Element ein Buchstaben getippt, oder so genau dann auch wieder nicht? Denn ich habe bisher, nur ne Fehlermeldung wenn in der Liste etwas vorkommt was keine Ziffer, Leerzeichen bzw. Komma ist, gebe ich einfach ne Fehlermeldung, àla : Da ist ein Zeichen was da nicht hin gehört. Dann noch ne Frage, bei Folgender Liste 1,5,6,8, (es geht um das Komma am Ende) soll ich dies als Fehler ansehen, und daraus die leere Liste machen? Oder schluck ich das als das gleiche wie 1,5,6,8 ? Des Weiteren scheint es immer noch welche hier auf der Wiki zu geben die sich nicht an die Konvention halten wie hier unterschrieben werden sollte. Des weiteren, scheint es einig zugeben die sich ein Preis für die meisten Zeilen, bzw die meisten Änderungen erwarten, oder? Mit endlich mal sonnigen Grüßen '''JonathanN 17Mai10 16:46''' @SebastianD: Ja, so erscheint mir die Fehlermeldung auch. ;) Die Datei existiert jedoch und ich habe den Parameter -lgtest_main dem Compiler-Befehl der Test-Datei beigefügt. Daher verstehe ich nicht, weshalb der Compiler dem Pfad nicht zu folgen können scheint. -- [[JohannesS]] <<DateTime(2010-05-17T13:42:22Z)>> Ich schätze, es ist nicht normal, dass ich bisher nicht einmal für das erste Übungsblatt Punkte erhalten habe, oder?<<BR>> @Hannah: Also eine Fehlermeldung, die ich erwarten würde, würde auch die Gesamtposition in der Eingabe ausgeben. Nur lässt sich das mit der aktuellen Methodensignatur nur über eine globale (veränderbare) Variable lösen, in der das Offset gespeichert würde. Das fände ich dann aber wieder zu ekelhaft, vor allem weil die ''parseListOfIntegers'' dann für korrekte Funktionsweise direkt von der main-Methode abhängen würde (Offset für Programmbefehl).<<BR>> @Johannes: Die Fehlermeldung sieht für mich so aus, als ob die Datei libgtest_main.so.0 nicht gefunden wurde. '''SebastianD 17Mai10 15:33:''' Ich schätze, es ist nicht normal, dass ich bisher nicht einmal für das erste Übungsblatt Punkte erhalten habe, oder?<<BR>> @Hannah: Also eine Fehlermeldung, die ich erwarten würde, würde auch die Gesamtposition in der Eingabe ausgeben. Nur lässt sich das mit der aktuellen Methodensignatur nur über eine globale (veränderbare) Variable lösen, in der das Offset gespeichert würde. Das fände ich dann aber wieder zu ekelhaft, vor allem weil die ''parseListOfIntegers'' dann für korrekte Funktionsweise direkt von der main-Methode abhängen würde (Offset für Programmbefehl).<<BR>> @Johannes: Die Fehlermeldung sieht für mich so aus, als ob die Datei libgtest_main.so.0 nicht gefunden wurde. '''SebastianD 17Mai10 15:33:''' Dann muss ich ja schon fast für jeden Fehler, eine andere FehlerMeldung ausgeben, also bei folgendem Beispiel an Eingabelisten 1,2,6 4,n , 5,8 müsste ich da als Fehlermeldung ausgeben: Bei der 2 Liste haben Sie als 2. Element ein Buchstaben getippt, oder so genau dann auch wieder nicht? Denn ich habe bisher, nur ne Fehlermeldung wenn in der Liste etwas vorkommt was keine Ziffer, Leerzeichen bzw. Komma ist, gebe ich einfach ne Fehlermeldung, àla : Da ist ein Zeichen was da nicht hin gehört. Dann noch ne Frage, bei Folgender Liste 1,5,6,8, (es geht um das Komma am Ende) soll ich dies als Fehler ansehen, und daraus die leere Liste machen? Oder schluck ich das als das gleiche wie 1,5,6,8 ? Des Weiteren scheint es immer noch welche hier auf der Wiki zu geben die sich nicht an die Konvention halten wie hier unterschrieben werden sollte. Des weiteren, scheint es einig zugeben die sich ein Preis für die meisten Zeilen, bzw die meisten Änderungen erwarten, oder? Mit endlich mal sonnigen Grüßen '''JonathanN 17Mai10 16:46''' @SebastianD: Ja, so erscheint mir die Fehlermeldung auch. ;) Die Datei existiert jedoch und ich habe den Parameter -lgtest_main dem Compiler-Befehl der Test-Datei beigefügt. Daher verstehe ich nicht, weshalb der Compiler dem Pfad nicht zu folgen können scheint. -- [[JohannesS]] <<DateTime(2010-05-17T13:42:22Z)>> Ich schätze, es ist nicht normal, dass ich bisher nicht einmal für das erste Übungsblatt Punkte erhalten habe, oder?<<BR>> @Hannah: Also eine Fehlermeldung, die ich erwarten würde, würde auch die Gesamtposition in der Eingabe ausgeben. Nur lässt sich das mit der aktuellen Methodensignatur nur über eine globale (veränderbare) Variable lösen, in der das Offset gespeichert würde. Das fände ich dann aber wieder zu ekelhaft, vor allem weil die ''parseListOfIntegers'' dann für korrekte Funktionsweise direkt von der main-Methode abhängen würde (Offset für Programmbefehl).<<BR>> @Johannes: Die Fehlermeldung sieht für mich so aus, als ob die Datei libgtest_main.so.0 nicht gefunden wurde. '''SebastianD 17Mai10 15:33:''' Bedeutung der Fehlermeldung ./ListProcessingTest: error while loading shared libraries: libgtest_main.so.0: cannot open shared object file: No such file or directory? -- [[JohannesS]] <<DateTime(2010-05-17T12:56:56Z)>> @Dennis: Ja, ''interleaveListOfIntegers'' soll drei Argumente haben, genau wie Sie es beschrieben haben. Und ja, wenn Sie die Resultatliste ausgeben, sollen Sie dafür ''printListOfIntegers'' mit einem prefix a la ''Result list :'' oder so ausgeben. Sinnvolle Fehlermeldung heißt, dass sie nicht einfach schreiben ''Ein Fehler ist aufgetreten'' sondern was für ein Fehler, und nett wäre, wenn Sie dann gleich auch dazu schreiben an welcher Stelle in der Liste und was die Liste war, die gerade geparsed wurde. Kurz, die Fehlermeldung die Sie selber gerne bekommen würden, wenn Sie das Programm als user benutzen. Eine Zeile pro Fehlermeldung finde ich ok, wenn die Fehlermeldung den geparseten string enthält, dann kann man das als Benutzer schon zuordnen. Aber ''printListOfIntegers'' sollte keine Fehlermeldung ausgeben, wenn die Liste leer ist, eine leere Liste ist ja auch eine Liste und man kann ja auch ganz regulär eine leere Liste als Argument übergeben (durch den leeren string, das soll dann kein Fehler sein, hatten wir ja schon in einer der vorherigen Fragen). '''Hannah 17Mai10 13:53''' Ist es korrekt wenn mein interleaveListsOfIntegers drei Argumente erhält? Zwei Zeiger Zahlenfolgen und, wie parseListOfIntegers auch, einen Zeiger auf die Liste in die das Ergebnis geschrieben werden soll (welche dann zuvor in der Main angelegt wird)? Darf ich in der Main dann printListOfIntegers und ein anderes prefix verwenden um die neue Liste auszugeben? Was genau ist mit einer sinnvollen Fehlermeldung in parseListOfIntegers gemeint. Genügt es eine allgmeine Fehlermeldung für falsche Eingabe zu verwenden oder soll explizit angegeben werden welcher Fehler vorliegt. Das würde jedoch dazu führen, dass da parseListOfIntegers zweimal parallel ausgeführt wird, die Fehlermeldungen relativ unstrukturiert ausgegeben werden. Mein Ansatz ist bis jetzt, dass printListOfIntegers wenn es eine leere Liste erhält nach der leeren List ("") einen Hinweis auf eine falsche Eingabe ausgibt. Wäre das ok?''''' ''''''''Dennis 17.Mai10 12:31'''''''' ''''' @Markus: Sie sollten sich auf die Funktionen und Konstrukte beschränken, die wir bisher in der Vorlesung hatten. '''Hannah 16Mai10 18:26''' Ist es eigentlich erlaubt Funktionen aus z.B. cstring und cctype zu verwenden? Oder darf man sich lediglich auf stdio und stdlib beschränken. '''MarkusN 16Mai 18:18''' @Fabian: Danke für den ersten Hinweis, ich habe den exit operator dort verwendet und daher hatte ich so viele Schwierigkeiten. Was die zweite Anmerkung angeht, bin ich nicht soo Anfänger, dass ich das nicht weiß. Evtl. habe ich es falsch ausgedrückt aber es war schon spät und den Compiler oder wie auch immmer hatte mich schon genervt :D Gruß. '''Dario 16Mai10 10:48''' @Dario: ''./ListProcessingMain "" " 1,2,3,4 "'' soll keine Usage-Info ausgeben, da ja 2 Argumente da sind ("" und " 1,2,3,4 "). Es liegt an dir dafür zu sorgen, dass "" in die leere Liste umgesetzt wird. Außerdem soll das Programm ja selbst bei falschen Zeichen in den Argumenten nicht mit einem exit-code terminieren (die funktion soll schließlich noch die leere Liste zurückgeben), sondern Weiterlaufen, aber den Benutzer darüber in Kenntnis setzen, dass wohl irgendwo im Programm nicht alles nach Plan lief. Wenn ich die Aufgabenstellung richtig verstehe, dann soll selbst ''./ListProcessingMain " abc" " 1,2,3,4 "'' die Liste 1,2,3,4 ausgeben, aber noch zusätzlich noch eine Warnung. Kleine Anmerkung am Rande: Der Compiler gibt die Usage-Meldung nicht aus, sondern dein Programm, falls das mit dem letzten Teil deines Satzes ausgesagt werden sollte. '''Fabian 16Mai10 9:21''' Also dann kann ich gar nicht meine leeren Listen außer mit dem TEST sehen, weil ''./ListProcessingMain'' "" "1,2,3,4" würde mir immer den Compiler Usage info ausgeben, und das Komma ohne Zahl ist ja nicht erlaubt. '''Dario 15Mai10 00:22''' @Dario: Das Programm muss mit genau zwei Argumenten aufgerufen werden (also ''argc == 3''), sonst müssen Sie gar nichts machen und können einfach die usage info ausgeben. '''Hannah 16Mai10 00:10''' Ja meine Frage war wenn ich z.B {{{ uebungsblatt-4$ ./ListProcessingMain 1 Usage: ./ListProcessingMain <list1> <list2> }}} eine Liste ist leer aber ich kriege den Usagesfehler . deshalb hatte ich mir gedacht die Geschichte mit der Null. Also muss ich diese Meldung ändern. P.S. wegen der Triviale Änderung tut es mir Leid , jedes mal sehe ich nicht dies kleines Kästchen. '''Dario 15Mai10 00:00''' @Dario: Ja, wie Sebastian sagt ist eine Liste in der internen Repräsentation leer, wenn gleich das erste Element schon ''-1'' ist. Beim Aufruf übergeben wird eine leere Liste mit einem leeren string als Argument, also z.B. ''./ListProcessingMain "" "1,4,5,546"''. Noch eine Bitte, Dario, wenn Sie eine Ihrer Fragen im Nachhinein korrigieren oder leicht verändern, setzten Sie doch bitte das Häkchen oben in das Kästchen ''Triviale Änderung'', es kriegen sonst alle, die diese Seite abonniert haben, insbesondere ich, vier Benachrichtigungmails oder so anstatt einer wie es sein sollte. '''Hannah 15Mai10 23:57''' Eine Liste ist leer, wenn sie mit -1 beginnt. '''SebastianS 15Mai10 23:50''' Aber ich habe noch nicht verstanden wann eine Liste leer ist.Ohne Argument oder mit unendlichen vielen Null? Gruß '''Dario 15Mai10 23:44''' @Dario: Die 0 ist erlaubt und muss ja auch gar nicht besonders behandelt werden. Nur negative Zahlen sind nicht erlaubt (weil kein ''minus'' erlaubt ist, das würde sonst alles komplizierter machen weil das ''minus'' ja nur am Anfang einer Zahl stehen dürfte und da nur einmal). '''Hannah 15Mai10 23:22''' Wenn eine Liste nur die Zahl Null enthält dann ist die Liste leer oder nicht? oder ist die Liste leer wenn ich kein Argument bzw. Zahl schreibe? Ich bin davon ausgegangen, dass wenn die erste zahl null ist,dann ist die Liste leer. sonst wird es schon komplizierter. z.B liste 1{0} aber auch {0,0,0,0,0,0,} ist wieder leer.. aber die Sache mit dem Null ist schon an sich komplieziert weil dann wäre eine so eine List { 0,0, unendliche viele null bis MAX_LIST_SIZE -1 ,1} nicht leer Noch eine Frage wenn ich so eine Liste habe { 0,1,2,3} oder { 1,2,0,3} oder {0,1,2} der Null müss berücksichtigt werden als Zahl bei der PrintFunktion oder muss einfach weggelassen werden? '''Dario 15Mai10 22:28''' @Fabian + Alle: Ja, so wie Sie es sagen ist es genau richtig. Ich hatte es verkürzt und dadurch nicht ganz korrekt dargestellt. Richtig ist, wie Sie sagen, dass eine Zahl zwischen 2^31^ und 2^32^ - 1 für einen ''int'' als negative Zahl aufgefasst wird, und eine Zahl die größer oder gleich 2^32^ ist modulo 2^32^ genommen wird (da ja nur 32 bits zur Verfügung stehen) und der Rest dann entweder als positive Zahl (falls < 2^31^) oder als negative Zahl (falls >= 2^31^) aufgefasst wird. '''Hannah 15Mai10 12:05''' Kleiner Hinweis zu den "int"-s: 1) ints haben einen Wertebereich von -2^31^ bis 2^31^ - 1(, werden somit also warscheinlich als Zweierkomplement-Zahl dargestellt). Zweierkomplementzahl bedeutet, dass die untersten n-1 Bits der Zahl als "normale positive" Binärzahl interpretiert wird und wenn wenn das oberste Bit auf 1 ist, dann wird noch 2^(n-1)^ von dieser Zahl abgezogen. (Integer n=32 für 32 Stellen) 2) wenn eine int-Variable folglich mit 2^31^ -1 (Binärdarstellung: 011111...111(32 Stellen))belegt ist, und man 1 auf diese Variable addiert, so erhält man -2^31^ (Binärdarstellung: 10000...0000 (32 Stellen)). Folglich stimmt das mit dem modulo nicht ganz. '''Fabian 15Mai10 8:52''' @Hannah: Achssooo.. Ich habe die ganze Zeit versucht diesen Fehler zu beheben, :D danke. '''Dario 4Mai10 19:40''' @Dario: Ein ''int'' sind 4 bytes = 32 bits und kann höchstens 2^31^ groß sein. Alles war größer ist (und eine 11-stellige Zahl ist größer), wird dann einfach modulo 2^31^ genommen. Darum brauchen Sie sich aber in Ihrem Programm nicht zu kümmern. '''Hannah 14Mai10 21:04''' Hallo, könnte mir bitte jemand nur einen kleinen Tipp geben warum wenn ich mehr als 11 Ziffern( für ein Zahl z.B- 12345678911,2,4) eintippe dann bekomme ich(erste Zahl, die andere nach der Komma sind richtig) eine Random Zahl? also liegt es an der Größe des Arrays? MAX_LIST_SIZE? Gruß '''Dario 4Mai10 19:40''' @Johannes: Wenn man das Programm z.B. so aufruft ''./ListProcessingMain "abc"'', dann zeigt ''argv[1]'' auf die Zeichenkette ''abc'' und nicht auf die Zeichenkette ''"abc"''. Die Anführungszeichen sind etwas für die Unix/Linux-Shell, aus der heraus Sie das Programm aufrufen, die werden nicht an das Programm übergeben. Sie können das ganz einfach testen indem Sie die Zeichenketten ausgeben, da werden dann keine Anführungszeichen drin sein, selbst wenn Sie beim Aufruf Anführungszeichen um die Argumente geschrieben haben. Wenn Sie wirklich ein Anführungszeichen als Argument übergeben wollten müssten Sie es "escapen", das geht zum Beispiel so ''./ListProcessingMain \"abc\"''. Ok? '''Hannah 14Mai10 19:40''' Folgende 2 Fragen: 1. Es sind ja nur dann Leerzeichen innerhalb der Liste möglich, wenn die Characterkette als String angegeben wird. Das wurde ja weiter unten schon festgestellt (sonst wären die Leerzeichen Argument-Separatoren). In dem Fall müsste man jedoch die Anführungszeichen bei Bearbeitung der Eingabe berücksichtigen. Sollen nun das non-String Eingabe-Format (z.B. 1,2,3) ohne Leerzeichen oder das String Eingabe-Format (z.B. "1, 2, 3") mit mögl. Leerzeichen oder beide Formate behandelt werden? 2. Beim Auftauchen anderer Zeichen soll "eine sinnvolle Warnung" sowie die leere Liste ausgegeben werden. Also nur die Warnung oder sollte sich die "leere Liste" irgendwie in der Ausgabe manifestieren? '''JohannesS 14Mai10 18:04''' __Offtopic:__ Jeder, der Interesse daran hat: Ich habe vor ner Woche ein Forum für alle Informatik-Studenten, die letztes Semester angefangen haben, eröffnet. Wer will, kann sich dort gerne anmelden: http://info-unifreiburg09.forumieren.com/ '''DavidZ. 14Mai10 15:48''' @Dario: In der Deklaration ''int list1AsString[MAX_LIST_SIZE]'' wird ja dann soviel Speicher reserviert. Wenn aber so viel Speicher gar nicht da ist, meckert der Compiler, würde ich auch machen an dessen Stelle. '''Hannah 14Mai10 13:02''' Warum kann man nicht die Variable MAX_LIST_SIZE belibig groß machen? also wenn ich 100000000000000= MAX_LIST_SIZE setze dann den Compiler meckert. '''Dario 14Mai10 11:59'''' Der Fehler war eine Zeile darunter printf("%s"...) anstatt printf("%c"...) '''Ben 14Mai10 02:41''' @Ben: In dem Teilstück unten sehe ich keinen Fehler, ich glaube der segmenation fault kommt woanders her. Schreiben Sie doch mal ein vollständiges, aber minimales(!) Programm, wo der segfault auftritt und pasten Sie es hierhin. '''Hannah 14Mai10 2:38''' Hallo, warum liefert ein switch über listAsString[i] in der Funktion parseListOfIntegers() __immer__ einen SegFault, wenn das Zeichen nicht zwischen 0-9 ist (in dem Fall noch als Char gespeichert)? Ich schreibe doch keinen Wert (in einen gesperrten Speicherbereich) sondern will nur den Wert überprüfen {{{ int i = 0; // listAsString == "abcd123"; switch(listAsString[i]) { // gibt sofort einen SegFault case '...': } }}} Danke '''Ben 14Mai10 02:13''' @Niklas + Alle: Ja, was Florin schreibt ist genau richtig. Sie sollen einfach nur testen ob bei einer nicht zulässigen Liste die leere Liste zurückkommt, wie in Aufgabe 1 gefordert. Wenn man testen wollen würde, ob jede mögliche Art der Fehlformatierungen auch genau als diese erkannt wird, würde man die Funktion ''parseListOfIntegers'' einen error code (int) zurückgeben lassen. Das ist auch nicht schwer, aber das ist hier nicht Teil der Aufgabe, ist glaube ich so schon genug Arbeit. '''Hannah 13Mai10 22:44''' @Sebastian: Ja, genau. Ist in der Aufgabe von dem Übungsblatt nicht genau spezifiziert, ich weiß, aber in der Mitteilung auf der Hauptseite habe ich es jetzt glaube ich genau gesagt, was gehen soll und was nicht. Wie gesagt, in kurz: zulässig sind Folgen von Zahlen mit genau einem Komma zwischen zwei Zahlen und beliebig Leerzeichen um die Kommata oder am Anfang und am Ende, alles andere nicht zulässig. So würde man es auch in Wirklicheit machen, weil z.B. bei Ihrem Beispiel ''3 4'' einfach unklar ist ob man das als ''34'' interpretieren soll oder als ''3,4'' und solche ambiguities sollte man immer ausschließen. '''Hannah 13Mai10 22:40''' @Hannah: D.h. "1,2,3 4,5,6" ''muss'' einen Fehler werfen? Man darf das nicht einfach als 1,2,34,5,6 interpretieren? '''Sebastian 13Mai10 22:33''' @Florin: Das sind sogenannte ''header guards'', erkläre ich in der nächsten Vorlesung. Kurz gesagt dienen Sie dazu, dass eine ''.h'' Datei nicht mehr als einmal included wird, das kann bei größeren Programmen ohne diese guards schnell passieren. Mein Linter hat gemeckert wenn ich die nicht dahin gemacht habe. Wenn Ihrer Ihre ''.h'' Datei ohne Meckern akzeptiert, auch gut, das würde mich aber wundern. '''Hannah 13Mai10 22:31''' @Dario: Zum ersten Teil der Frage: Nein, so etwas wie {{{ if ( arcobaleno == 'a' && 'b') }}} darf man nicht schreiben bzw. es würde nicht das tun was Sie erwarten. Zum zweiten Teil der Frage: Ja, Sie können annehmen dass Sie immer genau zwei Argumente bekommen, also dass immer ''argc == 3'' und die erste Folge in ''argv[1]'' steht und die zweite in ''argv[2]''. Wie man ein Programm von der Kommandozeile aufruft mit Argumenten die Leerzeichen erhalten habe ich ja schon vorher erklärt, dazu setzt man einfach Anführungszeichen um das Argument, dann kann man innerhalb des Argumentes so viele Leerzeichen schreiben wie man will und es wird immer noch als ein Argument genommen. '''Hannah 13Mai10 22:28''' @David + Manuel + Alle: Ich habe jetzt auf der Hauptseite unter Mitteilungen noch einmal genau formuliert, welche Eingabeargumente akzeptiert werden sollen und welche nicht. Nochmal in kurz: Folgen von Zahlen mit genau einem Komma zwischen zwei Zahlen und beliebig Leerzeichen um die Kommata oder am Anfang und am Ende, alles andere soll als nicht zulässig erkannt werden. Die Beispielfolgen in Ihren Fragen sind beide nicht zulässig, d.h. das Programm sollte in dem Fall meckern und die leere Folge zurückgeben, und der erweiterte Test sollte solche Fälle auch testen. '''Hannah 13Mai10 22:21''' @Niklas: Du kannst ja auf -1 testen, also ob die leeren Listen zurückkommen. Andere Frage: Was soll das {{{ #ifndef VORLESUNGEN_VORLESUNG_4_LISTPROCESSING_H_ #define VORLESUNGEN_VORLESUNG_4_LISTPROCESSING_H_ }}} in der ListProcessing.h? '''Florin 13.Mai 22:20''' Hallo, haben wir schon eine Möglichkeit kennengelernt mit gtest auf Fehlermeldungen zu testen? Das braucht man ja für die Test für 1.1 und 1.2 Gruß '''Niklas 13Mai10 22:18''' Hallo zusammen, eine technische Frage anstatt immer so zu schreiben char* arcobaleno {{{ if ( arcobaleno == 'a') && (arcobaleno == 'd' ) && (arcobaleno == 'b') }}} darf man auch so schreiben: {{{ if ( arcobaleno == 'a' && 'b' ) }}} oder gibt´s was um das kürzer und ohne "Wiederholung" zu schreiben? Bei dem Erstem Punkt der 1 Aufgabe ist so wie folgendes gemeint? Also {{{ ./ListProcessingMain 1,1,1,1,,1,1,1,1,1, 11111 }}} aber nicht so: {{{ 1,0,0, 0000 ,111111 }}} sonst wären ja drei Argumenten gell? Gruß '''Dario 13 Mai 18:43`''' @Sebastian : Besten Dank, ja es war der Zähler, der einen Wert hatte, den er eigentlich nicht haben sollte. Nur bis ich rausgefunden hatte warum. Aber jetzt hab ichs, naja zumindest das. =) '''JonathanN 13Mai10 16:18''' Wie soll dieser String ausgewertet werden? "1 4,3 5" bzw. muss man den Fall auswerten, dass in einer Zahl ein Leerzeichen stehen kann? '''Manuel 13. Mai 15:43''' Soo, ich weiß, ich weiß aber leider haben wir immernoch keine OFF-TOPIC-Section und ich dachte das muss ich mal mitteilen: http://www.youtube.com/watch?v=FIT3WlIyy1Y&NR=1&feature=fvwp. '''fry UTC+1 1273757790UTS''' Wie soll eigentlich genau mit einer Liste umgegangen werden, die Beispielsweiße so aussieht: ",,,5,7 ,3". Soll das Programm dann daraus : 0,0,0,5,7,3,-1 machen, oder die 0er weg lassen? '''David Z. 13. Mai 15:04''' @JonathanN Spontan würde ich dann sagen, dass du entweder die falsche Variable bearbeitest (unwahrscheinlich), oder dein Zähler irgendeinen Wert hat, den er nicht haben sollte. Probier doch mal: {{{ finallist[k] = -1; //Also warum dieser Befehl nicht ausgeführt wird? printf("%d %d",k,finallist[k]); }}} '''SebastianS 13Mai10 14:25''' @Sebastian, ja was in der Schleife steht wird sauber ausgeführt, nur diese Zeile nach der Schliefe iergendwie nicht. Also habe soeben noch mal was geprüft, er geht raus aus der Schleife, denn wenn ich einen printf befehl dahin setzte, der wird aus geführt, oder ist etwas an der Syntax des Befehls "faul"? '''JonathanN 13Mai10 14:12''' @Hannah: Ah, verstehe, danke :-) @JonathanN: Wird die Schleife ausgeführt? Also kommt er überhaupt zu dem Punkt? Wenn ja, sollte auch die Bedingung ausgeführt werden... Überprüf vlt nochmal deine Klammern :) '''SebastianS 13Mai10 13:22''' Kann mir jemand erklären warum beim folgenden Code der Letze Befehl nicht ausgeführ wird {{{ while (bedingung) { ein paar berechnungen } finallist[k] = -1; //Also warum dieser Befehl nicht ausgeführt wird? }}} '''JonathanN 13Mai10 13:27''' @SebastianS: Ok, ich verstehe. Es ist so, Sie dürfen immer annehmen, dass Sie genau zwei Argumente bekommen. In den strings dieser Argumente dürfen allerdings Leerzeichen stehen. Von der Kommandozeile aus geht das zum Beispiel so: ''./ListProcessingMain "1,2,3, 5,6 , 7" "8,9,0, 10"''. Das erste Argument wäre dann ''1,2,3, 5,6 , 7'' und das zweite Argument wäre ''8,9,0, 10''. '''Hannah 13Mai10 13:05''' @Hannah: Nunja, ich verstehe Aufgabe 1 so, dass wir auch aus so etwas: ''1,2,3, 5,6,7 8,9,0, 10,11'' zwei Listen generieren sollen (''1,2,3,5,6,7'' und ''8,9,0,10,11''). Allerdings würde argv bei obiger Argumentenübergabe ja folgendes liefern: ''[1] => "1,2,3,", [2] => "5,6,7", [3] => "8,9,0", [4] => "10,11"'' Somit erhalten wir ja nicht zwei sondern vier Argumente. An sich kein Problem, nur ist jetzt die Frage, ob wir in main() solche Vorkommnisse überprüfen sollen und die Strings entsprechend "zusammenkleben" sollen, oder ob wir das ganze an die Funktion weiterreichen sollen, damit die das entsprechend verarbeitet. '''SebastianS 13Mai10 12:50''' @SebastianD: Ich würde erstmal gerne verstehen, wofür Sie diesen Rückgabewert brauchen. In meiner Lösung des Übungsblattes brauche ich den nicht. Genau wie die anderen Listen soll ja auch die Ergebnisliste mit einem ''-1'' aufhören, so dass man also immer herausfinden kann wo Sie aufhört. Listen, die Ihre eigene Größe kennen ohne erst einmal durchzulaufen, machen mir in einer späteren Vorlesung. '''Hannah 13Mai10 9:50''' @Jonathan: Ja, genau, man muss die ''.h'' Datei in der ''.cpp'' includen, das macht man aber auch eigentlich immer so, wir haben es bisher bloß noch nie gebraucht, jetzt brauchen wir es zum ersten Mal. Falls Sie sich fragen, ob es korrekt ist: es ist korrekt, in der ''.h'' Datei stehen ja die Deklarationen und in der ''.cpp'' Datei die Definitionen. Das ist genauso wie erst ''int x;'' zu schreiben und dann später im Programm ''x = 4;''. Zum zweiten Teil Ihrer Frage: Ja, die Funktion soll drei Argumente haben: die beiden Eingabelisten und die Ausgabeliste, alle als ''int*''. Wobei Sie darauf achten müssen die Ausgabeliste vor dem Aufruf als Feld zu deklarieren, genau wie wir das in der Vorlesung vor den Aufrufen von ''parseListOfIntegers'' gemacht haben. '''Hannah 13Mai10 9:48''' @SebastianS: Die ''parseListOfIntegers'' Funktion soll nur eine Liste bearbeiten. Ich verstehe das Problem, dass sich dann bei Aufgabe 1 stellen soll nicht, erklären Sie es doch bitte nochmal genauer bzw. an einem konkreten Beispiel. Zum zweiten Teil der Frage: Ja, die Konvention ist, dass eine Liste bei ''-1'' zu Ende ist, egal was danach noch kommt. Genauso wie in ''C / C++'' ein string zu Ende ist wenn ein null-character kommt, egal was danach noch kommt. Und genau, die leere Liste ist die, wo gleich als erstes Element die ''-1'' kommt. '''Hannah 13Mai10 9:44''' Spricht irgendetwas gegen eine Änderung des Rückgabetyps der ''parseListOfIntegers''-Funktion? Ich würde die sonst dahingehend ändern, dass ich zurückgebe, wie viele Elemente die Liste enthält. '''SebastianD 12Mai10 23:59''' Guten Abend, dann bring ich mal gleich auch meine Fragen hier rein. Also die Variable MAX_LIST_SIZE kann ich in der .cpp Datei ja nicht nutzen wenn ich die .h nicht include, dies ist ja aber grad, das was nicht passieren soll. Diesen Wert brauch ich ja aber um zuüberprüfen, dass mein i mir nicht zu weit wegläuft, oder? Dann zum AufgabenTeil 2? Soll hier die Funktion diesmal die neue Liste als Ausgabewert haben, oder nehme ich wieder eine Liste, dann als 3. Parameter auf? Da ja die 2 Listen ja schon in der Main aufgeteilt werden, und mir also so schon 2 Parameter liefert? '''JonathanN 12Mai10 22:23''' Ist es zulässig, dass man die ''parseListOfIntegers'' Funktion derartig umbaut, dass sie als Argument alle Argumente des Programms entgegen nimmt, und diese selbst in zwei Listen aufteilt? Weil sonst sehe ich nicht, wie man Aufgabe 1 lösen soll, wo doch die Trennung schon in der ListProcessingMain durchgeführt wird? Weitere Frage: Dürfen wir beim Zusammenführen davon ausgehen, dass bei erreichen eines Elementes mit dem Wert -1 abgebrochen werden darf, da Ende der Liste? Eine Liste die mit -1 beginnt ist ja für uns eine "leere" Liste, oder? '''SebastianS 12Mai10 22:06''' [[http://www.gnu.org/software/make/manual/make.html#reference|Hier]] und [[http://www.gnu.org/software/autoconf/manual/make/Automatic-Variables.html|hier]]. Links sind in den Folien der heutigen Vorlesung entnommen. '''SebastianS 12Mai10 19:41''' Wo kann man denn den Link zu der Erklärung für den verwendeten Make Syntax finden? '''Daniel 12Mai10 18:43''' |
ListOfIntegers list1; const char* listAsString = " 1 , 5, 78 "; list1.parseFromString(listAsString); ASSERT_EQ(1, list1.getElement[0]); ASSERT_EQ(5, list1.getElement[1]); ASSERT_EQ(78, list1.getElement[2]); }}} Und folgender Fehler taucht beim Kompilieren auf: {{{ ListOfIntegersTest.cpp: In member function ‘virtual void ListOfIntegers_parseFromString_Test::TestBody()’: ListOfIntegersTest.cpp:14: error: invalid types ‘<unresolved overloaded function type>[int]’ for array subscript }}} Hat jemand eine Ahnung was das zu bedeuten hat?? '''Betim 26Mai 17:35''' Mir ist da auch noch eine Frage eingefallen: Kann ich wie im Blatt zuvor das Listenende mit -1 definieren, oder muss alles nur noch mit _size erfolgen? '''David Z. '''''' 26Mai10 ''''''16:17''' @Alle: Das mit dem ''&'' bei den Funktionsargumenten werde ich in der nächsten Vorlesung erklären. Schreiben Sie es für dieses Übungsblatt einfach hin. '''Hannah 26Mai10 01:02''' @Betim: Kopieren können Sie doch mit einer ganz normalen ''for'' Schleife, hier ist ein Beispiel: {{{ int* newElements = new int[newSize]; assert(size <= newSize); for (int i = 0; i < size; ++i) newElements[i] = _elements[i]; delete[] _elements; _elements = newElements; }}} Wie in der Vorlesung erklärt (schauen Sie sie sich vielleicht nochmal an, auch die mit den Zeigern), sind ''newElements'' und ''_elements'' in meinem Codeschnipsel oben einfach Zeiger auf Speicherplatz, wobei nach der ersten Zeile ''_elements'' auf den alten (vorher einmal allozierten) Speicherplatz zeigt, und ''newElements'' auf den gerade neu allozierten. Nach der ''for'' Schleife stehen die Elemente der Liste an beiden Stellen. Mit dem ''delete[] _elements'' wird dann der alte Speicherplatz freigegeben. Mit dem ''_elements = newElements'' zeigt jetzt der ''_elements'' Zeiger auf den neuen Speicherplatz. '''Hannah 26Mai10 00:59''' @Daniel & Veit: Ja, genau, das ist der Fehler, den ich in der Vorlesung gerne zeigen wollte, aber es gelang mir nicht. Er kann auftreten (muss aber nicht), wenn man ''delete[]'' auf einen Zeiger anwendet, der auf Speicher zeigt, der bereits frei gegeben worden ist, oder wenn man über den allozierten Bereich hinausgeschrieben hat. Deswegen muss man höllisch aufpassen mit ''new'' und ''delete''. '''Hannah 26Mai10 00:51''' @Ben: Tun Sie bei Aufgabe 1 so, als wüssten Sie noch nichts von Aufgabe 2. Und nachdem Sie Aufgabe 2 gemacht haben, brauchen Sie an Aufgabe 1 nichts mehr zu ändern. Insbesondere können Sie in den Methoden ''parseFromString'' und ''getInterleaveOf'' die Membervariable ''_capacity'' ignorieren. Wobei es natürlich sauberer wäre, Sie da zu setzen, was ja auch einfach ist, Sie können Sie einfach auf denselben Wert wie ''_size'' setzen. '''Hannah 26Mai10 00:48''' @Dario: Ein Objekt ''list'' der Klasse ''ListOfInteger'' ist ja kein Feld, also können Sie nicht einfach ''list[i]'' schreiben. Sie müssen ''list._elements[i]'' schreiben. '''Hannah 26Mai10 00:40''' Frage zur Aufgabe2: Wie kann man die alte Liste in die neue Liste kopieren? Angenommen aktuelle Liste ist zu groß, ich hol mir mehr Speicher mittels {{{_elements = new int[2*..]}}}. So und wie kopiere ich jetzt die alten Werte hier rein? Und wenn ich danach {{{delete[] _elements}}} mache, um den alten Speicherplatz freizugeben, dann ist doch der jetzige auch weg oder?? Mfg '''BetimM 26Mai o_O:35''' Komisch, ich sollte eigentlich eine Mail bekommen, wann immer hier jemand etwas postet, habe aber den ganzen Dienstag keine Benachrichtigungsmail bekommen. Ich werde mir die Fragen am Mittwoch anschauen, sorry für die Verspätung. '''Hannah 26Mai10 00:34''' {{{ interleaveListsOfIntegers(const ListOfIntegers& list1, const ListOfIntegers& list2) }}} Ah ja, diese & ist dann wohl für die Referenz zuständing. Jetzt gehts, Danke :) '''Daniel 25Mai10 22:47''' Der Fehler kommt, wenn man delete[] auf schon gelöschte Listen anwendet. Ein Workaround ist es, die Liste nach dem Löschen den Wert 0 zu geben. Dein Fehler kann aber auch auftreten, wenn du bei interleave keine Referenz sondern eine Kopie des Objektes übergibst. '''Ben 15Mai10 22:39''' @Veit dieses Problem habe ich auch, bei mir sind die Probleme schon mit dem Aufruf der Main und Eingabewerte über 3-4 Zahlen pro Liste erzeugbar (Fehler liegt wohl im interleave): {{{ ./ListProcessingMain "1,4,1,2" "4,3,2" first list is: 1,4,1,2 second list is: 4,3,2 interleved list is: 1,4,4,3,1,2,2 *** glibc detected *** ./ListProcessingMain: double free or corruption (fasttop): 0x0000000000d35030 *** ======= Backtrace: ========= /lib/libc.so.6(+0x775b6)[0x7f2fc399a5b6] /lib/libc.so.6(cfree+0x73)[0x7f2fc39a0e53] ./ListProcessingMain[0x400b55] ./ListProcessingMain[0x400a55] /lib/libc.so.6(__libc_start_main+0xfd)[0x7f2fc3941c4d] ./ListProcessingMain[0x400819] ======= Memory map: ======== 00400000-00402000 r-xp 00000000 08:05 35577934 /home/daniel/c++/uebungsblatt-5/ListProcessingMain 00601000-00602000 r--p 00001000 08:05 35577934 /home/daniel/c++/uebungsblatt-5/ListProcessingMain 00602000-00603000 rw-p 00002000 08:05 35577934 /home/daniel/c++/uebungsblatt-5/ListProcessingMain 00d35000-00d56000 rw-p 00000000 00:00 0 [heap] 7f2fbc000000-7f2fbc021000 rw-p 00000000 00:00 0 7f2fbc021000-7f2fc0000000 ---p 00000000 00:00 0 7f2fc3923000-7f2fc3a9b000 r-xp 00000000 08:05 33555453 /lib/libc-2.11.1.so 7f2fc3a9b000-7f2fc3c9b000 ---p 00178000 08:05 33555453 /lib/libc-2.11.1.so 7f2fc3c9b000-7f2fc3c9f000 r--p 00178000 08:05 33555453 /lib/libc-2.11.1.so 7f2fc3c9f000-7f2fc3ca0000 rw-p 0017c000 08:05 33555453 /lib/libc-2.11.1.so 7f2fc3ca0000-7f2fc3ca5000 rw-p 00000000 00:00 0 7f2fc3ca5000-7f2fc3cbb000 r-xp 00000000 08:05 33555487 /lib/libgcc_s.so.1 7f2fc3cbb000-7f2fc3eba000 ---p 00016000 08:05 33555487 /lib/libgcc_s.so.1 7f2fc3eba000-7f2fc3ebb000 r--p 00015000 08:05 33555487 /lib/libgcc_s.so.1 7f2fc3ebb000-7f2fc3ebc000 rw-p 00016000 08:05 33555487 /lib/libgcc_s.so.1 7f2fc3ebc000-7f2fc3f3e000 r-xp 00000000 08:05 33555503 /lib/libm-2.11.1.so 7f2fc3f3e000-7f2fc413d000 ---p 00082000 08:05 33555503 /lib/libm-2.11.1.so 7f2fc413d000-7f2fc413e000 r--p 00081000 08:05 33555503 /lib/libm-2.11.1.so 7f2fc413e000-7f2fc413f000 rw-p 00082000 08:05 33555503 /lib/libm-2.11.1.so 7f2fc413f000-7f2fc4235000 r-xp 00000000 08:05 100776696 /usr/lib/libstdc++.so.6.0.13 7f2fc4235000-7f2fc4435000 ---p 000f6000 08:05 100776696 /usr/lib/libstdc++.so.6.0.13 7f2fc4435000-7f2fc443c000 r--p 000f6000 08:05 100776696 /usr/lib/libstdc++.so.6.0.13 7f2fc443c000-7f2fc443e000 rw-p 000fd000 08:05 100776696 /usr/lib/libstdc++.so.6.0.13 7f2fc443e000-7f2fc4453000 rw-p 00000000 00:00 0 7f2fc4453000-7f2fc4473000 r-xp 00000000 08:05 33555429 /lib/ld-2.11.1.so 7f2fc4653000-7f2fc4657000 rw-p 00000000 00:00 0 7f2fc466f000-7f2fc4672000 rw-p 00000000 00:00 0 7f2fc4672000-7f2fc4673000 r--p 0001f000 08:05 33555429 /lib/ld-2.11.1.so 7f2fc4673000-7f2fc4674000 rw-p 00020000 08:05 33555429 /lib/ld-2.11.1.so 7f2fc4674000-7f2fc4675000 rw-p 00000000 00:00 0 7fffffa65000-7fffffa7a000 rw-p 00000000 00:00 0 [stack] 7fffffb2b000-7fffffb2c000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted }}} Kann mir jemand sagen, was mir dieser Fehler sagen möchte?''' Daniel 25Mai10 22:29''' {{{ [ RUN ] ListOfIntegers.getInterleaveOf *** glibc detected *** ./ListProcessingTest: free(): invalid next size (fast): 0x0000000001b38570 *** ======= Backtrace: ========= /lib/libc.so.6[0x2abd146e6dd6] /lib/libc.so.6(cfree+0x6c)[0x2abd146eb74c] ./ListProcessingTest[0x403675] ./ListProcessingTest[0x402747] /usr/local/lib/libgtest.so.0(_ZN7testing4Test3RunEv+0xaa)[0x2abd14a060ea] /usr/local/lib/libgtest.so.0(_ZN7testing8internal12TestInfoImpl3RunEv+0x108)[0x2abd14a061f8] /usr/local/lib/libgtest.so.0(_ZN7testing8TestCase3RunEv+0xbd)[0x2abd14a062bd] /usr/local/lib/libgtest.so.0(_ZN7testing8internal12UnitTestImpl11RunAllTestsEv+0x231)[0x2abd14a06541] /usr/local/lib/libgtest_main.so.0(main+0x3e)[0x2abd13cc3a7e] /lib/libc.so.6(__libc_start_main+0xfd)[0x2abd1468fabd] ./ListProcessingTest[0x4015a9] ======= Memory map: ======== 00400000-00406000 r-xp 00000000 00:14 537312 /home/veit/persoenlich/studium/ss10/cpp/repository/uebungsblatt-5/ListProcessingTest 00605000-00606000 r--p 00005000 00:14 537312 /home/veit/persoenlich/studium/ss10/cpp/repository/uebungsblatt-5/ListProcessingTest 00606000-00607000 rw-p 00006000 00:14 537312 /home/veit/persoenlich/studium/ss10/cpp/repository/uebungsblatt-5/ListProcessingTest 01b38000-01b59000 rw-p 00000000 00:00 0 [heap] 2abd13aa3000-2abd13ac2000 r-xp 00000000 fc:01 2624 /lib/ld-2.10.1.so 2abd13ac2000-2abd13ac6000 rw-p 00000000 00:00 0 2abd13cc1000-2abd13cc2000 r--p 0001e000 fc:01 2624 /lib/ld-2.10.1.so 2abd13cc2000-2abd13cc3000 rw-p 0001f000 fc:01 2624 /lib/ld-2.10.1.so 2abd13cc3000-2abd13cc4000 r-xp 00000000 fc:01 24035 /usr/local/lib/libgtest_main.so.0.0.0 2abd13cc4000-2abd13ec3000 ---p 00001000 fc:01 24035 /usr/local/lib/libgtest_main.so.0.0.0 2abd13ec3000-2abd13ec4000 r--p 00000000 fc:01 24035 /usr/local/lib/libgtest_main.so.0.0.0 2abd13ec4000-2abd13ec5000 rw-p 00001000 fc:01 24035 /usr/local/lib/libgtest_main.so.0.0.0 2abd13ec5000-2abd13fb7000 r-xp 00000000 fc:01 178424 /usr/lib/libstdc++.so.6.0.13 2abd13fb7000-2abd141b7000 ---p 000f2000 fc:01 178424 /usr/lib/libstdc++.so.6.0.13 2abd141b7000-2abd141be000 r--p 000f2000 fc:01 178424 /usr/lib/libstdc++.so.6.0.13 2abd141be000-2abd141c0000 rw-p 000f9000 fc:01 178424 /usr/lib/libstdc++.so.6.0.13 2abd141c0000-2abd141d5000 rw-p 00000000 00:00 0 2abd141d5000-2abd14257000 r-xp 00000000 fc:01 2631 /lib/libm-2.10.1.so 2abd14257000-2abd14457000 ---p 00082000 fc:01 2631 /lib/libm-2.10.1.so 2abd14457000-2abd14458000 r--p 00082000 fc:01 2631 /lib/libm-2.10.1.so 2abd14458000-2abd14459000 rw-p 00083000 fc:01 2631 /lib/libm-2.10.1.so 2abd14459000-2abd1445a000 rw-p 00000000 00:00 0 2abd1445a000-2abd14470000 r-xp 00000000 fc:01 238 /lib/libgcc_s.so.1 2abd14470000-2abd1466f000 ---p 00016000 fc:01 238 /lib/libgcc_s.so.1 2abd1466f000-2abd14670000 r--p 00015000 fc:01 238 /lib/libgcc_s.so.1 2abd14670000-2abd14671000 rw-p 00016000 fc:01 238 /lib/libgcc_s.so.1 2abd14671000-2abd147d7000 r-xp 00000000 fc:01 2627 /lib/libc-2.10.1.so 2abd147d7000-2abd149d6000 ---p 00166000 fc:01 2627 /lib/libc-2.10.1.so 2abd149d6000-2abd149da000 r--p 00165000 fc:01 2627 /lib/libc-2.10.1.so 2abd149da000-2abd149db000 rw-p 00169000 fc:01 2627 /lib/libc-2.10.1.so 2abd149db000-2abd149e0000 rw-p 00000000 00:00 0 2abd149e0000-2abd14a1b000 r-xp 00000000 fc:01 24033 /usr/local/lib/libgtest.so.0.0.0 2abd14a1b000-2abd14c1b000 ---p 0003b000 fc:01 24033 /usr/local/lib/libgtest.so.0.0.0 2abd14c1b000-2abd14c1c000 r--p 0003b000 fc:01 24033 /usr/local/lib/libgtest.so.0.0.0 2abd14c1c000-2abd14c1d000 rw-p 0003c000 fc:01 24033 /usr/local/lib/libgtest.so.0.0.0 2abd14c1d000-2abd14c1f000 rw-p 00000000 00:00 0 2abd18000000-2abd18021000 rw-p 00000000 00:00 0 2abd18021000-2abd1c000000 ---p 00000000 00:00 0 7fff40ab1000-7fff40ac6000 rw-p 00000000 00:00 0 [stack] 7fff40bef000-7fff40bf0000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted make: *** [test] Error 134 }}} Werde aus dieser Fehlerausgabe von GTest nicht schlau. Das Programm funktioniert gut, wenn ich es einfach so teste, also per Main-Funktion. Die Testfälle könnten natuerlich den Fehler beherbergen, aber ich wusste nicht ob man die hier posten darf oder nicht. Wo muss ich suchen? '''Veit 25Mai10 22:16''' Hallo, ich habe mehrere Fragen zum Blatt: 1. Soll die Aufgabe 1 mit den Methoden aus Aufgabe 2 gelöst werden (spätestens wenn man Aufgabe 2 implementiert)? 1. Soll in Aufgabe 1 (wenn nicht die push/pop Methoden genutzt werden) auch _capacity angepasst werden? 1. Soll, falls Punkt 2 eintritt, auch die Regel mit dem verdoppeln der Kapazität greifen? 1. Beist sich das nicht, wenn man push_back mit pop_back testet und umgekehrt? Weil scheint mir irgendwie "komisch", dass der pop_back Test vom (ungetesteten) push_back abhängt und umgekehrt. Wenn theoretisch was schief läuft, weiß ich ja nicht woran es lag. (Ok hier sind die Methoden "einfach", aber bei komplexeren Dingen könnte das doch ein problem geben) '''Ben 25Mai10 20:39''' @Florin: danke für die Antwort, ich habe mich ein bisschen über Referenzen dokumentiert und habe gelesen ,dass es also fast wie eine zweite name(oder copie) für die Variable ist. Ich bin davon ausgegangen ,dass einen Code wie folgendes stimmt. Wenn ich meine interleavefunktion ausrufe. {{{ void ListOfIntegers::interLeaveListOfIntegers(const ListOfIntegers& list1, const ListOfIntegers& list2) while ((ck1 == false) || (ck2 == false)) { if (!ck1 && _list1[i] == -1) }}} Außerdem habe es gemacht sowie du gesagt hast mit der h.datei ecc. aber kriege diese Fehlermeldung: {{{ ListProcessing.cpp: In member function ‘void ListOfIntegers::interLeaveListOfIntegers(ListOfIntegers&, ListOfIntegers&)’: ListProcessing.cpp:36: error: no match for ‘operator[]’ in ‘_list1[i]’ ListProcessing.cpp:43: error: no match for ‘operator[]’ in ‘_list2[i]’ }}} '''Dario 25Mai10 19:23''' @Dario: Du übergibst jetzt keine int* mehr, sondern zwei ListOfIntegers. Also muss in deiner .h-Datei stehen: {{{void interLeaveListOfIntegers(const ListOfIntegers& list1, const ListOfIntegers& list2);)}}} Grüße, '''Florin 25Mai10 18:17''' Hallo, ich habe ein kleines Problem: {{{ ListProcessingMain.cpp: In function ‘int main(int, char**)’: ListProcessingMain.cpp:32: error: no matching function for call to ‘ListOfIntegers::interLeaveListOfIntegers( ListOfIntegers&, ListOfIntegers&)’ ./ListProcessing.h:30: note: candidates are: void ListOfIntegers::interLeaveListOfIntegers(int*, int*) }}} das ist die Fehlermeldung. P.S. was heisst diese & am Ende von ListOfIntegers? Meine interleave Funktion {{{ void interLeaveListOfIntegers(int* list1, int* list2) }}} und die Mainfunktion {{{ lista.interLeaveListOfIntegers(list1, list2); }}} Ich verstehe nicht wie ich die Parameter anpassen soll.. list1 und list2 sind die zwei Objekten-elements (oder listen) die man aus char* erzeugt und haben schon eine definierte _size ohne Maxima.. Gruß '''Dario 25Mai10 14:42''' @Niklas: Ja, stimmt, schreiben Sie sich einfach eine ''get(int i)'' Funktion. Oder benutzen sie ''pop_back()'' wie von Sebastian vorgeschlagen, aber ''get'' wäre schon natürlicher. Eine dritte Alternative wäre in ''ListOfIntegers.h'' vor die Deklaration von ''parseFromString'' folgende Zeile zu schreiben {{{ FRIEND_TEST(ListOfIntegersTest, parseFromString) }}} Das habe ich in der Vorlesung nicht erklärt, aber Sie dürfen es gerne benutzen, weil es eigentlich die Methode der Wahl ist. Damit geben Sie dem ''TEST(ListOfIntegersTest, parseFromString)'' die Rechte, auf die Membervariablen eines ''ListOfInteger'' Objektes zuzugreifen, insbesondere die ''_elements''. '''Hannah 24Mai10 21:42''' Das lässt sich mittels der ''pop_back'' Methode realisieren. '''SebastianD 24Mai10 16:47''' Ok, noch eine Frage zu den Tests: Mir fällt irgendwie kein sinnvoller Test für die parse Funktion ein, der nicht die einzelnen Einträge der Liste anschauen muss. Dann bräuchte ich aber wieder eine Get() Funktion. Stehe ich da auf dem Schlauch oder ist das wirklich ein Problem? '''Niklas 24Mai 15:59''' @Dario: Der ''constructor'' wird aufgerufen, wenn das Objekt deklariert und damit effektiv im Speicher erzeugt (konstruiert = constructed) wird. Aufgabe des Konstruktors ist es typischerweise, die Membervariablen des Objektes geeignet zu initialisieren. Der ''destructor'' wird aufgerufen, kurz bevor das Objekt aus dem Speicher gelöscht (zerstört = destructed) wird. Die Aufgabe des Destruktors ist typischerweise Aufräumen und schauen, dass aller Speicher der zu Lebzeiten des Objektes alloziert wurde auch wieder freigeben wird. Von daher schon nicht schlecht die Namen. '''Hannah 24Mai10 14:36''' @Niklas: Erstmal keine Änderung gegenüber vorher, also ein ''TEST'' pro Methode und der heißt dann etwa ''TEST(ListOfIntegersTest, parseFromString)''. '''Hannah 24Mai10 14:32''' Hallo, wenn ich das richtig verstanden habe werden Tests in Gtest ja so erstellt TEST(<Filename>, <Functionname>). Wie sieht das denn mit Klassen ordentlich aus? Checkt man da alle Funktionen in einem Test? Gruß '''Niklas 24Mai 14:18'''' Also ich wollte nur eine kurze Frage stellen. Constructors und Deconstructors sind im Endeffekt nichts anders als Funktionen , die automatisch aufgerufen werden bzw. am Anfang der Klasse und eine am Ende der Klasse, wenn ich ein Objekt erstelle. Aber was wird "erzeugt und eliminiert"? Hätte nicht der Erfinder von c++ anders nennen können? :D Gruß '''Dario 23Mai 16:06''' @Heinke: Nach dem Aufruf von ''parseFromString'' soll ''_size'' schon auf dem richtigen Wert stehen. Sie müssen den Wert da ja sowieso schon wissen, damit Sie, wie in der Aufgabenstellung gefordert, genau die richtige Menge Platz für den ''_elements'' pointer allozieren können. Wie Sie das machen, dafür gibt es viele Möglichkeiten. Eine davon ist, einfach vorab die Anzahl der Kommas im Argument ''listAsString'' zu zählen. Wenn das Argument eine korrekt formatierte Liste enthält ist die Anzahl der Elemente ja einfach die Anzahl der Kommas plus eins. Und wenn Sie beim Parsen der Liste herausfinden, dass Sie nicht korrekt formatiert ist, dann geben Sie den Platz einfach wieder frei und setzen ''size = 0'', weil in dem Fall ja (nach wie vor) die leere Liste zurückgegeben werden soll. Eine andere Möglichkeit wäre, vorab einfach Platz für soviel ''int''s zu reserviere wie das Argument ''listAsString'' lang ist (d.h. wieviele Zeichen es hat). Denn mehr Zahlen können ja nicht drin stehen. Am Ende vom Parsen wissen Sie ja dann wieviele ''int''s tatsächlich drin standen und dann können Sie die genau passende Menge Platz allozieren und einmal umkopieren. So, das waren jetzt zwei Möglichkeiten, die mir spontan einfallen, aber es gibt bestimmt auch noch viele andere. '''Hannah 23Mai10 14:23''' Kann ich einfach ne weitere Methode schreiben, die die Länge der Liste zurück gibt, die sie haben wird, wenn sie geparsed ist (also die orkommenden Zahlen zählt) und diesen Wert dann den Methoden für interleave und parse geben, damit _size entsprechend gesetzt wird? Oder gibts noch einen supergenialen Weg, der mir nur noch nicht eingefallen ist, weil ich nicht supergenial bin? '''Heinke 23Mai10 14:14''' @Roman: Ja, richtig, kann praxisrelevant sein, muss aber nicht. Vielleicht kommen wir ja irgendwann gegen Ende des Semesters dazu. Freut mich auf jeden Fall, dass Sie sich für diese weiterführenden Konzepte interessieren und sich da offenbar auch schon sehr gut auskennen. '''Hannah 20Mai10 21:44''' @Hannah: Ich wollte auf gar keinen Fall dogmatisch rüber kommen, aber als rein theoretisch würde ich gerade das KISS-Prinzip nicht sehen. Klassen die mehr als nur die essentiellen Eigenschaften/Methoden eines Objektes implementieren haben auf lange Sicht praxisrelevante Nachteile die mMn nicht vernachlässigbar sind, da die Klassen riesig werden und unintuitiv. Auch könnte man die getInterleaveOf Methode in der ListHandler Klasse abstrahieren und z.B. unabhängig von dem genauen Typ der Liste machen (z.B. per interface). Derjenige der seine interleaveWith Methode in der Liste selber implementiert kann diese Methode nun für jede andere Form von Listen kopieren (und bei irgendwelchen Änderungen ALLE Methoden ändern..). Dass das über den momentanten Stand in der Vorlesung hinausgeht is mir klar, aber die Praxis Relevanz sehe ich da trotzdem ganz deutlich. '''RomanW 20Mai10 21:32''' @Roman: Mit "keine Methode ... sein sollte" und "ausgelagert sein sollte" wäre ich vorsichtig. Es gibt viele schöne Konzepte in der objekt-orientierten Welt, nur was die dann mit der Praxis zu tun haben, ist oft fraglich. Ich mache in der Vorlesung ganz dezidiert Programmieren in C++ aus der Praxis für die Praxis und so soll es sein und so soll es auch bleiben. Weiterführende Konzepte werden wir genau dann lernen und anwenden, wenn wir sie wirklich brauchen, vorher nicht. '''Hannah 20Mai10 21:07''' @SebastianD: Die Konfusion kommt höchstwahrscheinlich daher, dass interleaveWith (imo!) streng genommen keine Methode der ListOfInteger Klasse sein sollte, sondern (gemäß dem KISS-Prinzip) in einer Art ListHandler Klasse ausgelagert sein sollte. Diese würde dann eine Methode a la ListOfIntegers getInterleaveOf(ListOfIntegers list1, ListOfIntegers list2) bereitstellen und die neue Liste zurückgeben. '''RomanW 20Mai10 20:53''' @Ben: ''private'' bedeutet nicht Instanz-, sondern Klassensichtbarkeit. Du kannst also innerhalb deiner Listenklasse auf die (private) Member anderer Instanzen der Listenklasse zugreifen. '''SebastianD 20Mai10 20:19''' @Hannah: Es ging mir prinzipiell nur um die Interleave Methode, da habe ich von außen keinerlei Zugriff auf die Listen in den übergebenen Objekten, da _size und _elements private ist. Somit muss man entweder get/set Methoden erstellen um die Werte einzelt auslesen zu können, die Klassenvariablen public machen oder die Methoden vom zweiten Teil nutzen (push_back/pop_back), wobei jedoch direkt bei der leeren Liste ein assert kommt, den ich nicht abfangen kann. Es war von mir weniger eine Frage sondern mehr eine Feststellung :) '''Ben 20Mai10 19:38''' @Ben: Auf die Membervariablen ''_size'' und ''_elements'' brauchen Sie für dieses Übungsblatt keinen Zugriff von außerhalb der Klasse. Deswegen können Sie auch ''private'' sein (sollten Sie sowieso) und Sie brauchen auch keine spezielle ''get'' oder ''set'' Methode. Nur die Memberfunktionen brauchen Zugriff auf diese Membervariablen, und den haben Sie ja sowieso, d.h. Sie können z.B. in ''parseListOfIntegers'' einfach schreiben ''_size = listSize'' oder sowas. '''Hannah 20Mai10 19:28''' @Heinke: Ja, genau, siehe mein code snippet in der Antwort an SebastianD. '''Hannah 20Mai10 19:23''' @SebastianD: Berechtigte Frage. Ich würde es so machen: {{{ void ListOfIntegers::getInterleaveOf(const ListOfIntegers& list1, const ListOfIntegers& list2); }}} und dann in der ''main'' Funktion: {{{ ListOfInteger list1; ListOfInteger list2; list1.parseFromString(list1AsString); list2.parseFromString(list2AsString); list1.print("Input list 1 : "); list2.print("Input list 2 : "); ListOfInteger result; result.getInterleaveOf(list1, list2); result.print("Result list : "); }}} Die Version von Ben ist aber auch eine Variante die man in diesem Kontext öfter sieht. Ich würde die Methode dann allerdings ''interleaveWith'' nennen, man sollte das bei der objekt-orientierten Programmierung immer wie einen (einfachen) Satz lesen könnten. Die Variante hat halt den Nachteil, dass dann die eine Liste überschrieben wird, deswegen gefällt mir die oben besser. '''Hannah 20Mai10 19:14''' @Hannah: Ah. Verstehe. Mit anderen Worten, ich muss also für jede Liste eine Instanz des Objektes erstellen. Oder sehe ichs immer noch falsch? '''Heinke 20Mai10 18:23''' Für mich klingt es nach Version 1: {{{ ListProcessing list1; [...] ListProcessing list2; [...] list1.interleave(list2); }}} Nur muss man sich dann imho Gedanken über die Sichtbarkeit von _size und _elements machen oder eine set/get Methode implementiern...'''Ben 20Mai10 17:36''' Ich bin mir im Unklaren über die genaue Funktionsweise der neuen Interleave-Methode, da mir selbst spontan mehrere verschiedene Möglichkeiten einfallen:<<BR>> 1. void interleaveWith(ListOfIntegers list); // Die Elemente dieser Liste werden mit der Argumentliste vermischt (oder was auch immer).<<BR>> 2. ListOfIntegers interleaveWith(ListOfIntegers list); // siehe 1., nur dass die Argumente jetzt in einer neuen Liste gespeichert und diese zurück gegeben wird.<<BR>> 3. void interleave(ListOfIntegers list1, ListOfIntegers list2); // Speichert die Elemente der beiden Argumentlisten vermischt in dieser Liste (Liste vorher leeren?).<<BR>> 4. ListOfIntegers interleave(ListOfIntegers list1, ListOfIntegers list2); // Idealerweise sogar static. Speichert die Elemente der beiden Argumentlisten vermischt in einer neuen Liste und gibt diese zurück.<<BR>> 5. void interleaveWith(ListOfIntegers result, ListOfIntegers list); // C-Style. Man übergibt außerdem eine Liste, in der die Elemente dann gespeichert werden sollen.<<BR>> 6. ...<<BR>> Welche davon? '''SebastianD 20Mai10 14:24''' @Heinke: Für Aufgabe 1 vom neuen Übungsblatt soll das Programm exakt dasselbe machen, die Ihr Programm vom 4. Übungsblatt, nur soll das Programm mit Klassen realisiert sein, wie in der Vorlesung vorgemacht, und die Felder (die jetzt Membervariablen sind), sollen keine fixe Größe ''MAX_LIST_SIZE'' mehr haben, sondern genau die Größe, die benötigt wird. Beantwortet das Ihre Frage? '''Hannah 20Mai10 12:46''' Verstehe ich das richtig: Der Benutzer soll ./ListProcessingMain "1,1,1,1" "2,2,2,2,2" aufrufen und anschließend sollen die Listen intern geparsed, interleaved und als array im Objekt gespeichert werden? '''Heinke 20Mai10 9:28 ''' |
Fragen und Kommentare zur 5. Vorlesung / zum 5. Übungsblatt
Also ich habe die _capacity variable im Dekonstructor benutzt und damit brauche ich auch nicht die ganze Geschichte von der Verdopplung von _capacity.
Gruß Dario 27Mai10 21:51
@Robin: das kommt drauf an, wie du deine Liste initialisierst. Ich initialisiere z.B. mit NULL somit ist meine _capacity am anfang 0. Im push_back wird die Variable dann beim ersten Element auf 1 gesetzt und bei weiteren Elementen bei größerem Platzbedarf immer verdoppelt (if/else). Die Variable braucht man tatsächlich "nur" im Konstruktor und im push_back(). _capacity muss man erhöhen, wenn die Kapazität voll ist, also _size genau so groß ist wie _capacity und dann ein neues Element hinzu kommen soll. Hoffe, dass konnte helfen Gruß Ben 27.Mai10 21:43
Eine Frage zur der Membervariable _capacity und zwar steht in der Aufgabenstellung : Initialisieren Sie diese Variable im Konstruktor geeignet. Aber was soll dieses "geeignet"? Im Konstruktor hat man die size der Liste noch nicht, deshalb kann man der Variable _capacity diesen Wert nicht zu weisen. Sollen wir nun einen Wert willkürlich wählen z.B: 50, oder wie ist das zu verstehen? Braucht man für die Funktion int pop_back() auch diese Variable _capacity. Sorry aber das mit dieser Variable verursacht bei mir für Schwierigkeiten. So wie ich es jetzt verstanden habe, braucht man die Variable nur in der push_back(int x), und zwar soll dann die _capacity erhöht werden, wenn man die _size überschreitet. Was auch logisch erscheint, denn wenn man ein Integer hinzufügen will, aber die Liste bereits voll ist, so muss man neuen Speicher anfragen, die alte Liste kopieren und dann den Wert von push_back hinzufügen. Danach soll man den alten Speicher, den man nicht mehr brauch wieder freigeben, richtig? Hoffe mir kann jemand helfen. Gruß Robin 27 Main 21:22
Etwas Allgemeineres: Kann es sein, dass Hudson ein Problem mit unseren Ferien hat (es klagt jedenfalls, wenn man die 0 stehen lässt, weil es keinen Ordner uebungsblatt-6 gibt...)? SebastianS 27Mai10 02:33
@Dario Immer wenn du ein neues Element beim "parsen" oder beim "pushen" in die Liste schreibst, erhöhst du _size um 1. Ben 26Mai10
Die push- und pop_back Funktionen werden auf ein Objekt vom Typ ListOfIntegers aufgerufen (da ist also logischerweise ein Array mit Integern drin, nämlich _elements). Die _size (und manchmal auch die _capacity) musst du beim Aufruf der Funktionen entsprechend anpassen. SebastianD 26Mai10 22:04
Danke aber was ich nicht wirklich verstehe ist, wie man die Size von der Liste "messen" kann. Bei Parselistofintegers habe ich einfach die Anzahl von komma gezählt, aber hier geht´s nicht. Soll ich davon ausgehen ,dass die List in der Push oder pop function schon geparsed sind oder können auch String sein? Dario 26Mai10 21:50
@Dario Du solltest am Ende 3 Klassenvariablen haben: 1. _elements, diese enthält die Liste, 2. _size, diese enthält die Anzahl der Elemente und 3. _capacity, diese enthält die Größe deines allokierten Speichers.
_elements = new int[20]; _elements[0] = 7; _elements[1] = 8; _elements[2] = 2; // nun müssen die anderen Variablen folgende Werte haben: _size = 3; _capacity = 20;
Gruß Ben 26Mai10 21:47
Ich habe so gemacht , weil ich nicht ganau weiß , wie man die Größe von meinem _element in Push oder pop_backfunktion bestimmen kann. Dario 26Mai10 20:16
@Dario: Das verstehe ich nicht, warum wollen Sie der push_back oder pop_back Funktion ein Listenobjekt als Argument mitgeben? Die Methoden werden doch immer gerade von einem Listenobjekt aufgerufen, so wie z.B. in ListOfIntegers list; gefolgt von list.push_back(5). Die _capacity Variable brauchen Sie deswegen, weil es einmal die aktuelle Anzahl von Elementen in der Liste gibt (size) und einmal, für wieviel Elemente Platz alloziert wurde (_capacity). Das macht man deswegen, damit man nicht nach jedem push_back neu Platz allozieren und umkopieren muss, sondern nur ab und zu. Genauer gesagt kriegt man so eine durchschnittliche (amortisierte) Laufzeit für push_back, die unabhängig von der Listenlänge ist. Hannah 26Mai10 20:21
@Betim: Ja, wie Dario sagt, Ihr getElement ist ja eine ganz normale Funktion / Methode, und die ruft man mit runden Klammern auf, nicht mit eckigen. Hannah 26Mai10 20:16
@David: Ja, wie in der Vorlesung vorgemacht, soll man die -1 weglassen. Braucht man ja auch nicht mehr wenn man die _size hat. Hannah 26Mai10 20:15
Bei der 2te Aufgabe darf man die push_back und pop_back mit einem zusätzlichem Argument implementieren? damit brauche ich nicht mehr die _capacity variable. Wie folgendes:
// die list 1 ist schon geparsed. ListOfIntegers push; push.push_back( &list1 , x)
Dasselbe auch für pop_back. Grüße Dario 26Mai10 20:00
@Betim.Probier es einfach anstatt[] mit () klammer also getElement(1) anstatt getElement [0] Dario 26Mai10 17:52
@David: Ich hab das mit -1 entfernt und benutze stattdessen _size. Ich glaube auch, man soll das so machen. Aber mal ne andere Frage: Nachdem das mit FRIEND_TEST nicht funktioniert hat, habe ich mir eine getElement(int n) Methode geschrieben, die eben das n-te Element zurückgibt. Die sieht so aus:
int ListOfIntegers::getElement(int n) { assert(n >= 0); return _elements[n]; }
Der Test schaut so aus:
TEST(ListOfIntegers, parseFromString) { ListOfIntegers list1; const char* listAsString = " 1 , 5, 78 "; list1.parseFromString(listAsString); ASSERT_EQ(1, list1.getElement[0]); ASSERT_EQ(5, list1.getElement[1]); ASSERT_EQ(78, list1.getElement[2]);
Und folgender Fehler taucht beim Kompilieren auf:
ListOfIntegersTest.cpp: In member function ‘virtual void ListOfIntegers_parseFromString_Test::TestBody()’: ListOfIntegersTest.cpp:14: error: invalid types ‘<unresolved overloaded function type>[int]’ for array subscript
Hat jemand eine Ahnung was das zu bedeuten hat?? Betim 26Mai 17:35
Mir ist da auch noch eine Frage eingefallen: Kann ich wie im Blatt zuvor das Listenende mit -1 definieren, oder muss alles nur noch mit _size erfolgen? David Z. 26Mai10 16:17
@Alle: Das mit dem & bei den Funktionsargumenten werde ich in der nächsten Vorlesung erklären. Schreiben Sie es für dieses Übungsblatt einfach hin. Hannah 26Mai10 01:02
@Betim: Kopieren können Sie doch mit einer ganz normalen for Schleife, hier ist ein Beispiel:
int* newElements = new int[newSize]; assert(size <= newSize); for (int i = 0; i < size; ++i) newElements[i] = _elements[i]; delete[] _elements; _elements = newElements;
Wie in der Vorlesung erklärt (schauen Sie sie sich vielleicht nochmal an, auch die mit den Zeigern), sind newElements und _elements in meinem Codeschnipsel oben einfach Zeiger auf Speicherplatz, wobei nach der ersten Zeile _elements auf den alten (vorher einmal allozierten) Speicherplatz zeigt, und newElements auf den gerade neu allozierten. Nach der for Schleife stehen die Elemente der Liste an beiden Stellen. Mit dem delete[] _elements wird dann der alte Speicherplatz freigegeben. Mit dem _elements = newElements zeigt jetzt der _elements Zeiger auf den neuen Speicherplatz. Hannah 26Mai10 00:59
@Daniel & Veit: Ja, genau, das ist der Fehler, den ich in der Vorlesung gerne zeigen wollte, aber es gelang mir nicht. Er kann auftreten (muss aber nicht), wenn man delete[] auf einen Zeiger anwendet, der auf Speicher zeigt, der bereits frei gegeben worden ist, oder wenn man über den allozierten Bereich hinausgeschrieben hat. Deswegen muss man höllisch aufpassen mit new und delete. Hannah 26Mai10 00:51
@Ben: Tun Sie bei Aufgabe 1 so, als wüssten Sie noch nichts von Aufgabe 2. Und nachdem Sie Aufgabe 2 gemacht haben, brauchen Sie an Aufgabe 1 nichts mehr zu ändern. Insbesondere können Sie in den Methoden parseFromString und getInterleaveOf die Membervariable _capacity ignorieren. Wobei es natürlich sauberer wäre, Sie da zu setzen, was ja auch einfach ist, Sie können Sie einfach auf denselben Wert wie _size setzen. Hannah 26Mai10 00:48
@Dario: Ein Objekt list der Klasse ListOfInteger ist ja kein Feld, also können Sie nicht einfach list[i] schreiben. Sie müssen list._elements[i] schreiben. Hannah 26Mai10 00:40
Frage zur Aufgabe2: Wie kann man die alte Liste in die neue Liste kopieren? Angenommen aktuelle Liste ist zu groß, ich hol mir mehr Speicher mittels _elements = new int[2*..]. So und wie kopiere ich jetzt die alten Werte hier rein? Und wenn ich danach delete[] _elements mache, um den alten Speicherplatz freizugeben, dann ist doch der jetzige auch weg oder?? Mfg BetimM 26Mai o_O:35
Komisch, ich sollte eigentlich eine Mail bekommen, wann immer hier jemand etwas postet, habe aber den ganzen Dienstag keine Benachrichtigungsmail bekommen. Ich werde mir die Fragen am Mittwoch anschauen, sorry für die Verspätung. Hannah 26Mai10 00:34
interleaveListsOfIntegers(const ListOfIntegers& list1, const ListOfIntegers& list2)
Ah ja, diese & ist dann wohl für die Referenz zuständing. Jetzt gehts, Danke Daniel 25Mai10 22:47
Der Fehler kommt, wenn man delete[] auf schon gelöschte Listen anwendet. Ein Workaround ist es, die Liste nach dem Löschen den Wert 0 zu geben. Dein Fehler kann aber auch auftreten, wenn du bei interleave keine Referenz sondern eine Kopie des Objektes übergibst. Ben 15Mai10 22:39
@Veit dieses Problem habe ich auch, bei mir sind die Probleme schon mit dem Aufruf der Main und Eingabewerte über 3-4 Zahlen pro Liste erzeugbar (Fehler liegt wohl im interleave):
./ListProcessingMain "1,4,1,2" "4,3,2" first list is: 1,4,1,2 second list is: 4,3,2 interleved list is: 1,4,4,3,1,2,2 *** glibc detected *** ./ListProcessingMain: double free or corruption (fasttop): 0x0000000000d35030 *** ======= Backtrace: ========= /lib/libc.so.6(+0x775b6)[0x7f2fc399a5b6] /lib/libc.so.6(cfree+0x73)[0x7f2fc39a0e53] ./ListProcessingMain[0x400b55] ./ListProcessingMain[0x400a55] /lib/libc.so.6(__libc_start_main+0xfd)[0x7f2fc3941c4d] ./ListProcessingMain[0x400819] ======= Memory map: ======== 00400000-00402000 r-xp 00000000 08:05 35577934 /home/daniel/c++/uebungsblatt-5/ListProcessingMain 00601000-00602000 r--p 00001000 08:05 35577934 /home/daniel/c++/uebungsblatt-5/ListProcessingMain 00602000-00603000 rw-p 00002000 08:05 35577934 /home/daniel/c++/uebungsblatt-5/ListProcessingMain 00d35000-00d56000 rw-p 00000000 00:00 0 [heap] 7f2fbc000000-7f2fbc021000 rw-p 00000000 00:00 0 7f2fbc021000-7f2fc0000000 ---p 00000000 00:00 0 7f2fc3923000-7f2fc3a9b000 r-xp 00000000 08:05 33555453 /lib/libc-2.11.1.so 7f2fc3a9b000-7f2fc3c9b000 ---p 00178000 08:05 33555453 /lib/libc-2.11.1.so 7f2fc3c9b000-7f2fc3c9f000 r--p 00178000 08:05 33555453 /lib/libc-2.11.1.so 7f2fc3c9f000-7f2fc3ca0000 rw-p 0017c000 08:05 33555453 /lib/libc-2.11.1.so 7f2fc3ca0000-7f2fc3ca5000 rw-p 00000000 00:00 0 7f2fc3ca5000-7f2fc3cbb000 r-xp 00000000 08:05 33555487 /lib/libgcc_s.so.1 7f2fc3cbb000-7f2fc3eba000 ---p 00016000 08:05 33555487 /lib/libgcc_s.so.1 7f2fc3eba000-7f2fc3ebb000 r--p 00015000 08:05 33555487 /lib/libgcc_s.so.1 7f2fc3ebb000-7f2fc3ebc000 rw-p 00016000 08:05 33555487 /lib/libgcc_s.so.1 7f2fc3ebc000-7f2fc3f3e000 r-xp 00000000 08:05 33555503 /lib/libm-2.11.1.so 7f2fc3f3e000-7f2fc413d000 ---p 00082000 08:05 33555503 /lib/libm-2.11.1.so 7f2fc413d000-7f2fc413e000 r--p 00081000 08:05 33555503 /lib/libm-2.11.1.so 7f2fc413e000-7f2fc413f000 rw-p 00082000 08:05 33555503 /lib/libm-2.11.1.so 7f2fc413f000-7f2fc4235000 r-xp 00000000 08:05 100776696 /usr/lib/libstdc++.so.6.0.13 7f2fc4235000-7f2fc4435000 ---p 000f6000 08:05 100776696 /usr/lib/libstdc++.so.6.0.13 7f2fc4435000-7f2fc443c000 r--p 000f6000 08:05 100776696 /usr/lib/libstdc++.so.6.0.13 7f2fc443c000-7f2fc443e000 rw-p 000fd000 08:05 100776696 /usr/lib/libstdc++.so.6.0.13 7f2fc443e000-7f2fc4453000 rw-p 00000000 00:00 0 7f2fc4453000-7f2fc4473000 r-xp 00000000 08:05 33555429 /lib/ld-2.11.1.so 7f2fc4653000-7f2fc4657000 rw-p 00000000 00:00 0 7f2fc466f000-7f2fc4672000 rw-p 00000000 00:00 0 7f2fc4672000-7f2fc4673000 r--p 0001f000 08:05 33555429 /lib/ld-2.11.1.so 7f2fc4673000-7f2fc4674000 rw-p 00020000 08:05 33555429 /lib/ld-2.11.1.so 7f2fc4674000-7f2fc4675000 rw-p 00000000 00:00 0 7fffffa65000-7fffffa7a000 rw-p 00000000 00:00 0 [stack] 7fffffb2b000-7fffffb2c000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted
Kann mir jemand sagen, was mir dieser Fehler sagen möchte? Daniel 25Mai10 22:29
[ RUN ] ListOfIntegers.getInterleaveOf *** glibc detected *** ./ListProcessingTest: free(): invalid next size (fast): 0x0000000001b38570 *** ======= Backtrace: ========= /lib/libc.so.6[0x2abd146e6dd6] /lib/libc.so.6(cfree+0x6c)[0x2abd146eb74c] ./ListProcessingTest[0x403675] ./ListProcessingTest[0x402747] /usr/local/lib/libgtest.so.0(_ZN7testing4Test3RunEv+0xaa)[0x2abd14a060ea] /usr/local/lib/libgtest.so.0(_ZN7testing8internal12TestInfoImpl3RunEv+0x108)[0x2abd14a061f8] /usr/local/lib/libgtest.so.0(_ZN7testing8TestCase3RunEv+0xbd)[0x2abd14a062bd] /usr/local/lib/libgtest.so.0(_ZN7testing8internal12UnitTestImpl11RunAllTestsEv+0x231)[0x2abd14a06541] /usr/local/lib/libgtest_main.so.0(main+0x3e)[0x2abd13cc3a7e] /lib/libc.so.6(__libc_start_main+0xfd)[0x2abd1468fabd] ./ListProcessingTest[0x4015a9] ======= Memory map: ======== 00400000-00406000 r-xp 00000000 00:14 537312 /home/veit/persoenlich/studium/ss10/cpp/repository/uebungsblatt-5/ListProcessingTest 00605000-00606000 r--p 00005000 00:14 537312 /home/veit/persoenlich/studium/ss10/cpp/repository/uebungsblatt-5/ListProcessingTest 00606000-00607000 rw-p 00006000 00:14 537312 /home/veit/persoenlich/studium/ss10/cpp/repository/uebungsblatt-5/ListProcessingTest 01b38000-01b59000 rw-p 00000000 00:00 0 [heap] 2abd13aa3000-2abd13ac2000 r-xp 00000000 fc:01 2624 /lib/ld-2.10.1.so 2abd13ac2000-2abd13ac6000 rw-p 00000000 00:00 0 2abd13cc1000-2abd13cc2000 r--p 0001e000 fc:01 2624 /lib/ld-2.10.1.so 2abd13cc2000-2abd13cc3000 rw-p 0001f000 fc:01 2624 /lib/ld-2.10.1.so 2abd13cc3000-2abd13cc4000 r-xp 00000000 fc:01 24035 /usr/local/lib/libgtest_main.so.0.0.0 2abd13cc4000-2abd13ec3000 ---p 00001000 fc:01 24035 /usr/local/lib/libgtest_main.so.0.0.0 2abd13ec3000-2abd13ec4000 r--p 00000000 fc:01 24035 /usr/local/lib/libgtest_main.so.0.0.0 2abd13ec4000-2abd13ec5000 rw-p 00001000 fc:01 24035 /usr/local/lib/libgtest_main.so.0.0.0 2abd13ec5000-2abd13fb7000 r-xp 00000000 fc:01 178424 /usr/lib/libstdc++.so.6.0.13 2abd13fb7000-2abd141b7000 ---p 000f2000 fc:01 178424 /usr/lib/libstdc++.so.6.0.13 2abd141b7000-2abd141be000 r--p 000f2000 fc:01 178424 /usr/lib/libstdc++.so.6.0.13 2abd141be000-2abd141c0000 rw-p 000f9000 fc:01 178424 /usr/lib/libstdc++.so.6.0.13 2abd141c0000-2abd141d5000 rw-p 00000000 00:00 0 2abd141d5000-2abd14257000 r-xp 00000000 fc:01 2631 /lib/libm-2.10.1.so 2abd14257000-2abd14457000 ---p 00082000 fc:01 2631 /lib/libm-2.10.1.so 2abd14457000-2abd14458000 r--p 00082000 fc:01 2631 /lib/libm-2.10.1.so 2abd14458000-2abd14459000 rw-p 00083000 fc:01 2631 /lib/libm-2.10.1.so 2abd14459000-2abd1445a000 rw-p 00000000 00:00 0 2abd1445a000-2abd14470000 r-xp 00000000 fc:01 238 /lib/libgcc_s.so.1 2abd14470000-2abd1466f000 ---p 00016000 fc:01 238 /lib/libgcc_s.so.1 2abd1466f000-2abd14670000 r--p 00015000 fc:01 238 /lib/libgcc_s.so.1 2abd14670000-2abd14671000 rw-p 00016000 fc:01 238 /lib/libgcc_s.so.1 2abd14671000-2abd147d7000 r-xp 00000000 fc:01 2627 /lib/libc-2.10.1.so 2abd147d7000-2abd149d6000 ---p 00166000 fc:01 2627 /lib/libc-2.10.1.so 2abd149d6000-2abd149da000 r--p 00165000 fc:01 2627 /lib/libc-2.10.1.so 2abd149da000-2abd149db000 rw-p 00169000 fc:01 2627 /lib/libc-2.10.1.so 2abd149db000-2abd149e0000 rw-p 00000000 00:00 0 2abd149e0000-2abd14a1b000 r-xp 00000000 fc:01 24033 /usr/local/lib/libgtest.so.0.0.0 2abd14a1b000-2abd14c1b000 ---p 0003b000 fc:01 24033 /usr/local/lib/libgtest.so.0.0.0 2abd14c1b000-2abd14c1c000 r--p 0003b000 fc:01 24033 /usr/local/lib/libgtest.so.0.0.0 2abd14c1c000-2abd14c1d000 rw-p 0003c000 fc:01 24033 /usr/local/lib/libgtest.so.0.0.0 2abd14c1d000-2abd14c1f000 rw-p 00000000 00:00 0 2abd18000000-2abd18021000 rw-p 00000000 00:00 0 2abd18021000-2abd1c000000 ---p 00000000 00:00 0 7fff40ab1000-7fff40ac6000 rw-p 00000000 00:00 0 [stack] 7fff40bef000-7fff40bf0000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted make: *** [test] Error 134
Werde aus dieser Fehlerausgabe von GTest nicht schlau. Das Programm funktioniert gut, wenn ich es einfach so teste, also per Main-Funktion. Die Testfälle könnten natuerlich den Fehler beherbergen, aber ich wusste nicht ob man die hier posten darf oder nicht. Wo muss ich suchen? Veit 25Mai10 22:16
Hallo, ich habe mehrere Fragen zum Blatt:
- Soll die Aufgabe 1 mit den Methoden aus Aufgabe 2 gelöst werden (spätestens wenn man Aufgabe 2 implementiert)?
- Soll in Aufgabe 1 (wenn nicht die push/pop Methoden genutzt werden) auch _capacity angepasst werden?
- Soll, falls Punkt 2 eintritt, auch die Regel mit dem verdoppeln der Kapazität greifen?
- Beist sich das nicht, wenn man push_back mit pop_back testet und umgekehrt? Weil scheint mir irgendwie "komisch", dass der pop_back Test vom (ungetesteten) push_back abhängt und umgekehrt. Wenn theoretisch was schief läuft, weiß ich ja nicht woran es lag. (Ok hier sind die Methoden "einfach", aber bei komplexeren Dingen könnte das doch ein problem geben)
Ben 25Mai10 20:39
@Florin: danke für die Antwort, ich habe mich ein bisschen über Referenzen dokumentiert und habe gelesen ,dass es also fast wie eine zweite name(oder copie) für die Variable ist. Ich bin davon ausgegangen ,dass einen Code wie folgendes stimmt. Wenn ich meine interleavefunktion ausrufe.
void ListOfIntegers::interLeaveListOfIntegers(const ListOfIntegers& list1, const ListOfIntegers& list2) while ((ck1 == false) || (ck2 == false)) { if (!ck1 && _list1[i] == -1)
Außerdem habe es gemacht sowie du gesagt hast mit der h.datei ecc. aber kriege diese Fehlermeldung:
ListProcessing.cpp: In member function ‘void ListOfIntegers::interLeaveListOfIntegers(ListOfIntegers&, ListOfIntegers&)’: ListProcessing.cpp:36: error: no match for ‘operator[]’ in ‘_list1[i]’ ListProcessing.cpp:43: error: no match for ‘operator[]’ in ‘_list2[i]’
Dario 25Mai10 19:23
@Dario: Du übergibst jetzt keine int* mehr, sondern zwei ListOfIntegers. Also muss in deiner .h-Datei stehen: void interLeaveListOfIntegers(const ListOfIntegers& list1, const ListOfIntegers& list2);) Grüße, Florin 25Mai10 18:17
Hallo, ich habe ein kleines Problem:
ListProcessingMain.cpp: In function ‘int main(int, char**)’: ListProcessingMain.cpp:32: error: no matching function for call to ‘ListOfIntegers::interLeaveListOfIntegers( ListOfIntegers&, ListOfIntegers&)’ ./ListProcessing.h:30: note: candidates are: void ListOfIntegers::interLeaveListOfIntegers(int*, int*)
das ist die Fehlermeldung. P.S. was heisst diese & am Ende von ListOfIntegers? Meine interleave Funktion
void interLeaveListOfIntegers(int* list1, int* list2)
und die Mainfunktion
lista.interLeaveListOfIntegers(list1, list2);
Ich verstehe nicht wie ich die Parameter anpassen soll.. list1 und list2 sind die zwei Objekten-elements (oder listen) die man aus char* erzeugt und haben schon eine definierte _size ohne Maxima.. Gruß Dario 25Mai10 14:42
@Niklas: Ja, stimmt, schreiben Sie sich einfach eine get(int i) Funktion. Oder benutzen sie pop_back() wie von Sebastian vorgeschlagen, aber get wäre schon natürlicher. Eine dritte Alternative wäre in ListOfIntegers.h vor die Deklaration von parseFromString folgende Zeile zu schreiben
FRIEND_TEST(ListOfIntegersTest, parseFromString)
Das habe ich in der Vorlesung nicht erklärt, aber Sie dürfen es gerne benutzen, weil es eigentlich die Methode der Wahl ist. Damit geben Sie dem TEST(ListOfIntegersTest, parseFromString) die Rechte, auf die Membervariablen eines ListOfInteger Objektes zuzugreifen, insbesondere die _elements. Hannah 24Mai10 21:42
Das lässt sich mittels der pop_back Methode realisieren. SebastianD 24Mai10 16:47
Ok, noch eine Frage zu den Tests: Mir fällt irgendwie kein sinnvoller Test für die parse Funktion ein, der nicht die einzelnen Einträge der Liste anschauen muss. Dann bräuchte ich aber wieder eine Get() Funktion. Stehe ich da auf dem Schlauch oder ist das wirklich ein Problem? Niklas 24Mai 15:59
@Dario: Der constructor wird aufgerufen, wenn das Objekt deklariert und damit effektiv im Speicher erzeugt (konstruiert = constructed) wird. Aufgabe des Konstruktors ist es typischerweise, die Membervariablen des Objektes geeignet zu initialisieren. Der destructor wird aufgerufen, kurz bevor das Objekt aus dem Speicher gelöscht (zerstört = destructed) wird. Die Aufgabe des Destruktors ist typischerweise Aufräumen und schauen, dass aller Speicher der zu Lebzeiten des Objektes alloziert wurde auch wieder freigeben wird. Von daher schon nicht schlecht die Namen. Hannah 24Mai10 14:36
@Niklas: Erstmal keine Änderung gegenüber vorher, also ein TEST pro Methode und der heißt dann etwa TEST(ListOfIntegersTest, parseFromString). Hannah 24Mai10 14:32
Hallo, wenn ich das richtig verstanden habe werden Tests in Gtest ja so erstellt TEST(<Filename>, <Functionname>). Wie sieht das denn mit Klassen ordentlich aus? Checkt man da alle Funktionen in einem Test? Gruß Niklas 24Mai 14:18'
Also ich wollte nur eine kurze Frage stellen. Constructors und Deconstructors sind im Endeffekt nichts anders als Funktionen , die automatisch aufgerufen werden bzw. am Anfang der Klasse und eine am Ende der Klasse, wenn ich ein Objekt erstelle. Aber was wird "erzeugt und eliminiert"? Hätte nicht der Erfinder von c++ anders nennen können? Gruß Dario 23Mai 16:06
@Heinke: Nach dem Aufruf von parseFromString soll _size schon auf dem richtigen Wert stehen. Sie müssen den Wert da ja sowieso schon wissen, damit Sie, wie in der Aufgabenstellung gefordert, genau die richtige Menge Platz für den _elements pointer allozieren können. Wie Sie das machen, dafür gibt es viele Möglichkeiten. Eine davon ist, einfach vorab die Anzahl der Kommas im Argument listAsString zu zählen. Wenn das Argument eine korrekt formatierte Liste enthält ist die Anzahl der Elemente ja einfach die Anzahl der Kommas plus eins. Und wenn Sie beim Parsen der Liste herausfinden, dass Sie nicht korrekt formatiert ist, dann geben Sie den Platz einfach wieder frei und setzen size = 0, weil in dem Fall ja (nach wie vor) die leere Liste zurückgegeben werden soll. Eine andere Möglichkeit wäre, vorab einfach Platz für soviel ints zu reserviere wie das Argument listAsString lang ist (d.h. wieviele Zeichen es hat). Denn mehr Zahlen können ja nicht drin stehen. Am Ende vom Parsen wissen Sie ja dann wieviele ints tatsächlich drin standen und dann können Sie die genau passende Menge Platz allozieren und einmal umkopieren. So, das waren jetzt zwei Möglichkeiten, die mir spontan einfallen, aber es gibt bestimmt auch noch viele andere. Hannah 23Mai10 14:23
Kann ich einfach ne weitere Methode schreiben, die die Länge der Liste zurück gibt, die sie haben wird, wenn sie geparsed ist (also die orkommenden Zahlen zählt) und diesen Wert dann den Methoden für interleave und parse geben, damit _size entsprechend gesetzt wird? Oder gibts noch einen supergenialen Weg, der mir nur noch nicht eingefallen ist, weil ich nicht supergenial bin? Heinke 23Mai10 14:14
@Roman: Ja, richtig, kann praxisrelevant sein, muss aber nicht. Vielleicht kommen wir ja irgendwann gegen Ende des Semesters dazu. Freut mich auf jeden Fall, dass Sie sich für diese weiterführenden Konzepte interessieren und sich da offenbar auch schon sehr gut auskennen. Hannah 20Mai10 21:44
@Hannah: Ich wollte auf gar keinen Fall dogmatisch rüber kommen, aber als rein theoretisch würde ich gerade das KISS-Prinzip nicht sehen. Klassen die mehr als nur die essentiellen Eigenschaften/Methoden eines Objektes implementieren haben auf lange Sicht praxisrelevante Nachteile die mMn nicht vernachlässigbar sind, da die Klassen riesig werden und unintuitiv. Auch könnte man die getInterleaveOf Methode in der ListHandler Klasse abstrahieren und z.B. unabhängig von dem genauen Typ der Liste machen (z.B. per interface). Derjenige der seine interleaveWith Methode in der Liste selber implementiert kann diese Methode nun für jede andere Form von Listen kopieren (und bei irgendwelchen Änderungen ALLE Methoden ändern..). Dass das über den momentanten Stand in der Vorlesung hinausgeht is mir klar, aber die Praxis Relevanz sehe ich da trotzdem ganz deutlich. RomanW 20Mai10 21:32
@Roman: Mit "keine Methode ... sein sollte" und "ausgelagert sein sollte" wäre ich vorsichtig. Es gibt viele schöne Konzepte in der objekt-orientierten Welt, nur was die dann mit der Praxis zu tun haben, ist oft fraglich. Ich mache in der Vorlesung ganz dezidiert Programmieren in C++ aus der Praxis für die Praxis und so soll es sein und so soll es auch bleiben. Weiterführende Konzepte werden wir genau dann lernen und anwenden, wenn wir sie wirklich brauchen, vorher nicht. Hannah 20Mai10 21:07
@SebastianD: Die Konfusion kommt höchstwahrscheinlich daher, dass interleaveWith (imo!) streng genommen keine Methode der ListOfInteger Klasse sein sollte, sondern (gemäß dem KISS-Prinzip) in einer Art ListHandler Klasse ausgelagert sein sollte. Diese würde dann eine Methode a la ListOfIntegers getInterleaveOf(ListOfIntegers list1, ListOfIntegers list2) bereitstellen und die neue Liste zurückgeben. RomanW 20Mai10 20:53
@Ben: private bedeutet nicht Instanz-, sondern Klassensichtbarkeit. Du kannst also innerhalb deiner Listenklasse auf die (private) Member anderer Instanzen der Listenklasse zugreifen. SebastianD 20Mai10 20:19
@Hannah: Es ging mir prinzipiell nur um die Interleave Methode, da habe ich von außen keinerlei Zugriff auf die Listen in den übergebenen Objekten, da _size und _elements private ist. Somit muss man entweder get/set Methoden erstellen um die Werte einzelt auslesen zu können, die Klassenvariablen public machen oder die Methoden vom zweiten Teil nutzen (push_back/pop_back), wobei jedoch direkt bei der leeren Liste ein assert kommt, den ich nicht abfangen kann. Es war von mir weniger eine Frage sondern mehr eine Feststellung Ben 20Mai10 19:38
@Ben: Auf die Membervariablen _size und _elements brauchen Sie für dieses Übungsblatt keinen Zugriff von außerhalb der Klasse. Deswegen können Sie auch private sein (sollten Sie sowieso) und Sie brauchen auch keine spezielle get oder set Methode. Nur die Memberfunktionen brauchen Zugriff auf diese Membervariablen, und den haben Sie ja sowieso, d.h. Sie können z.B. in parseListOfIntegers einfach schreiben _size = listSize oder sowas. Hannah 20Mai10 19:28
@Heinke: Ja, genau, siehe mein code snippet in der Antwort an SebastianD. Hannah 20Mai10 19:23
@SebastianD: Berechtigte Frage. Ich würde es so machen:
void ListOfIntegers::getInterleaveOf(const ListOfIntegers& list1, const ListOfIntegers& list2);
und dann in der main Funktion:
ListOfInteger list1; ListOfInteger list2; list1.parseFromString(list1AsString); list2.parseFromString(list2AsString); list1.print("Input list 1 : "); list2.print("Input list 2 : "); ListOfInteger result; result.getInterleaveOf(list1, list2); result.print("Result list : ");
Die Version von Ben ist aber auch eine Variante die man in diesem Kontext öfter sieht. Ich würde die Methode dann allerdings interleaveWith nennen, man sollte das bei der objekt-orientierten Programmierung immer wie einen (einfachen) Satz lesen könnten. Die Variante hat halt den Nachteil, dass dann die eine Liste überschrieben wird, deswegen gefällt mir die oben besser. Hannah 20Mai10 19:14
@Hannah: Ah. Verstehe. Mit anderen Worten, ich muss also für jede Liste eine Instanz des Objektes erstellen. Oder sehe ichs immer noch falsch? Heinke 20Mai10 18:23
Für mich klingt es nach Version 1:
ListProcessing list1; [...] ListProcessing list2; [...] list1.interleave(list2);
Nur muss man sich dann imho Gedanken über die Sichtbarkeit von _size und _elements machen oder eine set/get Methode implementiern...Ben 20Mai10 17:36
Ich bin mir im Unklaren über die genaue Funktionsweise der neuen Interleave-Methode, da mir selbst spontan mehrere verschiedene Möglichkeiten einfallen:
1. void interleaveWith(ListOfIntegers list); // Die Elemente dieser Liste werden mit der Argumentliste vermischt (oder was auch immer).
2. ListOfIntegers interleaveWith(ListOfIntegers list); // siehe 1., nur dass die Argumente jetzt in einer neuen Liste gespeichert und diese zurück gegeben wird.
3. void interleave(ListOfIntegers list1, ListOfIntegers list2); // Speichert die Elemente der beiden Argumentlisten vermischt in dieser Liste (Liste vorher leeren?).
4. ListOfIntegers interleave(ListOfIntegers list1, ListOfIntegers list2); // Idealerweise sogar static. Speichert die Elemente der beiden Argumentlisten vermischt in einer neuen Liste und gibt diese zurück.
5. void interleaveWith(ListOfIntegers result, ListOfIntegers list); // C-Style. Man übergibt außerdem eine Liste, in der die Elemente dann gespeichert werden sollen.
6. ...
Welche davon? SebastianD 20Mai10 14:24
@Heinke: Für Aufgabe 1 vom neuen Übungsblatt soll das Programm exakt dasselbe machen, die Ihr Programm vom 4. Übungsblatt, nur soll das Programm mit Klassen realisiert sein, wie in der Vorlesung vorgemacht, und die Felder (die jetzt Membervariablen sind), sollen keine fixe Größe MAX_LIST_SIZE mehr haben, sondern genau die Größe, die benötigt wird. Beantwortet das Ihre Frage? Hannah 20Mai10 12:46
Verstehe ich das richtig: Der Benutzer soll ./ListProcessingMain "1,1,1,1" "2,2,2,2,2" aufrufen und anschließend sollen die Listen intern geparsed, interleaved und als array im Objekt gespeichert werden? Heinke 20Mai10 9:28