Μάθημα - Απλά Συνδεδεμένες Λίστες

...ασύγχρονα μαθήματα γλώσσας C

Re: ΚΕΦΑΛΑΙΟ 6 - ΔΕΙΚΤΕΣ

Δημοσίευσηαπό migf1 » 03 Ιούλ 2011, 13:29

Star_Light έγραψε:
[snip]
Παντως εγω C αν και διαβαζα και στο παρελθον και ειχα βγαλει 2 βιβλια του γκιουρδα.... δεν θα ντραπω να πω πως τωρα αρχισα να μαθαινω καλα.
[snip]


Off topic:
Δεν πιστεύω πως τίθεται καν θέμα ντροπής ρε συ. Έτσι κι αλλιώς, κανείς δεν μπορεί να πει πως ξέρει τέλεια μια γλώσσα ή ότι τα ξέρει όλα, γιατί είναι τεράστιο το εύρος των εφαρμογών της στη πληροφορική. Π.χ. μπορεί να ξέρεις να προγραμματίζεις GTK+ με C πολύ καλά, αλλά αν πας να προγραμματίσεις π.χ. σε Windows API θα χρειαστεί να ρίξεις διάβασμα μέχρι να προσαρμοστείς στις διαφορετικές προσεγγίσεις αλλά και τις συναρτήσεις του.

Προφανώς το να έχεις γερές βάσεις στα της γλώσσας (που στη C μεταφράζεται κυρίως σε pointers :lol:) σου παίρνει πολύ λιγότερο χρόνο η εκμάθηση κι η εφαρμογή ενός νέου API, συγκριτικά με κάποιον που δεν ξέρει ή μισο-ξέρει τη γλώσσα. Αλλά και χρόνο θα σου πάρει και διάβασμα θα πρέπει να ρίξεις.

Όπως επίσης, το να έχεις μάθει καλά και να έχεις εμπεδώσει το πως δουλεύουν τα πράγματα "πίσω από τις κουρτίνες" σε μια γλώσσα (κι η C είναι η ιδανική για αυτό) αποτελεί τεράστιο εφόδιο για την περαιτέρω εκμάθηση πιο high-level γλωσσών. Ενώ το αντίθετο, δεν είναι καθόλου εύκολο.

Σχετικά με τα βιβλία, ορισμένα είναι πολύτιμα ως πηγές αλλά ακόμα πιο πολύτιμο είναι να έχει διδαχτεί κανείς σε σωστό περιβάλλον την ύλη του εκάστοτε βιβλίου (ή συναφούς βιβλίου). Αυτή είναι και η μεγάλη διαφορά όσων π.χ. διδάσκονται το ίδιο πράγμα σε στοχευμένο ακαδημαϊκό περιβάλλον συγκριτικά ας πούμε με τους αυτοδίδακτους (χωρίς αυτό να αποκλείει και κάποιες εξαιρέσεις).

Προσωπικά πιστεύω πως τα 2 μεγάλα λάθη που κάνουν οι περισσότεροι όταν ξεκινάνε να μάθουν μια γλώσσα μόνοι τους, είναι:
  1. Η βιασύνη να πάνε απευθείας στο Ω, προσπερνώντας ή περνώντας στα "πεταχτά" άλλα... γράμματα της αλφαβήτου που προηγούνται, χωρίς να τα έχουν πραγματικά κατανοήσει, ή νομίζοντας πως τα έχουν κατανοήσει (επειδή ως αυτοδίδακτοι δεν έχουν καθοδήγηση από κάποιον που ήδη ξέρει (βλέπε καθηγητή) για το big picture).
  2. Η λανθασμένη εντύπωση πως αρκούν π.χ. 1-2-3 μήνες αυτοδίδακτης προσπάθειας για να "μάθουν" μια γλώσσα (όποια γλώσσα κι αν είναι αυτή). Ακόμα και να έχουν εξαντλήσει το λεξιλόγιο των keywords της γλώσσας και να το έχουν όντως κατανοήσει, πρέπει να αποκτήσουν και ευχέρεια στη σύνθεση και τις αλληλο-επιδράσεις αυτών των εννοιών που αντιπροσωπεύουν τα keywords, κι αυτό γίνεται μόνο με συγγραφή κώδικα ολοκληρωμένων προγραμμάτων. Και μάλιστα όσο μεγαλύτερο το φάσμα τομέων που καλύπτουν με συγγραφή ολοκληρωμένου κώδικα, τόσο περισσότερο εμπεδώνουν τη γλώσσα. Και όλα αυτά δεν μπορούν να γίνουν σε 1-2-3 μήνες.

Ας πάρουμε για παράδειγμα το παιχνίδι της Ξερής που έχω ποστάρει σε άλλο νήμα κι ας πούμε πως το βάζει κάποιος σαν στόχο προκειμένου να μάθει και να εξοικειωθεί με τις βασικές αρχές της C. Ακόμα και αν έχει μάθει άπταιστα τη σύνταξη της γλώσσας, αν δεν βρεθεί κάποιος να τον καθοδηγήσει για το ότι π.χ. τα μαζέματα των φύλλων του κάθε κάθε παίκτη όπως και τα φύλλα στο τραπέζι είναι ιδανικές περιπτώσεις για να υλοποιηθούν με στοίβες (stacks) το πιθανότερο είναι και πάρα πολύ περισσότερο να παιδευτεί και ο κώδικάς τους να καταλήξει όχι μόνο αχρείαστα πολύπλοκος, αλλά κυρίως "βαρύς", αργός και μνημοβόρος. Αυτό προφανώς είναι ανεξάρτητο από τη γλώσσα, εμπίπτει στην ανάλυση αλγορίθμων και δομών δεδομένων.

Επίσης, το να φτιάξει το παιχνίδι πρώτα σε κονσόλα, του εξασφαλίζει πως το μεγαλύτερο μέρος της προσπάθειάς του θα παραμένει στοχευμένο στην επίλυση του συγκεκριμένου προβλήματος, και όχι σε δευτερεύουσας σημασίας καλλωπιστικής φύσης θέματα, όπως είναι για παράδειγμα το γραφικό περιβάλλον του παιχνιδιού.

Το να "ζωγραφίσεις" για παράδειγμα το τραπέζι και τα τραπουλόχαρτα, και να τα παρουσιάζεις να μετακινούνται, όχι μόνο δεν έχει απολύτως καμία σχέση με τον πυρήνα του προβλήματος, αλλά απαιτεί να αποπροσανατολίσεις την προσπάθειά σου προς μια δευτερεύουσας σημασίας δραστηριότητα, καλλωπιστικής φύσης, η οποία όμως αποτελεί σχεδόν αυτόνομη ενότητα και πιθανότατα θα σου πάρει περισσότερο χρόνο να την υλοποιήσεις από ότι η ίδια η ουσία του παιχνιδιού.

Και κατά την προσωπική μου πάντα άποψη το χειρότερο που μπορεί να κάποιος μαθαίνοντας μια γλώσσα είναι να ξεκινάει πρώτα από τα... καλλωπιστικά. Στο τέλος καταλήγει να τα κάνει όλα έναν... αχταρμά στο κεφάλι του και είτε να τα παρατάει είτε το τελικό αποτέλεσμα να είναι ενδεχομένως όμορφο αλλά να σέρνεται, να σπαταλάει μνήμη, να είναι αχρείαστα πολύπλοκο στον κώδικά του (και άρα αχρείαστα πολύπλοκο στη συντήρηση ή στη βελτίωσή του) ή όλα μαζί :lol:

