Star_Light Δημοσ. 29 Μαρτίου 2014 Δημοσ. 29 Μαρτίου 2014 (επεξεργασμένο) Έχω τρια αρχεια: /* stackADT.h */ #ifndef STACKADT_H #define STACKADT_H #include<stdbool.h> typedef struct stack_type *Stack; Stack create(void); void destroy(Stack s); void make_empty(Stack s); bool is_empty(Stack s); bool is_full(Stack s); void push(Stack s, int i); int pop(Stack s); #endif /* stackADT3.c */ #include<stdio.h> #include<stdlib.h> #include "stackADT.h" struct node { int data; struct node *next; }; struct stack_type { struct node *top; }; static void terminate (const char *message) { printf("%s\n" , message); exit(EXIT_FAILURE); } Stack create(void) { Stack s = malloc(sizeof(struct stack_type)); if(s == NULL) terminate("Error in create: stack could not be created."); s->top = NULL; return s; } void destroy(Stack s) { make_empty(s); free(s); } void make_empty(Stack s) { while(!is_empty(s)) pop(s); } bool is_empty(Stack s) { return s->top == NULL; } bool is_full(Stack s) { return false; } void push(Stack s, int i) { struct node *new_node = malloc(sizeof(struct node)); if (new_node == NULL) terminate("Error in push : stack is full. "); new_node->data = i; new_node->next = s->top; s->top = new_node; } int pop(Stack s) { struct node *old_top; int i; if(is_empty(s)) terminate("Error in pop : stack is empty. "); old_top = s->top; i = old_top->data; s->top = old_top ->next; free(old_top); return i; } /* stackclient.c */ #include<stdio.h> #include "stackADT.h" int main(void) { Stack s1 , s2; int n; s1 = create(); s2 = create(); push(s1 , 1); push(s1 , 2); n = pop(s1); printf("Popped %d from s1\n", n); push(s2 , n); n = pop(s1); printf("Popped %d from s1 \n",n); push(s2 , n); destroy(s1); while( !is_empty(s2)) printf("Popped %d from s2\n", pop(s2)); push(s2,3); make_empty(s2); if(is_empty(s2)) printf("s2 is empty\n"); else printf(" s2 is not empty\n"); destroy(s2); return 0; } Βασικα θέλω να τροποποιήσω τα παραπάνω ωστε μια στοίβα να αποθηκεύει τιμές τύπου void * ο Item θα καταργηθει μετα τις νέες αλλαγές και επισης θελω να τροποιήσω και το αρχειο του client ωστε να αποθηκεύει δεικτες στις s1 και s2 στοιβες. Νομιζω πως το πρωτοτυπο της push θα ειναι void push(Stack s , void *p); Το μελος data θα γινει char data[N+1] πχ αλλα με μπερδευει το πως θα χρησιμοποιησω τον p μεσα στην push. Ειναι μια άσκηση σε ένα βιβλιο και δεν έχει την λύση στο σαιτ να την δώ αν κολλήσω. Εκτος αυτου κάτι έχει παιξει με το Ιντερνετ στο Linux επειδη αλλαξα μητρικη και δεν μπαινει και μπαινω μονο απο τα Windows και εδω δεν έχω compiler ακομα στα Windows. Οτι κάνω το κάνω με online compilers Επεξ/σία 30 Μαρτίου 2014 από Star_Light
ChRis6 Δημοσ. 29 Μαρτίου 2014 Δημοσ. 29 Μαρτίου 2014 Όλος ο κώδικας φαίνεται σε μια γραμμή(τουλάχιστον σε μένα).Κάνε πάλι format στο post αν θες,γιατί έτσι δεν διαβάζεται εύκολα 1
Star_Light Δημοσ. 29 Μαρτίου 2014 Μέλος Δημοσ. 29 Μαρτίου 2014 Όλος ο κώδικας φαίνεται σε μια γραμμή(τουλάχιστον σε μένα). Κάνε πάλι format στο post αν θες,γιατί έτσι δεν διαβάζεται εύκολα Ναι έχεις δικιο. Τωρα νομιζω το έφτιαξα. YΓ ξέρω πως δουλεύει ο κώδικας πάντως. Πιστευω οτι το stackADT.h θα έχει 2 αλλαγές μονο στα πρωτότυπα void push(Stack s, void *p); και void *pop(Stack s);
Star_Light Δημοσ. 30 Μαρτίου 2014 Μέλος Δημοσ. 30 Μαρτίου 2014 (επεξεργασμένο) Έχει κανεις το Code Blocks 10.05? θέλω να μεταγλωτίσω τα αρχεια μαζί έκανα οτι λέει εδω http://blog.johnmuellerbooks.com/2011/07/26/creating-a-codeblocks-project-with-multiple-existing-files.aspx πατάω για compile αλλα μου εμφανίζει κατι κουλά λάθη για conflicting types στα πρωτοτυπα των συναρτήσεων και έχω χαθεί λιγο. Γενικα οτι να ναι μηνύματα πχ στην κλήση της pop που επιστρέφεται η τιμή στην n λεει για redefinition. Σκέφτομαι τον *p να τον περνάω μεσα απο την push σαν generic οπως έδειξα πιο πάνω και μετα να χρησιμοποιήσω την strcpy( new_node->data , p); Αντί της : new_node->data = i; που υπάρχει τώρα για να γίνεται η αντιγραφή των συμβολοσειρών την push θα την καλώ απο το αρχειο του client -> push(s1 , "Good Morning"); αλλα ακομα δεν έχω βρει τι θα επιστρέφω απο την pop πως θα τον επιστρεφω δηλαδη τον p σαν generic. Στην προκειμένη οπως ζητάει και η άσκηση πρέπει να ειναι δεικτης σε συμβολοσειρά. EDIT-FIXED : Λείπει μια main απο το stackclient.c και αντι για Item θέλει int στο stackADT3.c ο τρόπος για να τρέξεις παράλληλα πολλά αρχεια ειναι στον σύνδεσμο που δίνω και πιο πάνω για το Code Blocks 10.05 . Οποτε πλέον τρέχει κανονικα!!!! Επεξ/σία 30 Μαρτίου 2014 από Star_Light
ChRis6 Δημοσ. 30 Μαρτίου 2014 Δημοσ. 30 Μαρτίου 2014 Εγώ θα έβαζα και το μέγεθος του buffer στην push : main --> push( stack , void* , size_t ) --> malloc --> memcpy --> mainΈτσι μπορείς να βάλεις διαφορετικούς τύπους δεδομένων στη στοίβα.Φυσικά πρέπει να κρατάς και τον τύπο του void* p για να ξεχωρίζεις τα αντικείμενα μεταξύ τους 1
Star_Light Δημοσ. 6 Απριλίου 2014 Μέλος Δημοσ. 6 Απριλίου 2014 Chris6 ευχαριστω για την απάντηση και σορρυ αλλα δεν μπορουσα να απαντησω πιο νωρίς γιατι ειμαι εκτος σπιτιου εντος της εβδομάδας. Ο τρόπος που έλυσα την άσκηση ειναι ο εξής : Καταρχην θεωρούμε δεδομένο τον κώδικα απο τα τρια αρχεια που έχει δοθει και οτι θα κάνουμε σε αυτα ορισμένες τροποποιήσεις. Στο αρχειο επικεφαλιδας άλλαξαν τα προτυπα των συναρτήσεων σε void push(Stack s , void *p); και void * pop(Stack s); Οι αλλαγές στο αρχείο stackADT3.c ειναι μέσα στις συναρτήσεις push , pop και το μέλος της δομής int data θα γινει char data[100]; struct node { char data[100]; struct node *next; }; push definition : void push(Stack s, void *p) { struct node *new_node = malloc(sizeof(struct node)); if (new_node == NULL) terminate("Error in push : stack is full. "); //new_node->data = i; strcpy( new_node->data , p); new_node->next = s->top; s->top = new_node; } και τέλος στην pop void * pop(Stack s) { struct node *old_top; //int i; if(is_empty(s)) terminate("Error in pop : stack is empty. "); old_top = s->top; //i = old_top->data; s->top = old_top ->next; //free(old_top); return old_top; } Στο αρχειο stackclient.c θα έχουμε : /* stackclient.c */ #include<stdio.h> #include "stackADT.h" int main(void) { Stack s1 , s2; //int n; s1 = create(); s2 = create(); push(s1,"Hello"); push(s1,"Sir"); //n = pop(s1); printf("Popped %s from s1\n", pop(s1)); push(s2,"Sir"); //n = pop(s1); printf("Popped %s from s1 \n",pop(s1)); push(s2,"Hello"); destroy(s1); while( !is_empty(s2)) printf("Popped %s from s2\n", pop(s2)); push(s2,"HEHE"); make_empty(s2); if(is_empty(s2)) printf("s2 is empty\n"); else printf("s2 is not empty\n"); destroy(s2); return 0; } Κάπως έτσι το σκέφτηκα. Μου τρέχει κανονικα και μου εμφανίζει αυτα που θέλω. Μαλλον ειναι σωστη η λυση ετσι οπως την ζητάει και η εκφώνηση(*) στο βιβλιο βεβαια κάποια θέματα που με απασχολουν ειναι : - Δεν κάνω free μεσα στην pop. - Καμια κριτική για τον τροπο επίλυσης της άσκησης? - Η συνάρτηση is_full δεν νομιζω οτι χρειάζεται το Stack s σαν ορισμα της αλλα στο βιβλιο μέσα ο King το αφήνει. - Αν θελήσω να κάνω αυτο το προγραμμα καπως εύχρηστο και να δέχεται ειτε strings ειτε οτιδηποτε άλλο θα πρέπει να διαχειριζομαι την εισοδο σαν string να την αποθηκευω στον πινακα μέλος data και μετα να κάνω αν χρειάζεται μετατροπη σε ακέραιο? αν πχ η εισοδος ειναι στοιβα ακεραιων και οχι strings. Ευχαριστώ (*) Η εκφώνηση της άσκησης υπενθυμίζω οτι ειναι η : Modify the stackADT.h and stackADT3.c files of Section 19.4 so that a stack stores values of type void* , as described in Section 19.5; The Item type will no longer be used. Modify stackclient.c so that it stores pointers to strings in the s1 and s2 stacks. Ο Item τυπος ηταν απλα ένα συνωνυμο για έναν int με typedef. Τα αρχεια αρχικα ηταν οπως στο 1ο μήνυμα. Στην ενοτητα 19.5 απλα περιέγραψε οτι τα πρότυπα των συναρτήσεων θα ειναι αυτα που χρησιμοποίησα και εγώ πιο πάνω στο αρχειο .h
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα