Stapel => push
-
Also ich komme teils mit. O.O
Ich habe mal getestet und erfahren, dass das Programm in C++ geschrieben werden muss, da, wenn ich es als c-Programm kompilieren will, bekomme ich nur Fehler.Ist doch eine Ecke rasanter, als ich dachte. O.o Jetzt entstehen wieder einige Fragen mehr...
Am Besten, wir Fragen mal unseren Übungsleiter, wie man das dort macht.Trotzdem THX Nexus!
Falls weitere Fragen zu diesem Stack sind, schreibe ich wieder in dieses Thema, da ich im Moment erstmal müde bin und zweitens ich morgen oder so eh noch nicht durchblicken werde.^^'
MFG Majin_Clodan
-
Kannst du deinen Übungsleiter auch gerade fragen, wieso ihr nicht C++ programmiert, wenn das schon so dargestellt wird?
Finde ich nämlich wie gesagt etwas fragwürdig.Nein, wenn du willst, kannst du dich ja mal erkundigen, warum man nicht
cout
stattprintf()
,cin
stattscanf()
verwendet. Oder wieso man immer noch die alten C-Header mit der Endung .h hat (in C++ wären C-Header wenigstens mit einem c vornedran und ohne Endung, also<cstdio>
und<cstdlib>
). Aber nicht, dass du deswegen Probleme bekommst...P.S. Den C++-Header
<stack>
brauchst du nur, wenn du auf die fertige Klasse stack zugreifen willst, also in deinem Falle nicht.
-
So:
Wir sollen das Programm in C programmieren.
Die vollständigen Vorgaben sehen nun so aus. Hat sich nicht viel geändert, außer das die C++-bibliothek nicht mehr da ist:#include <stdio.h> #include <stdlib.h> struct TStackA { void** info; int maxGroesse; int pos; }; TStackA stapel; int anzahl = 0; TStackA create() { } TStackA push(void* info, TStackA oldStack) { } TStackA pop(TStackA oldStack) { } void* top(TStackA stack) { } /******************************************************************************* * Das Ein-/Ausgabeverhalten der main-Funktion darf nicht verändert werden. * e <Enter> beendet das Programm. * p <Zahl> <Enter> speichert <Zahl> auf dem Stapel. * o <Enter> entfernt das oberste Element vom Stapel. * t <Enter> Gibt den Integerwert an der Stapelspitze aus. *******************************************************************************/ int main(int argc, char* argv[]) { int* val; char command[8]; TStackA stack; printf("%d",stapel.info); stack = create(); while(*command != 'e') { printf("cmd? "); scanf("%s",command); switch(*command) { case 'p' : val = (int*)malloc(sizeof(int)); printf("val? "); scanf("%d",val); stack = push(val,stack); break; case 'o' : val = (int*)top(stack); if(val) free(val); stack = pop(stack); break; case 't' : if((val = (int*)top(stack))) printf("%d ",*val); break; } } }
Nun haben wir uns heute hingesetzt und versucht, das Programm nun zum Laufen zu bringen, doch wir haben hierbei ein Problem:
Wir wollen in der funktion "TStackA create()" einen neuen Stapel erstellen. Unsere codes sahen zum Schluss so aus:if(anzahl == 0) stapel.maxGroesse = 10; stapel.info=2; stapel.pos = 0; return stapel;
Das Problem hierbei ist, dass in der Struktur die Variable "info" vom Typ "void" ist. Das heißt, dass man hierbei immer einen Fehler bekommt, wenn der Wert nicht(!) 0 ist:
stapel.info=2;
Wie kann man diese Problematik umgehen?? Mein Tutor sagte mal was zu etwas, was "malloc" heißt, aber kp was das ist und wie man das implementieren soll. O.o
Hoffe, es ist nicht zu viel Text zum Lesen, da mein Beitrag doch arg lang ist. Ist aber nur die Vorgabe so lang.^^'
MFG Majin_Clodan
-
Majin_Clodan schrieb:
Nun haben wir uns heute hingesetzt und versucht, das Programm nun zum Laufen zu bringen, doch wir haben hierbei ein Problem:
Wir wollen in der funktion "TStackA create()" einen neuen Stapel erstellen.Wollt ihr nicht eine Funktion
TStackA* create(void)
schreiben, die dynamisch Speicher anfordert und einen Zeiger darauf zurückgibt? Ist meiner Ansicht nach einheitlicher, da wahrscheinlich auch spätere Operationen per Zeiger passieren und passt auch zumalloc()
.Wegen
malloc()
: Damit kannst du Speicher anfordern, schau mal hier. Denk dran, dass du den Speicher wieder mitfree()
freigeben musst.Majin_Clodan schrieb:
Das Problem hierbei ist, dass in der Struktur die Variable "info" vom Typ "void" ist. Das heißt, dass man hierbei immer einen Fehler bekommt, wenn der Wert nicht(!) 0 ist:
stapel.info=2;
Wie kann man diese Problematik umgehen?? Mein Tutor sagte mal was zu etwas, was "malloc" heißt, aber kp was das ist und wie man das implementieren soll.
Der Typ ist
void*
, nichtvoid
. Man kann keine Variablen vom Typvoid
haben.void*
ist ein typenloser Zeiger - also ein Zeiger, bei dem man nicht weiss, auf was für einen Typen er zeigt (int
,double
, ...).Ich denke, die Aufgabenstellung ist so gemeint, dass man mittels
malloc()
Speicher für einenint
reserviert und diesen dann der Variableninfo
zuweist. Auf der von mir verlinkten Seite sollte sich die Verwendung der manuellen Speicherverwaltung einigermassen erklären.Aber
void*
macht nur Sinn (aus C-Sicht), wenn sich dahinter mehrere Typen verbergen können. Und dann musst du noch irgendwo speichern, was für ein Typ nun tatsächlich genutzt wird, sonst weisst du ja nicht, wie du auf den Wert hinter dem Zeiger zugreifen kannst. Wenn du in deinem Stack nurint
s haben sollst, nimmst du besser einenint*
.
-
Moin!
Also ich habe mir mal einige tutorials, auch wegen dem, was intern geschieht, durchgelesen und es wird langsam logisch, was hier alles geschieht. xD Naja, wenn man sowas bisher noch nicht kannte und man auf einmal damit konfrontiert wird. xDTrotzdem schaffe ich es aber irgendwie nicht, Speicher zu reservieren.
Also mein "create" sieht nun so aus:
TStackA create() { stapel.info = (void **)malloc(sizeof(int)); // Reservierung Speicherbereich in Groesse "int" stapel.info = 4; //Stapelinformation, welche auf Stapel gelegt wird stapel.maxGroesse; //Stapelgroesse stapel.pos = 0; //Feldposition return stapel; //RG von Veranderung des Stapels }
Also bei er Zeile, wo ich Speicherbereich reserviere, kommt kein Fehler. Nun dacht ich mir, testest du es mal und legst einen int-Wert von 4 dort rein. Klappt aber nicht d.h. in der Zeile:
stapel.info = 4; //Stapelinformation, welche auf Stapel gelegt wird
bekomme ich den folgenden Fehler:
error: invalid conversion from 'int' to 'void*'*Ich verstehe das nicht. Ich habe doch einen gültigen Speicherbereich reserviert oder nicht?? Wieso kann ich diesen Wert nicht dort rein speichern?? ?.?
MFG Majin_Clodan
-
Die Fehlermeldung sagt ja alles. Du probierst ein int einem void** zuzuweisen, was ohne casten nicht geht. (Und auch nicht viel Sinn macht..)
-
Nun info ist ein Zeiger auf einen Zeiger im Speicherbereich deines Stapels und du reservierst Speicher für genau ein Element der Größe int und versuchst dann dem Zeiger einen int Wert zuzuweisen, das kann nicht gehen. Wahrscheinlich geht es aber um folgendes Prinzip:
int iStapelGröße = 100 // Das ist die Anzahl der Elemente die maximal auf den Stack gepusht werden können int* pStapel = (int*) malloc( sizeof ( int ) * iStapelGröße ); //hier wird Speicher reserviert int **info = &pStapel; //info zeigt nun auf das erste element im stapel //Push //Zuweisung: **info = 4; //nächstes freies Element wählen: info = &(*info++); // nächste Zuweisung: **info=3; ...
-
So,
habe es nun endlich hinbekommen.Jetzt gibt es nur noch ein kleines Problem, welches in einer weiteren Aufgabe ist. Es ist eigentlich fast alles gleich. Der einzigste Unterschied ist der, dass die Struktur nun so aussieht:
struct TStackP { void* info; TStackP* p; };
Mein Programm sieht bis jetzt so aus. Nicht wundern, falls es wieder viel aussieht. Ich gehe nur auf ein paar Zeilen ein.
#include <stdio.h> #include <stdlib.h> struct TStackP { void* info; TStackP* p; }; int zaehler = 0; TStackP stapel; void** zAufInfo = &stapel.info; //Zeiger auf void* info im Stapel -> I TStackP create() { stapel.info = (void *)malloc(10 + sizeof(int)); // Reservierung Felder des Array vom Typ int! <-------------- void** zAufInfo = &stapel.info; return stapel; } TStackP push(void* info, TStackP oldStack) { oldStack.info = (void *)malloc(10 + sizeof(int)); // Reservierung 1 Felder des Array vom Typ int! <-------------- zAufInfo[zaehler] = info; // I ++zaehler; return oldStack; } TStackP pop(TStackP oldStack) { zAufInfo[zaehler] = NULL; //Oberstes Stapelelement gelöscht --zaehler; //Dekrementierung oldStack.p[zaehler-1]; return oldStack; } void* top(TStackP stack) { if(zaehler <= 0) { printf("Der stapel ist leer"); exit(EXIT_FAILURE); } return zAufInfo[zaehler]; } /******************************************************************************* * Das Ein-/Ausgabeverhalten der main-Funktion darf nicht verändert werden. * e <Enter> beendet das Programm. * p <Zahl> <Enter> speichert <Zahl> auf dem Stapel. * o <Enter> entfernt das oberste Element vom Stapel. * t <Enter> Gibt den Integerwert an der Stapelspitze aus. *******************************************************************************/ int main(int argc, char* argv[]) { int* val; char command[8]; TStackP stack; stack = create(); while(*command != 'e') { printf("cmd? "); scanf("%s",&command); switch(*command) { case 'p' : val = (int*)malloc(sizeof(int)); printf("val? "); scanf("%d",val); stack = push(val,stack); break; case 'o' : val = (int*)top(stack); if(val) free(val); stack = pop(stack); break; case 't' : if((val = (int*)top(stack))) printf("%d ",*val); break; } } }
Man muss sich die vorgaben so vorstellen, dass in allen Funktionen außer der main nichts stand.
Bei diesem Programm schaff ich es nicht, etwas auf meinen Stapel zu tun. Ich bekomme zwar keine Fehlermeldung, wenn ich etwas raufsetze, aber wenn ich es sehen will, was dort ist, sehe ich nichts, als wäre dieser nicht da. O.O
Ich kann die Elemente auch löschen und ab einem bestimmten Punkt, wenn die Menge der elemente 0 ist und ich wieder was löschen will, wird das Programm beendet, doch das bringt mir ja nicht viel.^^'Also das Problem war ja meines erachtens, dass "info" in der Struktur kein Zeiger auf Zeiger mehr war. Dementsprchend bastelte ich mir einen und dieser zeigt dann auf dieses info in meiner Struktur:
void** zAufInfo = &stapel.info;
Wieso? Naja, weil ich später, wenn ich Elemente auf meinen Stapel tun wollte, immer Fehler bekam.
Meine push-Anweisung sieht dann so aus:zAufInfo[zaehler] = info
Hier wird die Information "info" an die Stelle "zaehler" im feld eingefügt.
So weit so gut. Wenn ich nun aber sehen will, was ich auf dem Stapel habe, sehe ich ja nichts. In meinem "top" habe ich dann dafür das:
return zAufInfo[zaehler];
danach dann soll es ja per printf ausgegeben werden, doch das macht es nicht.
Was habe ich falsch gemacht? Etwas falsches mit meinem "Zeiger auf Zeiger" oder so??
______
Legende in der Struktur:
info => speichert einen Zeiger auf die Information zu dem heweiligen Eintrag
p => dient der Verkettung der Stapelelemente=> wusste selber kaum, was p mir sagen soll und deswegen umgehe ich es einfach oder in wie fern könnte man es gebrauchen??
MFG Majin_Clodan
PS: so viel Text in einem Beitrag. xD
-
Hallo Komilitone(hab die gleiche aufgabe
)...also ich hab das Problem, dass der Compiler schon beim Aufruf der Funktion "create" einen Fehler meldet "syntax error before "create" ".
Ich seh überhaupt nich durch...muss ich vorher noch etwas definieren bzw. festlegen??
-
fischkopp schrieb:
Hallo Komilitone(hab die gleiche aufgabe
)...also ich hab das Problem, dass der Compiler schon beim Aufruf der Funktion "create" einen Fehler meldet "syntax error before "create" ".
Ich seh überhaupt nich durch...muss ich vorher noch etwas definieren bzw. festlegen??
Dann zeig den Code mal her. Du hast doch nicht etwa ein ; bei der Klassendefinition vergessen, oder?
-
Hallo Programmierpraktikum-Geschädigte und nette Menschen, die uns helfen,
Auch mir geht es so... Egal wie ich den Quelltext gestalte, immer kommt bei mir "Syntax-Error before create". Kann das am Compiler liegen (benutze DEV-C++)?? Ich mein, ich bekomm gar nicht die Fehlermeldungen, die schon erwähnt wurden, weil halt schon immer vorher ein Fehler auftritt. Hier beispielsweise mein create Funktion zu TStackA
#include <stdio.h> #include <stdlib.h> struct TStackA { void** info; int maxGroesse; int pos; }; TStackA stapel; // egal was ich mache kommt hier ein Fehler bzw. int anzahl = 0; // unten bei TStackA creat() TStackA create() { stapel.info = (void **)malloc(sizeof(int)); // Reservierung Speicherbereich in Groesse "int" stapel.info = 4; //Stapelinformation, welche auf Stapel gelegt wird stapel.maxGroesse; //Stapelgroesse stapel.pos = 0; //Feldposition return stapel; //RG von Veranderung des Stapels }
Vielen Dank für eure Hilfe im Voraus!
-
@BartMan
Das Programm, dass du bekommen hast ist als c Dokument gespeichert. Editiere mal die Endung auf *.cpp, dann kommt keine Meldung beim create mehr.
-
In C müssen Funktionen, die keine Parameter haben, das explizit durch
void
angeben.TStackA create(void)
-
hab das gleiche problem
die vorgabe ist c und nicht c++ und lehvis wird sicher auch nur ein c programm annehmen. also bringt es nichts das ding auf .cpp zu ändern
sonst könntest du ja gleich die c++ klassen dafür nehemen
in c++ könntest du sogar das struct weg lassen.wäre eine möglichkeit:
typedef struct TStackA { void** info; int maxGroesse; int pos; }TStackA;
in C brauchst du immer ein typedef (,oder?)
diese aufgabe spiegelt leider auch die vorlesung des prof´s B. wieder. er mischt ständig c mit c++ und das was in C ist entspricht nicht mal dem C99
-
dap schrieb:
hab das gleiche problem
Schau mal meinen Post an.
dap schrieb:
wäre eine möglichkeit:
typedef struct TStackA { void** info; int maxGroesse; int pos; }TStackA;
in C brauchst du immer ein typedef (,oder?)
Wenn du das Schlüsselwort
struct
in Deklarationen weglassen willst, ja. (Okay, es ginge auch über ein Makro, aber lassen wir das...)Dein Konstrukt sollte aber eher so aussehen:
typedef struct // hier kein Bezeichner { void** info; int maxGroesse; int pos; } TStackA;
-
ohne dem typedef oder makro kann man sonst die funktion (vorgeabe)
TStackA create(){} nicht aufrufen, weil beim compilieren ja schon der fehler kommt das er mit dem TStackA nix an zu fangen weißallg. tuh ich mich mit dem anblick des "void**" schwer. zumal der den wert in der main-funktion als integer ausgeben soll und in der eingabe mit scanf kann man auch nur eine zahl eingeben. daher verstehe ich denn sinn überhaupt nicht. und ich denke das da schnell laufzeitfehler entstehen können
-
Hi
habe die selbe aufgabe gestellt bekommen,
ich glaube das dass *void dazu dient um in C verschiedene komplexe Datenstrukturen zu speicher, also structs.da wir ja **void verwenden erzeugen wir eine Liste, ein array von vielen *voids
somit kann man leicht hinzufügen wie bei normalen array.TStackA push(void* info, TStackA oldStack) { next = info; if (oldStack.pos < oldStack.maxGroesse){ oldStack.info[oldStack.pos++] = next; // next info wird im info Feld gespeichert, danach pos erhöht um 1 } else { // wenn kein Platz mehr, erhöhe um 50% oldStack.info = (void**)realloc(oldStack.info, (oldStack.maxGroesse + oldStack.maxGroesse / 2)); oldStack.info[oldStack.pos++] = next; // next info wird im info Feld gespeichert, danach pos erhöht um 1 } return oldStack; }
gruß
-
next ist ein void* next;
eigentlich ist der überflüssig er zeigt nur noch mal deutlich, das es sich um ein nächstes element handelt.
meine ausgabe ist äußert komisch, ich weis nicht wie ich den inhalt dieses pointer auf pointer ausgeben kann.
er gibt mir immer nur die adresse aus, wenn ich info[stack.pos] anspreche sollte er eigentlich den inhalt davon ausspucken, nicht wieder den pointer auf die pos.
gruß
-
Du brauchst *info[stack.pos].
-
HHHIIIIIILLLLLLFFFFFFFEEEEEEE!!!!!!!!
Ich hab genau die gleichen Probleme wie alle andern auch.
Mein Programm sieht noch genauso aus wie am Anfang, d.h. meine Vorgage ist immernoch unverändert.
Und bei den Lösungsansätzen hier verstehe ich rein garnichts.
Ich bekomme nicht mal das create() hin und hab auch nicht die leiseste Ahnung, wie ich das anstellen soll.Ich hoffe, mir kann jemand helfen.