Χρειάζεται όρεξη, υπομονή, επιμονή και κυρίως προσήλωση και καλή διάθεση για να μάθει κανείς καλά μια γλώσσα, όποια κι αν είναι αυτή. Με συγγραφή απλών παραδειγμάτων σε κώδικα από τον ίδιο για οτιδήποτε δεν πολυ-καταλαβαίνει μέχρι να το καταλάβει, και σταδιακά αυξανόμενης δυσκολίας μικρο-projects στο τέλος κάθε ενότητας που μαθαίνει (τα καλά βιβλία συνήθως το περιλαμβάνουν αυτό).

In real life, η γλώσσα αυτή κάθε αυτή δεν είναι ποτέ αρκετή και πρέπει να συνοδεύεται κι από γνώσεις ανάλυσης αλγορίθμων, που προϋποθέτουν έτσι κι αλλιώς πολύ καλή γνώση στις δομές δεδομένων. Στα πολύ μεγάλα projects υπάρχουν διακριτές θέσεις για αυτές τις δουλειές, οι αναλυτές κάνουν την ανάλυση και οι προγραμματιστές την υλοποιούν (ίσως έχετε συναντήσει και τον όρο "code-monkeys" που χρησιμοποιείται υποτιμητικά για όσους οι γνώσεις τους εν πολλοίς εξαντλούνται στη σύνταξη της γλώσσας, ενδεχομένως και σε τετριμμένους αλγόριθμους που κατεβάζουν από το Internet).

Κατά κανόνα οι αναλυτές ξέρουν και να προγραμματίζουν σε τουλάχιστον μια γλώσσα, ενώ οι οι προγραμματιστές ξέρουν να προγραμματίζουν σε τουλάχιστον 2 ή 3 γλώσσες, αλλά η ικανότητα τους σε ανάλυση αλγορίθμων περιορίζεται στα απολύτως τετριμμένα.

Συνήθως οι αμιγώς προγραμματιστές είναι είτε αυτοδίδακτοι είτε απόφοιτοι μικρών σχολών, ενώ οι αναλυτές είναι απόφοιτοι πανεπιστημίων.

Προφανώς τα παραπάνω έχουν κάποιο νόημα για όσους ασχολούνται ή σκοπεύουν να ασχοληθούν σοβαρά κι επαγγελματικά με το... άθλημα, και όχι για χόμπι.

Όπως και να έχει, μου ήρθε τώρα στο μυαλό μια συζήτηση σε ένα άλλο φόρουμ, με θέμα "Προγραμματιστής & Πολυτεχνείο" όπου προς μεγάλη μου έκπληξη είδα πολλούς να υποστηρίζουν πως ούτε λίγο ούτε πολύ τα πτυχία είναι άχρηστα, αφού οτιδήποτε χρειαστεί κανείς μπορεί να το διαβάσει μόνος τους είτε σε βιβλία είτε στο Ιντερνετ !!!!!!!!!!!!!!!!!

Κι επειδή μεταξύ άλλων έχει σχέση και με τις λίστες που αναλύουμε σε αυτό το νήμα, κάνω quote την εξιστόρηση μιας (από τις πολλές) προσωπικής μου εμπειρίας με κάποιον αυτοδίδακτο...

έγραψε:
Υπήρχε λοιπόν μια απλά συνδεδεμένη λίστα η οποία έπρεπε να διατηρείται ταξινομημένη και η οποία ήταν και τεράστια και σε πλήθος κόμβων και σε όγκο του κάθε κόμβου.

Καταρχήν, ξέρεις γιατί είχε επιλεγεί αυτή η "για τα μπάζα" υλοποίηση; Γιατί ο ιδιοκτήτης είχε προσλάβει έναν αυτοδίδακτο για τη δουλειά, που του ζήτησε τα μισά χρήματα από τους πτυχιούχους.

Πάμε παρακάτω.

Ξέρεις τι έκανε ο code-monkey για κάθε νέο κόμβο που ήθελε να εισαγάγει στη λίστα; Τον έβαζε στην αρχή της λίστας και μετά έκανε.... bubble-sort !!!!!!!!!!!!!!!!!!

Με μετατροπή της λίστας από απλή σε διπλά συνδεδεμένη, με ένα δεύτερο μόνιμο δείκτη στο tail της (εκτός του head στην αρχή της δηλαδή) και με απευθείας ταξινομημένη εισαγωγή του κάθε νέου κόμβου στην σωστή θέση, ξεκινώντας είτε από το head είτε από το tail, ανάλογα με αν το key του νέου κόμβου ήταν μικρότερο ή μεγαλύτερο από το μισό του πλήθους της λίστας, ο μέσος όρος του χρόνου ταξινόμησης έπεσε στο 1/10.

Και με κώδικα που συμπεριλαμβανομένης της συνάρτησης μετατροπής από απλής σε διπλά συνδεδεμένης λίστας δεν με πήρε ούτε μισή ώρα για να τον γράψω.

Προφανώς του το έκανα τσάμπα και γιατί ήταν γνωστός και γιατί αυτά τα πράματα είναι απλή αλφάβητος για τους πτυχιούχους.

Το παράδειγμα (αν και τραβηγμένο, υπό την έννοια πως ο τύπος δεν ήταν απλώς code-monkey, μάλλον σκέτο monkey ήταν) δεν το έγραψα ούτε για να περιαυτολογήσω ούτε για να πουλήσω μούρη (άλλωστε είπαμε είναι απλά πράματα αυτά, συν ότι κι εγώ έχω κάνει άπειρες παπαριές κατά καιρούς).

Το έγραψα αφενός επειδή είναι πραγματικό και απλό στην κατανοήσή του, κι αφετέρου για να δώσω ακόμα μεγαλύτερη έμφαση στο επιχείρημα πως το συγκριτικό πλεονέκτημα ενός πτυχιούχου είναι τεράστιο. Από τα πιο απλά μέχρι τα πιο σύνθετα θέματα.


Πω, πω... πάλι ολόκληρη έκθεση έγραψα :lol:
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 6 - ΔΕΙΚΤΕΣ

Δημοσίευσηαπό migf1 » 03 Ιούλ 2011, 19:56

Star_Light έγραψε:
[snip]
καπου ο δασκαλος migf1 (ας μου επιτρεψει αυτο τον χαρακτηρισμο μιας και ειναι καλλιτεχνης) ειπε για το αν θα πρεπει να συνεχισει η οχι..... βασικα η δικια μου αποψη ειναι λιγο πιο σιγα ειναι πολυ ενδιαφεροντα ολα αυτα και τα διαβαζω σιγα σιγα και με προσοχη οπως και αλλα μελη ...
[snip]

Όντως, σαν να έπεσαν πολλά μαζεμένα!!!

Λέω πριν προχωρήσουμε παρακάτω να προσπαθήσετε να φτιάξετε ένα μικρό πρόγραμμα, ως crash-test των όσων έχουμε πει μέχρι στιγμής. Ένα πρόγραμμα δηλαδή που για να το φέρετε εις πέρας θα προϋποθέτει πως όντως έχετε εμπεδώσει αυτά που έχουμε πει μέχρι τώρα.

Γράψτε ένα πρόγραμμα που θα διαβάζει από το πληκτρολόγιο τυχαίο πλήθος λέξεων (μια λέξη ανά γραμμή) και σε τυχαία σειρά μέχρι να διαβάσει τη λέξη "stop".

Θα τις μετατρέπει σε πεζά γράμματα κι ανάλογα με το γράμμα από το οποίο αρχίζει η κάθε λέξη θα την αποθηκεύει σε μια από 26 απλά συνδεδεμένες λίστες, με την κάθε λίστα από αυτές να αντιστοιχεί σε ένα από τα 26 πεζά γράμματα της λατινικής αλφαβήτου. Δηλαδή όσες λέξεις ξεκινάνε με το γράμμα a θα αποθηκεύονται στη λίστα που αντιστοιχεί στο a, όσες ξεκινάνε από b θα αποθηκεύονται στη λίστα που αντιστοιχεί στο b, κλπ.

Η σειρά των λέξεων στην κάθε λίστα θα πρέπει να είναι χρονολογικά αντίστροφη (δηλαδή οι πιο πρόσφατα πληκτρολογημένες λέξεις να εμφανίζονται πρώτες στη λίστα τους).

Για λιγότερο κώδικα, η λέξη "stop" θα αποθηκεύεται κι αυτή στη λίστα του s. Αν μια λέξη αρχίζει από χαρακτήρα με ASCII code μικρότερο του 'a' θα μπαίνει στη λίστα του a, ενώ αν αρχίζει από χαρακτήρα με ASCII code μεγαλύτερο του 'z' θα μπαίνει στη λίστα του z.

Πριν τερματίσει το πρόγραμμα θα τυπώνει τα περιεχόμενα (λέξεις) μόνο όσων λιστών δεν είναι άδειες, καθώς και το σε ποιο γράμμα αντιστοιχούν και πόσες λέξεις περιέχουν. Στο τέλος θα τυπώνει το συνολικό πλήθος των λέξεων που περιέχονται σε όλες τις λίστες.


Το παραπάνω πρόγραμμα σίγουρα δεν θα το χαρακτήριζα εύκολο για αρχάριους, αλλά αν έχετε κατανοήσει όσα έχουμε πει μέχρι τώρα είναι απόλυτα εφικτό!. Τεστάρει όχι μόνο λίστες, αλλά και πίνακες και strings και χαρακτήρες. Είναι πολύ καλή άσκηση που θα σας βοηθήσει να ξεκαθαρίσετε πάρα πολλά πράγματα αν την καταφέρετε μόνοι σας!

Τις βασικές δομές και συναρτήσεις που θα χρειαστείτε για την διαχείριση των λιστών (εισαγωγή κόμβων, πλήθος κόμβων, τύπωμα λιστών, καταστροφή λιστών) τις έχουμε ήδη γράψει σε κώδικα. Hint: Αποφασίστε όμως αν, σύμφωνα με την εκφώνηση, τις εισαγωγές κόμβων πρέπει να τις κάνετε με την list_append() ή με την list_prepend() ;)

Ιδανικά, για να είναι το πρόγραμμα πιο δομημένο και άρα πολύ πιο εύκολο να του προσθέσουμε κι άλλες λειτουργίες μελλοντικά, θα πρέπει να γραφτεί με τις δομές που αναλύω στο 5ο μέρος του tutorial, αν και προϋποθέτει ακόμα μεγαλύτερη κατανόηση των εννοιών που έχουμε αναλύσει (μπορεί όμως κάλλιστα να υλοποιηθεί και με όσα έχουν αναλυθεί μέχρι και το 3ο μέρος).

Με τον τρόπο του 5ου μέρους, ο κώδικας (χωρίς σχόλια) μου πήρε 160 γραμμές συνολικά, χρησιμοποιώντας 9 συναρτήσεις + την main()... 3 συναρτήσεις για διαχείριση strings (διάβασμα, μετατροπή σε πεζά κι αντιγραφή) και 5 για διαχείριση λιστών (αρχικοποίηση, έλεγχο για κενή λίστα, εισαγωγή κόμβων, τύπωμα κόμβων και καταστροφή λίστας). Επίσης, για μεγαλύτερη απλότητα στον κώδικα, δεν κάνει έλεγχο για το αν η κάθε γραμμή εισόδου περιέχει περισσότερες από μια λέξεις (αν περιέχει, τότε τις διαβάζει όλες μαζί σαν μια λέξη).

Η υλοποίησή μου δίνει την παρακάτω έξοδο:

Εικόνα

Τον κώδικα του προγράμματος θα τον ποστάρω μόνο αν μου τον ζητήσετε (εννοώ για να σας δώσω όσο χρόνο θέλετε για να το φτιάξετε μόνοι σας).

HINTS:

  • Για τις 26 λίστες, χρησιμοποιήστε έναν πίνακα από λίστες... π.χ.: List alphabet[26]; Ενημερωτικά, αυτό είναι ένα απλοϊκό hash-table (απλά το αναφέρω ως πληροφορία, δεν υπονοώ δηλαδή πως χρειάζεται να διαβάσετε περί hash-tables για να φτιάξετε τον παραπάνω πίνακα).
  • Φτιάξτε οπωσδήποτε μια συνάρτηση (π.χ. init_alphabet(List alphabet[] ) ) που θα αρχικοποιεί τα πεδία head (=NULL), tail (=NULL) και len (=0) ΟΛΩΝ των λιστών του πίνακα, πριν ξεκινήσετε να κάνετε οτιδήποτε άλλο με τις λίστες.
  • Εκμεταλλευτείτε το γεγονός πως στη στάνταρ C οι char αντιστοιχούν σε ASCII codes, ώστε όταν εξετάζετε το 1ο γράμμα της κάθε λέξης να αντιστοιχήσετε το ASCII code του 'a' στο 0, ... το ASCII code του 'z' σε 25 , προκειμένου να βρείτε σε ποιο στοιχείο του πίνακα είναι η λίστα στην οποία πρέπει να μπει η λέξη.
  • Θυμηθείτε πως στη C αν s είναι ένα string, τότε *s ή s[0] είναι ο πρώτος χαρακτήρας του.

ΥΓ. Όχι και δάσκαλος, απλά πιο έμπειρος :)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 6 - ΔΕΙΚΤΕΣ

Δημοσίευσηαπό Star_Light » 04 Ιούλ 2011, 01:57

migf1 ευχαριστουμε για τις συμβουλες!!! εχεις δικιο σε ολα ... και εγω αναγνωρισα μερικα λαθη σε αυτα που επισημαινεις και εσυ ...

Οσο για σημερα... ειπα να ρεπαρω λιγακι!!! Απο αυριο παλι θα μπω δυναμικα... συνεχιζοντας με το 4ο μερος!!!
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 6 - ΔΕΙΚΤΕΣ

Δημοσίευσηαπό Star_Light » 04 Ιούλ 2011, 23:15

Κώδικας: Επιλογή όλων


#include <stdio.h>
#include <stdlib.h>

void function( int **x)
{
(*x)++;
return;
}
int main()
{
int *x;
int y;
x=&y;

printf("O x apo tin main(): %d \n",*x);

function(&x);
printf("O x apo tin function me call by reference: %d \n",*x);

return 0;
}


γιατι μου βγαζει 0 και 0 εδω ??? πχ δεν λογαριαζει καθολου υποψιν το (*x)++; μεσα στην συναρτηση.....
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 6 - ΔΕΙΚΤΕΣ

Δημοσίευσηαπό migf1 » 04 Ιούλ 2011, 23:23

Γιατί μέσα στην function() μετακινείς τον x μια θέση δεξιά, ενώ υποθέτω θέλεις να αυξήσεις κατά 1 τον int στον οποίον δείχνει: (**x)++
Star_Light έγραψε:
Κώδικας: Επιλογή όλων


#include <stdio.h>
#include <stdlib.h>

void function( int **x)
{
(*x)++;
return;
}
int main()
{
int *x;
int y;
x=&y;

printf("O x apo tin main(): %d \n",*x);

function(&x);
printf("O x apo tin function me call by reference: %d \n",*x);

return 0;
}


γιατι μου βγαζει 0 και 0 εδω ??? πχ δεν λογαριαζει καθολου υποψιν το (*x)++; μεσα στην συναρτηση.....
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 6 - ΔΕΙΚΤΕΣ

Δημοσίευσηαπό migf1 » 04 Ιούλ 2011, 23:25

Επίσης, αρχικοποίησε σε κάτι το y στην main() πριν βάλεις τον x να δείχνει στη διεύθυνση &y
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 6 - ΔΕΙΚΤΕΣ

Δημοσίευσηαπό Star_Light » 05 Ιούλ 2011, 22:06

Λοιπον εχω 2 αποριουλες ...

Κώδικας: Επιλογή όλων


/*==========================================================
YLOPOIHSH LISTAS ME SUNARTHSEIS

5/7/11

==========================================================
*/
#include<stdio.h>
#include<stdlib.h>

typedef struct customer /*xreiazetai kai i leksi customer wste na kserei mesa sto swma
tou se ti tupo anaferetai o deiktis next */
{
int id;
struct customer *next;
} Customer;

int main ()
{
int i;
Customer *head , *one;
Customer *two;

head = NULL;

{
head= calloc(1,sizeof(Customer));
head->id=1;
head->next = NULL;
}

one= calloc(1,sizeof(Customer));
one->id=2;
one->next=NULL;
head->next=one;

two=calloc(1,sizeof(Customer));
two->id=3;
two->next=NULL;
one->next=two;

for(i=0; i<3; i++)
{
void list_print(Customer *head);
}

free(one->next); /*Etsi einai to swsto kai oxi opws to eixa anapoda gt einai sfalma */
free(head->next); /* epeidi to head itan hdh katestrameno dn borousa meta na dwsw px */
free(head); /* free(head->next) */

if(head==NULL)
printf("H free dn ekane kala tin douleia tis \n");
else
printf("H mnimi eleutherwthike!");


return 0;
}
void list_print(Customer *head)
{
while(head)
{
printf("%d",head->id);
head=head->next;
}
putchar('\n');
return;
}



Καταρχην γιατι δεν μου δουλευει η συναρτηση???? :/
Κατα δευτερον εχουμε πει πως ο δεικτης head εδω (list) στους κωδικες του migf1 δεν ειναι ο ιδιος κομβος
αλλα ειναι ενας δεικτης που δειχνει σε εναν κομβο... ωραια τοτε αυτο εδω γιατι
head->next=one;

εχει πεδιο next???
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 6 - ΔΕΙΚΤΕΣ

Δημοσίευσηαπό Star_Light » 05 Ιούλ 2011, 22:11

Oπα οκ... παιζει να ρωτησα πατατουλα...επειδη ειπαμε εχουμε κληση με τιμη. Και ζΗταω να εκτυπωσει μονο το head->id πχ
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 6 - ΔΕΙΚΤΕΣ

Δημοσίευσηαπό migf1 » 05 Ιούλ 2011, 23:37

Star_Light έγραψε:Λοιπον εχω 2 αποριουλες ...
[snip]
Καταρχην γιατι δεν μου δουλευει η συναρτηση???? :/

Γιατί την έχεις κάτω από την main(). Ή θα πρέπει να την βάλεις πάνω από την main() ολόκληρη ή να βάλεις πάνω από τη main() το πρότυπο της print_list().

έγραψε:Κατα δευτερον εχουμε πει πως ο δεικτης head εδω (list) στους κωδικες του migf1 δεν ειναι ο ιδιος κομβος
αλλα ειναι ενας δεικτης που δειχνει σε εναν κομβο... ωραια τοτε αυτο εδω γιατι
head->next=one;

εχει πεδιο next???

Αν το κάνεις malloc() / calloc() το ίδιο το head, τότε ναι έχει πεδίο next (και πεδίο id). Αν δεν το κάνεις malloc() / calloc() και απλά το βάλεις να δείχνει σε έναν άλλνο ήδη malloc'ed() / calloc'ed κόμβο, τότε το head->next αναφέρεται στο πεδίο next του κόμβου στον οποίον δείχνει ο head.

Ελπίζω να μη σε μπέρδεψα χειρότερα.

ΥΓ. Θέλω να πω πως είσαι από τα λίγα άτομα που έχω βρει στο Ίντερνετ να κάνουν τόσο εύστοχες ερωτήσεις σχετικά με τους δείκτες :)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: ΚΕΦΑΛΑΙΟ 6 - ΔΕΙΚΤΕΣ

Δημοσίευσηαπό Star_Light » 05 Ιούλ 2011, 23:50

migf1 έγραψε:
Star_Light έγραψε:Λοιπον εχω 2 αποριουλες ...
[snip]
Καταρχην γιατι δεν μου δουλευει η συναρτηση???? :/

Γιατί την έχεις κάτω από την main(). Ή θα πρέπει να την βάλεις πάνω από την main() ολόκληρη ή να βάλεις πάνω από τη main() το πρότυπο της print_list().

έγραψε:Κατα δευτερον εχουμε πει πως ο δεικτης head εδω (list) στους κωδικες του migf1 δεν ειναι ο ιδιος κομβος
αλλα ειναι ενας δεικτης που δειχνει σε εναν κομβο... ωραια τοτε αυτο εδω γιατι
head->next=one;

εχει πεδιο next???

Αν το κάνεις malloc() / calloc() το ίδιο το head, τότε ναι έχει πεδίο next (και πεδίο id). Αν δεν το κάνεις malloc() / calloc() και απλά το βάλεις να δείχνει σε έναν άλλνο ήδη malloc'ed() / calloc'ed κόμβο, τότε το head->next αναφέρεται στο πεδίο next του κόμβου στον οποίον δείχνει ο head.

Ελπίζω να μη σε μπέρδεψα χειρότερα.

ΥΓ. Θέλω να πω πως είσαι από τα λίγα άτομα που έχω βρει στο Ίντερνετ να κάνουν τόσο εύστοχες ερωτήσεις σχετικά με τους δείκτες :)


OK! Aλλα τωρα μου πεταει segmentation fault πχ

Κώδικας: Επιλογή όλων


/*==========================================================
YLOPOIHSH LISTAS ME SUNARTHSEIS

5/7/11

==========================================================
*/
#include<stdio.h>
#include<stdlib.h>

typedef struct customer /*xreiazetai kai i leksi customer wste na kserei mesa sto swma
tou se ti tupo anaferetai o deiktis next */
{
int id;
struct customer *next;
} Customer;

void list_print(Customer *head);
int main ()
{
Customer *head;

head = NULL;

{
head= calloc(1,sizeof(Customer));
head->id=1;
head->next = NULL;
}

while(head!=NULL)
{
printf("%d", head->id);
head=head->next;
}
void list_print(Customer *head);


free(head->next); /* epeidi to head itan hdh katestrameno dn borousa meta na dwsw px */
free(head); /* free(head->next) */

if(head==NULL)
printf("H free dn ekane kala tin douleia tis \n");
else
printf("H mnimi eleutherwthike!");


return 0;
}
void list_print(Customer *head)
{
for(head=NULL; head->next; head=head->next)
{
printf("%d", head->id);
}
putchar('\n');
return;
}




Ειπα να "καθαρισω" λιγο τον κωδικα εννοωντας πως να βγαλω αυτο που θα επρεπε να οριζω συνεχως κομβους ας πουμε ...
αλλα στην for μου κανει ενα segmentation fault. Αυτη τη στιγμη εγω εχω βαλει τον head να δειχνει στον κομβο του 1 ή στον κομβο που διαθετει ενα πεδιο id 1 ωραια???? το head->next εδω ειναι NULL.

Και εξηγω θελω να ξεκινησω απο τον βρωμοδεικτη που δειχνει στο NULL (ok πλακα κανω λολ)
μεχρι το head->next που ειναι NULL Και αρα τερματιζει τοτε κανε head=head->next ωραια???
γιατι πεταει σφαλμα μνημης.... αυτο συμβαινει και αμα δωσω while(head) ή αμα δωσω πχ head->next!=NULL στο 2ο της for.

Mπορει να κανω καλες ερωτησεις αλλα εκεινο που με προβληματιζει ειναι οτι σαν να μπερδευεται το μυαλο μου και να μην μπορω να συνταξω κωδικα??? τεσπα θα δουμε ειναι νωρις ακομα...
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

ΠροηγούμενηΕπόμενο

Επιστροφή στο Μαθήματα C

cron