[Powered by Google Translate] [Ενότητα 6] [Περισσότερα Άνετα] [Rob Bowden] [Πανεπιστήμιο του Χάρβαρντ] [Αυτό είναι CS50.] [CS50.TV] Μπορούμε να κατευθυνθείτε προς το τμήμα μας ερωτήσεις. Έστειλα το URL για το διάστημα πριν. Η αρχή της ενότητας των ερωτήσεων πω- προφανώς δεν είμαι απόλυτα unsick-είναι μια πολύ εύκολη ερώτηση του τι ακριβώς είναι Valgrind; Τι σημαίνει valgrind κάνουμε; Όποιος θέλει να πει ό, τι valgrind κάνει; [Φοιτητικό] Έλεγχοι διαρροών μνήμης. Ναι, valgrind είναι ένας γενικός ελεγκτής μνήμης. Είναι, σε τελική ανάλυση, σας λέει αν έχετε τυχόν διαρροές μνήμης, η οποία είναι ως επί το πλείστον αυτό που το χρησιμοποιείτε για, γιατί, αν θέλετε να κάνουν καλά στο σύνολο πρόβλημα ή αν θέλετε να να πάρει την μεγάλη του σκάφους, θα πρέπει να έχετε κανένα απολύτως διαρροές μνήμης, και σε περίπτωση που έχετε μια διαρροή μνήμης που δεν μπορείτε να βρείτε, Επίσης, να έχετε κατά νου ότι κάθε φορά που ανοίγετε ένα αρχείο και αν δεν το κλείσει, αυτό είναι μια διαρροή μνήμης. Πολλοί άνθρωποι ψάχνουν για κάποιο κόμβο ότι δεν είστε απελευθερώνοντας όταν πραγματικά, δεν κλείσει το λεξικό στο πρώτο βήμα. Επίσης, σας ενημερώνει αν έχετε οποιαδήποτε άκυρη διαβάζει ή γράφει, το οποίο σημαίνει ότι αν προσπαθήσετε και να ορίσετε μια τιμή αυτό είναι πέρα ​​από το τέλος του σωρού και αυτό δεν συμβαίνει σε seg σφάλμα αλλά valgrind πιάνει, δεδομένου ότι δεν θα πρέπει πραγματικά να γράφει εκεί, και έτσι σίγουρα δεν πρέπει να έχουν κανένα από αυτά είτε. Πώς μπορείτε να χρησιμοποιήσετε Valgrind; Πώς μπορείτε να χρησιμοποιήσετε Valgrind; Είναι ένα γενικό ζήτημα της είδος του να τρέξει και να δούμε την έξοδο. Η έξοδος υπερισχύει πολλές φορές. Υπάρχει επίσης διασκέδαση όπου τα λάθη, αν έχετε κάποια τρομερά λάθος πράγμα συμβαίνει σε έναν βρόχο, τότε τελικά θα πει, "Way πάρα πολλά λάθη. Πάω να σταματήσει την καταμέτρηση τώρα. " Είναι βασικά κειμένου εξόδου που θα πρέπει να αναλύσει. Στο τέλος, θα σας πω τυχόν διαρροές μνήμης που έχετε, πόσες ομάδες, η οποία μπορεί να είναι χρήσιμα διότι αν είναι ένα unfreed μπλοκ, τότε είναι συνήθως πιο εύκολο να βρείτε από 1.000 μπλοκ unfreed. 1.000 τεμάχια unfreed σημαίνει ότι κατά πάσα πιθανότητα δεν είστε απελευθερώνοντας συνδεδεμένες λίστες σας σωστά ή κάτι τέτοιο. Που είναι Valgrind. Τώρα έχουμε το τμήμα μας ερωτήσεις, το οποίο δεν χρειάζεται να κατεβάσετε. Μπορείτε να κάνετε κλικ στο όνομά μου και τραβήξτε τους στο χώρο. Τώρα κάντε κλικ πάνω μου. Αναθεώρηση 1 θα είναι στοίβα, που κάνουμε πρώτα. Αναθεώρηση 2 θα είναι ουρά, και Αναθεώρηση 3 θα είναι η κατά μόνας συνδεδεμένη λίστα. Ξεκινώντας με το stack μας. Όπως λέει εδώ, μια στοίβα είναι ένα από τα πιο βασικά, θεμελιώδεις δομές δεδομένων της επιστήμης των υπολογιστών. Η πολύ πρωτότυπο παράδειγμα είναι η στοίβα των δίσκων στην τραπεζαρία. Είναι βασικά κάθε φορά που εισάγονται σε μια στοίβα, κάποιος πρόκειται να πει, "Ω, σαν μια στοίβα των δίσκων." Μπορείτε στοίβα τους δίσκους επάνω. Στη συνέχεια, όταν θα πάτε για να τραβήξει ένα δίσκο, ο πρώτος δίσκος που είναι να πάρει τράβηξε είναι ο τελευταίος που τέθηκε στη στοίβα. Η στοίβα επίσης-όπως λέει-εδώ έχουμε το τμήμα της μνήμης που ονομάζεται η στοίβα. Και γιατί είναι αυτό που ονομάζεται η στοίβα; Επειδή σαν μια δομή δεδομένων στοίβα, ωθεί και σκάει πλαίσια στοίβα στη στοίβα, όπου στοίβα καρέ είναι σαν μια ειδική πρόσκληση μιας συνάρτησης. Και όπως μια στοίβα, θα πρέπει πάντα να επιστρέψετε από μια κλήση συνάρτησης για να μπορέσετε να κατεβείτε σε χαμηλότερα πλαίσια στοίβα πάλι. Δεν μπορείτε να έχουν την κύρια γραμμή κλήσης foo κλήση και να επιστρέψετε στην κύρια γραμμή άμεσα. Είναι πάντα έχεις να ακολουθήσετε τη σωστή στοίβα πιέζει και σκάει. Οι δύο πράξεις, όπως είπα, είναι push και pop. Αυτά είναι καθολική άποψη. Θα πρέπει να γνωρίζετε ώθηση και ποπ άποψη των στοίβες δεν το θέμα αυτό. Θα δούμε ουρές είναι το είδος των διαφορετικών. Δεν έχει πραγματικά μια καθολική θητεία, αλλά ώθηση και pop είναι καθολική για στοίβες. Push είναι μόλις τεθεί στη στοίβα. Pop είναι απογειωθεί τη στοίβα. Και βλέπουμε εδώ έχουμε typedef struct στοίβα μας, έτσι έχουμε char ** χορδές. Μην φοβάστε να πάρετε από οποιαδήποτε **. Αυτό πρόκειται να καταλήξει να είναι μια σειρά από χορδές ή μια σειρά από δείκτες σε χαρακτήρες, όπου δείκτες σε χαρακτήρες τείνουν να είναι χορδές. Δεν πρέπει να είναι χορδές, αλλά εδώ, από όπου και αν πρόκειται να είναι χορδές. Έχουμε μια σειρά από χορδές. Έχουμε ένα μέγεθος, το οποίο αντιπροσωπεύει πόσα στοιχεία είναι σήμερα στην στοίβα, και τότε έχουμε την ικανότητα, η οποία είναι πόσα στοιχεία μπορεί να είναι στη στοίβα. Η χωρητικότητα θα πρέπει να ξεκινήσει ως κάτι μεγαλύτερο από 1, αλλά το μέγεθος πρόκειται να ξεκινήσει ως 0. Τώρα, υπάρχουν βασικά τρεις διαφορετικοί τρόποι που μπορείτε να σκεφτείτε μια στοίβα. Λοιπόν, υπάρχουν πιθανώς περισσότερο, αλλά οι δύο βασικοί τρόποι είναι μπορείτε να το εφαρμόσουν χρησιμοποιώντας μια σειρά, ή μπορείτε να το εφαρμόσουν χρησιμοποιώντας μια συνδεδεμένη λίστα. Συνδέεται λίστες είναι το είδος των ασήμαντο για να κάνουν στοίβες από. Είναι πολύ εύκολο να κάνει μια στοίβα χρησιμοποιώντας συνδεδεμένες λίστες, έτσι και εδώ, θα πάμε για να κάνει μια στοίβα με συστοιχίες, και στη συνέχεια, χρησιμοποιώντας πίνακες, υπάρχει επίσης δύο τρόποι που μπορείτε να το σκεφτώ. Πριν, όταν είπα έχουμε μια ικανότητα για τη στοίβα, έτσι ώστε να μπορούν να χωρέσουν ένα στοιχείο στη στοίβα. Ο ένας τρόπος θα μπορούσε να συμβεί είναι το συντομότερο να χτυπήσει 10 στοιχεία, τότε είστε έτοιμοι. Ίσως γνωρίζετε ότι υπάρχει ένα άνω φράγμα των 10 πράγματα στον κόσμο ότι δεν θα χρειαστεί περισσότερο από 10 πράγματα για το stack σας, περίπτωση κατά την οποία μπορείτε να έχετε ένα ανώτατο όριο για το μέγεθος του stack σας. Ή θα μπορούσατε να έχετε το stack σας είναι απεριόριστη, αλλά αν κάνετε μια σειρά, αυτό σημαίνει ότι κάθε φορά που θα χτυπήσει 10 στοιχεία, τότε θα πάμε να πρέπει να αυξηθεί σε 20 στοιχεία, και όταν χτύπησε 20 στοιχεία, εσείς πρόκειται να πρέπει να αυξηθεί σειρά σας στοιχεία σε 30 ή 40 στοιχεία. Θα πάμε να πρέπει να αυξηθεί η ικανότητα, η οποία είναι αυτό που πάμε να κάνουμε εδώ. Κάθε φορά που φθάνουν το μέγιστο μέγεθος του stack μας, όταν πιέζουμε για κάτι άλλο, θα πάμε να χρειαστεί να αυξηθεί η χωρητικότητα. Εδώ, έχουμε δηλωθεί ως ώθηση ώθηση bool (char str *). Char str * είναι η συμβολοσειρά που πιέζουμε πάνω στη στοίβα, bool και λέει μόνο αν θα επιτύχει ή αποτύχει. Πώς μπορούμε να αποτύχει; Ποια είναι η μόνη περίσταση που μπορείτε να σκεφτείτε όπου θα πρέπει να επιστρέψει false; Ναι. [Φοιτητικό] Αν είναι πλήρης και είμαστε χρησιμοποιώντας μια εφαρμογή που οριοθετείται. Ναι, ναι, πώς ορίζουμε-απάντησε αν είναι πλήρης και είμαστε χρησιμοποιώντας ένα φραγμένο εφαρμογή. Στη συνέχεια, θα επιστρέψει σίγουρα ψευδής. Από τη στιγμή που θα χτυπήσει 10 πράγματα στον πίνακα, δεν μπορεί να χωρέσει 11, έτσι ώστε να επιστρέψει false. Τι και αν είναι απεριόριστο; Ναι. Εάν δεν μπορείτε να επεκτείνετε τον πίνακα για κάποιο λόγο. Ναι, έτσι η μνήμη είναι ένας περιορισμένος πόρος, και τελικά, αν θα συνεχίσουμε να πιέζουμε τα πράγματα στη στοίβα ξανά και ξανά, θα πάμε για να προσπαθήσουμε και να διαθέσει ένα μεγαλύτερο φάσμα για να χωρέσει η μεγαλύτερη χωρητικότητα, και malloc ή οτιδήποτε άλλο που χρησιμοποιούμε πρόκειται να επιστρέψει ψευδείς. Λοιπόν, malloc θα επιστρέψει null. Θυμηθείτε, κάθε φορά που θα καλέσει ποτέ malloc, θα πρέπει να ελέγξει για να δείτε αν επιστρέφει null ή αλλιώς αυτό είναι μια αφαίρεση ορθότητα. Επειδή θέλουμε να έχουμε ένα απέραντο στοίβα, η μόνη περίπτωση θα πάμε να επιστρέψει ψευδείς είναι αν προσπαθήσουμε να αύξηση της ικανότητας και malloc ή ό, τι επιστρέφει false. Στη συνέχεια, pop δεν παίρνει ορίσματα, και επιστρέφει τη συμβολοσειρά που βρίσκεται στην κορυφή της στοίβας. Ό, τι πιο πρόσφατα έσπρωξε στη στοίβα είναι ό, τι ποπ επιστρέφει, και αφαιρεί επίσης από την στοίβα. Και παρατηρήσετε ότι επιστρέφει null αν δεν υπάρχει τίποτα στη στοίβα. Είναι πάντοτε δυνατό ότι η στοίβα είναι άδειο. Στην Java, αν έχετε συνηθίσει σε αυτό, ή σε άλλες γλώσσες, προσπαθεί να σκάσει από ένα άδειο στοίβα θα μπορούσε να προκαλέσει μια εξαίρεση ή κάτι τέτοιο. Αλλά σε C, null είναι ένα είδος πολλές από τις περιπτώσεις πώς θα χειριστεί αυτά τα προβλήματα. Επιστρέφοντας null είναι το πώς θα πάμε για να δηλώσει ότι η στοίβα ήταν άδειο. Έχουμε παρέχονται κωδικό που θα δοκιμάσουν τη λειτουργικότητα stack σας, εφαρμογή πιέστε και ποπ. Αυτό δεν θα είναι ένα πολύ κώδικα. Θα το κάνω, στην πραγματικότητα, πριν το κάνουμε αυτό, υπαινιγμός, υπαινιγμός- αν δεν το έχετε δει, malloc δεν είναι η μόνη λειτουργία που διαθέτει μνήμη στο σωρό για σας. Υπάρχουν μια οικογένεια των λειτουργιών alloc. Το πρώτο είναι η malloc, που έχετε συνηθίσει. Στη συνέχεια υπάρχει calloc, η οποία κάνει το ίδιο πράγμα με malloc, αλλά θα το μηδέν τα πάντα για σένα. Αν έχετε ποτέ ήθελε να θέσει τα πάντα σε κενή μετά mallocing κάτι θα πρέπει να έχουν χρησιμοποιηθεί μόνο calloc στην πρώτη θέση, αντί της γραφής α για το βρόχο στο μηδέν από το σύνολο του μπλοκ μνήμης. Realloc είναι σαν malloc και έχει πολλές ειδικές περιπτώσεις, αλλά βασικά αυτό που κάνει είναι realloc παίρνει ένα δείκτη που είχαν ήδη διατεθεί. Realloc είναι η λειτουργία που θέλετε να είναι η προσοχή στο σημείο αυτό. Παίρνει ένα δείκτη που είχε ήδη επιστραφεί από malloc. Ας πούμε ότι έχετε ζητήσει από malloc ένα δείκτη των 10 bytes. Στη συνέχεια, αργότερα θα διαπιστώσετε ότι ήθελε 20 bytes, έτσι ώστε να καλέσετε realloc σε αυτό το δείκτη με 20 bytes, realloc και αυτόματα θα αντιγράψει τα πάντα για εσάς. Αν ονομάζεται απλά malloc και πάλι, όπως έχω ένα μπλοκ των 10 bytes. Τώρα χρειάζομαι ένα μπλοκ των 20 bytes, οπότε αν malloc 20 bytes, τότε θα πρέπει να αντιγράψετε το χέρι πάνω από τα 10 bytes από το πρώτο πράγμα που στο δεύτερο πράγμα και στη συνέχεια δωρεάν το πρώτο πράγμα. Realloc θα χειριστεί αυτό για σας. Παρατηρήστε ότι η υπογραφή θα είναι άκυρη *, το οποίο επιστρέφει μόνο ένα δείκτη προς το μπλοκ της μνήμης, τότε άκυρη * ptr. Μπορείτε να φανταστείτε * άκυρη ως γενικό δείκτη. Σε γενικές γραμμές, ποτέ δεν ασχολούνται με * άκυρη, αλλά malloc επιστρέφει ένα κενό *, και στη συνέχεια, είναι ακριβώς χρησιμοποιείται σαν αυτό είναι πραγματικά πρόκειται να είναι ένα char *. Η προηγούμενη * κενό που είχε επιστρέψει από malloc τώρα θα πρέπει να περάσει για να realloc, και στη συνέχεια, το μέγεθος είναι ο νέος αριθμός των bytes που θέλετε να διαθέσει, έτσι νέας παραγωγικής ικανότητας σας. Θα σας δώσω μερικά λεπτά, και να το κάνουμε στο χώρο μας. Ξεκινήστε με την Αναθεώρηση 1. Θα σταματήσετε μετά ελπίζουμε για αρκετό χρόνο για να εφαρμόσει ώθηση, και στη συνέχεια, θα σας δώσω ένα άλλο διάλειμμα για να κάνει ποπ. Αλλά δεν είναι πραγματικά τόσο πολύ κώδικα σε όλα. Το πιο κώδικας είναι ίσως η επέκταση πράγματα, να αυξάνεται η ικανότητα. Εντάξει, δεν υπάρχει πίεση για να γίνει εντελώς, αλλά εφ 'όσον αισθάνεστε σαν να είστε στο σωστό δρόμο, αυτό είναι καλό. Υπάρχει κάποιος που να έχει οποιοδήποτε κώδικα αισθάνονται άνετα μαζί μου τραβώντας προς τα επάνω; Ναι, θα το κάνω, αλλά δεν έχει καμία κάποιος κωδικός που μπορώ να σηκώσει; Εντάξει, μπορεί να ξεκινήσετε, να το αποθηκεύσετε, ό, τι είναι; Ξεχάσω πάντα αυτό το βήμα. Εντάξει, κοιτάζοντας ώθηση, θέλεις να εξηγήσει τον κωδικό σας; [Φοιτητικό] Πρώτα απ 'όλα, θα αυξηθεί το μέγεθος. Υποθέτω ότι ίσως θα έπρεπε να είχα-ότι ούτως ή άλλως, θα αυξηθεί το μέγεθος, και να δω αν είναι μικρότερη από τη χωρητικότητα. Και αν είναι μικρότερη από τη χωρητικότητα, μπορώ να προσθέσω στην παράταξη που ήδη έχουμε. Και αν δεν είναι, θα πολλαπλασιάσει τη χωρητικότητα κατά 2, και εγώ την ανακατανομή σειρά χορδές σε κάτι με ένα μεγαλύτερο μέγεθος χωρητικότητας τώρα. Και στη συνέχεια, αν αυτό αποτύχει, λέω το χρήστη και να επιστρέψει ψευδείς, και αν είναι εντάξει, τότε έβαλα το string στο νέο σημείο. [Rob Β.] Επίσης, παρατηρούμε ότι χρησιμοποιήσαμε ένα ωραίο χειριστή bitwise εδώ να πολλαπλασιάζονται επί 2. Θυμηθείτε, αριστερή στροφή είναι πάντα θα πρέπει να πολλαπλασιάζεται επί 2. Δεξιά στροφή διαιρείται με το 2, αρκεί να θυμάστε ότι αυτό σημαίνει διαιρούμε με το 2 όπως σε έναν ακέραιο διαιρείται δια 2. Θα μπορούσε να περικόψει το 1 εδώ ή εκεί. Αλλά στροφή αριστερά κατά 1 είναι πάντα πρόκειται να πολλαπλασιαστεί επί 2, εκτός και αν τα όρια υπερχείλισης του ακεραίου, και τότε δεν θα είναι. Ένα σχόλιο πλευρά. Μου αρέσει να κάνω, αυτό δεν πρόκειται να αλλάξει την κωδικοποίηση με οποιονδήποτε τρόπο, αλλά μου αρέσει να κάνω κάτι τέτοιο. Είναι πραγματικά πρόκειται να γίνει λίγο περισσότερο. Ίσως αυτό δεν είναι η ιδανική περίπτωση για να δείξει αυτό, αλλά μου αρέσει να σε τμήμα αυτών των μπλοκ- εντάξει, αν αυτό, αν συμβεί αυτό, τότε θα πάω να κάνω κάτι, και στη συνέχεια η λειτουργία γίνεται. Δεν χρειάζεται να μετακινηθείτε προς τα μάτια μου σε όλη τη διαδρομή κάτω από τη λειτουργία για να δούμε τι θα συμβεί μετά το άλλο. Είναι αν αυτό εάν συμβεί κάτι τέτοιο, τότε θα επιστρέψει ακριβώς. Έχει επίσης το ωραίο πρόσθετο όφελος των πάντων πέρα ​​από αυτό τώρα μετατίθενται αριστερά μία φορά. Εγώ δεν χρειάζεται πλέον να-αν ποτέ κοντά γελοία παραγάδια, τότε τα 4 byte μπορεί να βοηθήσει, και, επίσης, η πιο αριστερά είναι κάτι, το λιγότερο αισθάνεστε συγκλονισμένοι αν θέλετε-εντάξει, έχω να θυμάμαι Είμαι σήμερα σε ένα βρόχο, ενώ στο εσωτερικό του άλλου μέσα από ένα βρόχο for. Οπουδήποτε μπορείτε να κάνετε αυτήν την επιστροφή αμέσως, κάτι σαν. Είναι εντελώς προαιρετική και δεν αναμένεται σε καμία περίπτωση. [Φοιτητικό] Πρέπει να υπάρχει ένα μέγεθος - σε κατάσταση αποτυχίας; Η κατάσταση εδώ είναι αποτυχία που δεν realloc, οπότε ναι. Παρατηρήστε πως στην κατάσταση βλάβης, κατά πάσα πιθανότητα, εκτός και αν εμείς δωρεάν πράγματα αργότερα, είμαστε πάντα θα αποτύχει Δεν έχει σημασία πόσες φορές προσπαθούμε να προωθήσουμε κάτι. Αν συνεχίσουμε να πιέζουμε, κρατάμε προσαύξηση μέγεθος, ακόμα κι αν δεν είμαστε τίποτα βάζοντας πάνω στη στοίβα. Συνήθως δεν αυξήσετε το μέγεθος μέχρι αφού έχουμε θέσει με επιτυχία στη στοίβα. Εμείς θα το κάνουμε, ας πούμε, είτε εδώ και εδώ. Και στη συνέχεια, αντί να λέει s.size ≤ ικανότητα, είναι λιγότερο από ό, τι ικανότητα, μόνο και μόνο επειδή περάσαμε, όπου τα πάντα ήταν. Και, θυμηθείτε το μόνο μέρος που θα μπορούσε ενδεχομένως να επιστρέψει false Είναι εδώ, όπου realloc επέστρεψε null, και αν τύχει να θυμάστε τυπικό σφάλμα, ίσως θα μπορούσε να εξετάσει αυτό μια περίπτωση κατά την οποία θέλετε να εκτυπώσετε ένα τυπικό σφάλμα, έτσι fprintf stderr αντί απλά να τυπώνουν απευθείας από πρότυπο. Και πάλι, αυτό δεν είναι η προσδοκία, αλλά αν είναι λάθος, πληκτρολογήστε printf, τότε ίσως να θέλετε να το εκτυπώσετε σε τυπικό σφάλμα, αντί του στάνταρ έξω. Όποιος έχει κάτι άλλο να σημειώσουμε; Ναι. [Φοιτητικό] Μπορείς να πάει πάνω από το [δεν ακούγεται]; [Rob Β.] Ναι, η πραγματική binariness του ή απλά τι είναι; [Φοιτητικό] Έτσι, μπορείτε να το πολλαπλασιάσετε με το 2; [Rob Β.] Ναι, βασικά. Στο δυαδικό γη, έχουμε πάντα μας σύνολο των ψηφίων. Η μετατόπιση αυτή την αριστερά κατά 1 βασικά αυτό εισάγει εδώ στη δεξιά πλευρά. Πίσω από αυτό, απλά να θυμόμαστε ότι τα πάντα σε δυαδική είναι μία δύναμη του 2, οπότε αυτό αντιπροσωπεύει 2 στο 0, αυτό το 2 στο 1, αυτό το 2 στο 2. Με την εισαγωγή ενός 0 έως τη δεξιά πλευρά τώρα, έχουμε αλλάξει τα πάντα πάνω. Αυτό που κάποτε ήταν 2 προς το μηδέν είναι πλέον 2 στο 1, 2 στο 2. Η δεξιά πλευρά που εισάγεται πρόκειται απαραιτήτως να είναι 0, που έχει νόημα. Αν πολλαπλασιάσει ποτέ έναν αριθμό με το 2, δεν πρόκειται να καταλήξουμε περίεργο, έτσι ώστε το 2 προς τον τόπο 0 πρέπει να είναι 0, και αυτό είναι αυτό που προειδοποίησε για ένα δεύτερο είναι, αν πριν το κάνετε να συμβεί για να μετατοπίσει πέρα από τον αριθμό των bits σε έναν ακέραιο τότε αυτό το 1 πρόκειται να καταλήξουν μακριά. Αυτό είναι το μόνο ανησυχία, αν τυχαίνει να ασχολείται με πραγματικά μεγάλες δυνατότητες. Αλλά σε αυτό το σημείο, τότε έχουμε να κάνουμε με μια σειρά από δισεκατομμύρια των πραγμάτων, το οποίο δεν θα μπορούσε να χωρέσει σε μνήμη ούτως ή άλλως. Τώρα μπορούμε να προχωρήσουμε σε ποπ, η οποία είναι ακόμη πιο εύκολο. Θα μπορούσατε να μου αρέσει αν τύχει να σκάσει ένα σωρό, και τώρα είστε στο μισό ικανότητα και πάλι. Θα μπορούσατε να realloc να συρρικνωθεί το μέγεθος της μνήμης που έχετε, αλλά δεν έχετε να ανησυχείτε για αυτό, έτσι η μόνη περίπτωση realloc πρόκειται να είναι αυξανόμενη μνήμη, ποτέ συρρίκνωση της μνήμης, το οποίο πρόκειται να κάνει ποπ εξαιρετικά εύκολο. Τώρα ουρές, οι οποίες πρόκειται να είναι όπως στοίβες, αλλά η εντολή που θα πάρουμε τα πράγματα από αντιστρέφεται. Ο πρωτότυπος παράδειγμα μια ουρά είναι μια γραμμή, οπότε υποθέτω αν ήταν αγγλικά, θα έλεγα ένα πρωτότυπο παράδειγμα μιας ουράς είναι μια ουρά. Έτσι, σαν μια γραμμή, εάν είστε το πρώτο πρόσωπο στη γραμμή, περιμένετε να είναι το πρώτο πρόσωπο από τη γραμμή. Εάν είστε το τελευταίο άτομο στη γραμμή, θα έχετε την ευκαιρία να είναι το τελευταίο πρόσωπο εξυπηρετούνται. Καλούμε αυτό το μοτίβο FIFO, ενώ ήταν στοίβα LIFO μοτίβο. Αυτά τα λόγια είναι αρκετά καθολική. Όπως και σε αντίθεση με στοίβες συστοιχίες, ουρές τυπικώς δεν επιτρέπουν την πρόσβαση σε στοιχεία στην μέση. Εδώ, μια στοίβα, έχουμε ώθηση και ποπ. Εδώ, τυχαίνει να έχουν καλέσει τους enqueue και dequeue. Έχω επίσης ακούσει να λέγεται μετατόπιση και unshift. Έχω ακούσει ανθρώπους να λένε ποπ ώθηση και να ισχύουν και για τις ουρές. Έχω ακούσει τοποθετείτε, αφαιρείτε, έτσι ώθηση και ποπ, αν μιλάμε για στοίβες, σας πιέζουν και σκάει. Αν μιλάμε για ουρές, θα μπορούσατε να πάρετε τις λέξεις που θέλετε να χρησιμοποιήσετε για την εισαγωγή και την αφαίρεση, και δεν υπάρχει συναίνεση σχετικά με το τι θα έπρεπε να λέγεται. Αλλά εδώ, έχουμε enqueue και dequeue. Τώρα, η struct μοιάζει σχεδόν ίδιο με το struct στοίβας. Αλλά θα πρέπει να παρακολουθείτε το κεφάλι. Υποθέτω ότι λέει εδώ κάτω, αλλά γιατί χρειαζόμαστε το κεφάλι; Τα πρωτότυπα είναι βασικά ίδια με ωθήσει και ποπ. Μπορείτε να σκεφτείτε από το ως ώθηση και ποπ. Η μόνη διαφορά είναι ποπ επιστρέφει, αντί του τελευταίου, αυτό είναι το πρώτο επιστροφή. 2, 1, 3, 4, ή κάτι τέτοιο. Και εδώ είναι η αρχή. Ουρά μας είναι τελείως γεμάτο, οπότε υπάρχουν τέσσερα στοιχεία σε αυτό. Το τέλος της ουράς μας είναι επί του παρόντος 2, και τώρα πάμε να εισάγετε κάτι άλλο. Όταν θέλετε να εισαγάγετε αυτό το κάτι άλλο, ό, τι κάναμε για την έκδοση στοίβα είναι να επεκταθεί μπλοκ της μνήμης μας. Ποιο είναι το πρόβλημα με αυτό; [Φοιτητικό] Μπορείτε να μετακινήσετε το 2. Αυτό που είπα πριν για το τέλος της ουράς, αυτό δεν έχει νόημα να αρχίσουμε σε 1, τότε θέλουμε να dequeue 1, τότε dequeue 3, τότε dequeue 4, τότε dequeue 2, dequeue τότε αυτό το ένα. Εμείς δεν μπορούμε να χρησιμοποιήσουμε realloc τώρα, ή τουλάχιστον, θα πρέπει να χρησιμοποιήσετε realloc με διαφορετικό τρόπο. Αλλά ίσως δεν θα πρέπει να χρησιμοποιούν μόνο realloc. Θα έχετε την ευκαιρία να χρειαστεί να αντιγράψετε το χέρι μνήμη σας. Υπάρχουν δύο λειτουργίες για να αντιγράψετε τη μνήμη. Υπάρχει memcopy και memmove. Διαβάζω σήμερα τις σελίδες man για να δείτε ποιο θα πάμε να θέλετε να χρησιμοποιήσετε. Εντάξει, memcopy, η διαφορά είναι ότι memcopy και memmove, ένας χειρίζεται την υπόθεση σωστά Όπου και αν αντιγράψετε σε μια περιοχή που συμβαίνει να συμπίπτουν με την περιοχή πραγματοποιείτε αντιγραφή. Memcopy δεν το χειριστεί. Memmove κάνει. Μπορείτε να σκεφτείτε το πρόβλημα που- Ας πούμε ότι θέλετε να αντιγράψετε αυτόν τον τύπο, αυτά τα τέσσερα για αυτόν τον τύπο πάνω. Στο τέλος, ποια είναι η σειρά πρέπει να μοιάσει μετά το αντίγραφο είναι 2, 1, 2, 1, 3, 4, και στη συνέχεια κάποια πράγματα στο τέλος. Αλλά αυτό εξαρτάται από την σειρά με την οποία έχουμε πραγματικά αντιγραφή, δεδομένου ότι, αν δεν ληφθεί υπόψη το γεγονός ότι η περιοχή είμαστε σε αντιγραφή επικαλύπτει το ένα είμαστε αντιγραφή από, τότε θα μπορούσαμε να κάνουμε σαν αρχή εδώ, αντιγράψτε το 2 στο μέρος που θέλετε να πάτε, στη συνέχεια να προχωρήσουμε προς τα εμπρός δείκτες μας. Τώρα θα πάμε να είναι εδώ και εδώ, και τώρα θέλετε να αντιγράψετε αυτός ο τύπος για αυτόν τον τύπο και να προχωρήσουμε προς τα εμπρός δείκτες μας. Τι θα πάμε να καταλήξετε είναι 2, 1, 2, 1, 2, 1 αντί της κατάλληλης 2, 1, 2, 1, 3, 4, επειδή 2, 1 αγνόησε την αρχική 3, 4. Memmove ότι χειρίζεται σωστά. Στην περίπτωση αυτή, βασικά ακριβώς να χρησιμοποιείτε πάντα memmove επειδή χειρίζεται σωστά. Γενικά, δεν εκτελέσει οποιαδήποτε χειρότερα. Η ιδέα είναι αντί της ξεκινώντας από την αρχή και με αυτόν τον τρόπο η αντιγραφή όπως εμείς μόλις έκανε εδώ, αρχίζει από το τέλος και αντιγράφει σε, και σε αυτή την περίπτωση, δεν μπορείτε ποτέ να έχετε ένα πρόβλημα. Δεν υπάρχει καμία απόδοση χαθεί. Πάντα να χρησιμοποιείτε memmove. Ποτέ μην ανησυχείτε για memcopy. Και αυτό είναι που θα πάμε να πρέπει να χωριστά memmove το τυλιγμένο γύρω-τμήμα της ουράς σας. Μην ανησυχείτε αν δεν γίνει εντελώς. Αυτό είναι πιο δύσκολο από ό, τι στοίβα, ώθηση, και ποπ. Όποιος έχει οποιοδήποτε κώδικα θα μπορούσε να συνεργαστεί με; Ακόμα και αν εντελώς ελλιπής; [Φοιτητικό] Ναι, είναι τελείως ελλιπείς, εν τούτοις. Εντελώς ελλιπής είναι μια χαρά όσο εμείς-μπορεί να σας σώσει την αναθεώρηση; Ξεχάσω ότι κάθε φορά. Εντάξει, αγνοώντας τι συμβαίνει όταν πρέπει να αλλάξετε το μέγεθος πράγματα. Εντελώς αγνοούν resize. Εξηγήστε αυτόν τον κώδικα. Φεύγω πρώτα από όλα, εάν το μέγεθος είναι μικρότερο από το αντίγραφο καταρχάς και στη συνέχεια, μετά από αυτό, βάζω-παίρνω το κεφάλι + μέγεθος, και εγώ να βεβαιωθείτε ότι αναδιπλώνεται γύρω από την χωρητικότητα της συστοιχίας, και βάζω τη νέα σειρά σε αυτή τη θέση. Τότε θα αυξήσει το μέγεθος και την επιστροφή αλήθεια. [Rob Β.] Αυτό είναι σίγουρα μία από εκείνες τις περιπτώσεις όπου θα πάμε να θέλουν να χρησιμοποιούν mod. Κάθε είδους περίπτωση που έχετε περιτύλιγμα γύρω, αν νομίζετε ότι περιτύλιγμα γύρω, η άμεση σκέψη θα πρέπει να είναι mod. Ως μια γρήγορη βελτιστοποίηση / κωδικό σας κάνουν μια γραμμή μικρότερη, θα παρατηρήσετε ότι η γραμμή αμέσως μετά αυτό το ένα είναι ακριβώς το μέγεθος + +, έτσι ώστε να συγχωνευθούν ότι σε αυτή τη γραμμή, το μέγεθος + +. Τώρα εδώ κάτω, έχουμε την περίπτωση όπου δεν έχουμε αρκετή μνήμη, έτσι αυξάνουμε την ικανότητά μας με το 2. Υποθέτω ότι θα μπορούσατε να έχετε το ίδιο πρόβλημα εδώ, αλλά μπορούμε να το αγνοήσουμε τώρα, όπου κι αν αποτύχει να αυξήσει την ικανότητά σας, τότε θα πάμε να θέλουν να μειωθεί η ικανότητά σας κατά 2 ξανά. Άλλο ένα σύντομο σημείωμα είναι ακριβώς όπως μπορείτε να κάνετε + =, μπορείτε επίσης να κάνετε << =. Σχεδόν οτιδήποτε μπορεί να πάει πριν ισούται, + =, | =, & = << =. Char * νέα είναι νέο μπλοκ της μνήμης μας. Ω, εδώ. Τι κάνουν οι άνθρωποι σκέφτονται για τον τύπο του νέου μπλοκ της μνήμης μας; [Φοιτητικό] Θα πρέπει να είναι char **. Ανακαλώντας στη μνήμη struct μας εδώ, χορδές είναι αυτό που ανακατανομή. Κάνουμε μια ολόκληρη νέα δυναμική αποθήκευση των στοιχείων στην ουρά. Τι θα πάμε να υπαγωγή στις χορδές σας είναι ό, τι είμαστε τώρα mallocing, και έτσι οι νέες πρόκειται να είναι ένα char **. Είναι πρόκειται να είναι μια σειρά από χορδές. Τότε ποια είναι η περίπτωση σύμφωνα με την οποία θα πάμε να επιστρέψει false; [Φοιτητικό] Θα πρέπει να κάνουμε το char *; [Rob Β.] Ναι, καλή κλήση. [Φοιτητικό] Τι ήταν αυτό; [Rob Β.] Θέλαμε να κάνουμε το μέγεθος του char * επειδή δεν είμαστε πλέον- αυτό θα ήταν πράγματι ένα πολύ μεγάλο πρόβλημα, διότι sizeof (char) θα είναι 1. Sizeof char * πρόκειται να είναι 4, έτσι πολλές φορές, όταν έχουμε να κάνουμε με ints, έχετε την τάση να πάρετε μακριά με αυτό, επειδή το μέγεθος του int και το μέγεθος του int * σε 32-bit σύστημα πρόκειται να είναι το ίδιο πράγμα. Αλλά εδώ, sizeof (char) και sizeof (char *) είναι τώρα πρόκειται να είναι το ίδιο πράγμα. Ποια είναι η περίσταση όπου θα επιστρέψει false; [Φοιτητικό] Νέα είναι μηδενική. Ναι, αν είναι νέα null, θα επιστρέψει false, και Πάω να ρίξει εδώ κάτω- [Φοιτητών] [δεν ακούγεται] [Rob Β.] Ναι, αυτό είναι καλό. Θα μπορούσατε να το κάνετε είτε 2 φορές ικανότητα ή αλλαγή χωρητικότητας 1 και στη συνέχεια το μόνο που εδώ κάτω ή οτιδήποτε άλλο. Θα το κάνουμε εμείς ως είχε. Χωρητικότητα >> = 1. Και δεν πρόκειται ποτέ να χρειάζεται να ανησυχείτε για να χάσει τη θέση του για 1 γιατί έφυγες μετατοπιστεί κατά 1, έτσι η θέση του 1 είναι κατ 'ανάγκη ένα 0, τόσο δεξιά στροφή από 1, είστε ακόμα πρόκειται να είναι μια χαρά. [Φοιτητικό] Μήπως πρέπει να το κάνουμε αυτό πριν από την επιστροφή; [Rob Β.] Ναι, αυτό έχει απολύτως κανένα νόημα. Ας υποθέσουμε τώρα ότι θα πάμε να καταλήξετε επιστρέφουν αλήθεια για το τέλος. Ο τρόπος που θα πάμε να κάνουμε αυτές τις memmoves, πρέπει να είμαστε προσεκτικοί με το πώς μπορούμε να κάνουμε. Υπάρχει κάποιος που έχει κάποιες προτάσεις για το πώς μπορούμε να κάνουμε; Εδώ είναι αρχή μας. Αναπόφευκτα, θέλουμε να ξεκινήσουμε από την αρχή και πάλι και δραστηριότητες αντίγραφο σε από εκεί, 1, 3, 4, 2. Πώς μπορείτε να το κάνετε αυτό; Κατ 'αρχάς, πρέπει να δούμε την σελίδα man για memmove πάλι. Memmove, σειρά επιχειρημάτων είναι πάντα σημαντικό. Θέλουμε προορισμός μας πρώτη, δεύτερη πηγή, το τρίτο μέγεθος. Υπάρχουν πολλές λειτουργίες που αντιστρέφουν προέλευσης και προορισμού. Προορισμός, πηγή τείνει να είναι κάπως συνεπής. Μετακίνηση, τι είναι αυτό που επιστρέφει; Επιστρέφει ένα δείκτη προς τον προορισμό, για οποιοδήποτε λόγο, μπορεί να θέλετε να. Μπορώ να το διαβάσετε εικόνα, αλλά θέλουμε να προχωρήσουμε σε προορισμό μας. Τι είναι ο προορισμός μας θα πρέπει να; [Φοιτητικό] Νέα. [Rob Β.] Ναι, και όπου είμαστε από αντιγραφή; Το πρώτο πράγμα που αντιγράφετε είναι αυτό το 1, 3, 4. Ποιο είναι το αυτό-1, 3, 4. Ποια είναι η διεύθυνση αυτού του 1; Ποια είναι η διεύθυνση του εν λόγω 1; [Φοιτητών] [δεν ακούγεται] [Rob Β.] Επικεφαλής + η διεύθυνση του πρώτου στοιχείου. Πώς να πάρει το πρώτο στοιχείο του πίνακα; [Φοιτητικό] Ουρά. [Rob Β.] Ναι, q.strings. Να θυμάστε, εδώ, το κεφάλι μας είναι 1. Καταριέται αυτό. Απλά πιστεύω ότι είναι μαγικά- Εδώ, το κεφάλι μας είναι 1. Πάω να αλλάξετε το χρώμα μου πάρα πολύ. Και εδώ είναι χορδές. Αυτό μπορούμε να το γράψετε είτε όπως κάναμε εδώ με το κεφάλι + q.strings. Πολλοί άνθρωποι, επίσης, να το γράψετε και q.strings [κεφάλι]. Αυτό δεν είναι πραγματικά είναι λιγότερο αποτελεσματική. Μπορείτε να σκεφτείτε από το όπως εσείς την εύρεση τιμών και στη συνέχεια να πάρει τη διεύθυνση του, αλλά ο compiler δεν πρόκειται να το μεταφράσει σε ό, τι είχαμε πριν από ούτως ή άλλως, q.strings + κεφάλι. Είτε έτσι είτε αλλιώς θέλετε να το σκέφτομαι αυτό. Και πόσα bytes θέλουμε να αντιγράψετε; [Φοιτητικό] Χωρητικότητα - το κεφάλι. Χωρητικότητα - το κεφάλι. Και τότε θα μπορούσε πάντα να γράψουν ένα παράδειγμα να καταλάβω αν αυτό είναι σωστό. [Φοιτητικό] Πρέπει να διαιρείται με το 2 τότε. Ναι, έτσι υποθέτω ότι θα μπορούσε να χρησιμοποιήσει το μέγεθος. Έχουμε ακόμα το μέγεθος είναι- χρησιμοποιώντας το μέγεθος, έχουμε το μέγεθος ίσο προς 4. Μέγεθος μας είναι 4. Το κεφάλι μας είναι 1. Θέλουμε να αντιγράψετε αυτά τα 3 στοιχεία. Αυτή είναι η λογική ελέγχει ότι το μέγεθος - το κεφάλι είναι σωστά 3. Και επιστρέφοντας εδώ, όπως είπαμε πριν, αν χρησιμοποιείται ικανότητα, τότε θα είχαμε να διαιρούμε με το 2 επειδή έχουμε μεγαλώσει ήδη την ικανότητά μας, έτσι αντ 'αυτού, θα πάμε να χρησιμοποιήσετε το μέγεθος. Που αντιγράφει το τμήμα. Τώρα, θα πρέπει να αντιγράψετε το άλλο τμήμα, το τμήμα που έχει απομείνει από την αρχή. Αυτό πρόκειται να memmove σε ποια θέση; [Φοιτητικό] Μέγεθος Plus - κεφάλι. Ναι, γι 'αυτό έχουν ήδη αντιγραφεί σε μέγεθος - bytes κεφάλι, και έτσι όπου θέλετε να αντιγράψετε τα υπόλοιπα bytes είναι νέα και στη συνέχεια το μέγεθος μείον-καλά, ο αριθμός των bytes που έχουμε ήδη αντιγραφεί μέσα Και στη συνέχεια, όταν εμείς από την αντιγραφή; [Φοιτητικό] Q.strings [0]. [Rob Β.] Ναι, q.strings. Θα μπορούσαμε να κάνουμε και είτε q.strings [0]. Αυτό είναι σημαντικά λιγότερο κοινή από αυτό. Αν είναι ακριβώς πρόκειται να είναι 0, τότε θα έχουν την τάση να δείτε q.strings. Αυτό είναι όπου είμαστε από αντιγραφή. Πόσα bytes δεν έχουμε αφήσει να αντιγράψετε; >> [Φοιτητικό] 10. Δεξιά. [Φοιτητικό] Μήπως πρέπει να πολλαπλασιαστούν 5 έως 10 φορές το μέγεθος των bytes ή κάτι άλλο; Ναι, έτσι αυτό είναι όπου-τι ακριβώς είμαστε αντιγραφή; [Φοιτητών] [δεν ακούγεται] Ποιο είναι το είδος του πράγματος είμαστε αντιγραφή; [Φοιτητών] [δεν ακούγεται] Ναι, έτσι το char * s που είμαστε αντιγραφή, δεν γνωρίζουμε εάν αυτά προέρχονται από. Λοιπόν, εκεί που δείχνει να, σαν τις χορδές, καταλήγουμε σπρώχνοντάς το επάνω στην ουρά ή enqueuing επάνω στην ουρά. Όταν αυτά προέρχονται από, δεν έχουμε ιδέα. Πρέπει απλώς να παρακολουθείτε την char * s οι ίδιοι. Δεν θέλουμε να αντιγράψετε το μέγεθος - bytes κεφάλι. Θέλουμε να αντιγράψετε το μέγεθος - το κεφάλι char * s, έτσι θα πάμε να πολλαπλασιάσει αυτό με sizeof (char *). Ίδιο εδώ κάτω, το κεφάλι * sizeof (char *). [Φοιτητικό] Τι γίνεται με [δεν ακούγεται]; Το δικαίωμα αυτό εδώ; [Φοιτητικό] Όχι, κάτω από αυτό, το μέγεθος - το κεφάλι. [Rob Β.] Το δικαίωμα αυτό εδώ; Αριθμητική δείκτη. Πώς αριθμητική δείκτη πρόκειται να λειτουργήσει είναι πολλαπλασιάζει αυτόματα από το μέγεθος του τύπου ότι έχουμε να κάνουμε με. Ακριβώς όπως και εδώ, νέα + (μέγεθος - κεφάλι) είναι ακριβώς ισοδύναμη με νέο & [μέγεθος - το κεφάλι] μέχρι να αναμένουμε ότι για να λειτουργήσει σωστά, από το αν έχουμε να κάνουμε με έναν int πίνακα, τότε δεν με δείκτη int- ή αν είναι το μέγεθος των 5 και θέλετε το 4ο στοιχείο, τότε ο δείκτης σε int array [4]. Μπορείτε μην τα-[4] * μέγεθος του int. Αυτό είναι χειρίζεται αυτόματα, και αυτή η υπόθεση Είναι κυριολεκτικά ισοδύναμο, έτσι ώστε η σύνταξη βραχίονα είναι ακριβώς πρόκειται να μετατραπεί σε αυτό το συντομότερο κάνετε compile. Αυτό είναι κάτι που πρέπει να είστε προσεκτικοί από αυτό όταν προσθέτετε το μέγεθος - το κεφάλι προσθέτετε όχι ένα byte. Είσαι προσθήκη ενός char *, το οποίο μπορεί να είναι ένα byte ή οτιδήποτε άλλο. Άλλες ερωτήσεις; Εντάξει, dequeue πρόκειται να είναι εύκολο. Θα σας δώσω ένα λεπτό για να εφαρμόσουν. Ω, και υποθέτω ότι αυτή είναι η ίδια κατάσταση όπου τι η enqueue περίπτωση, εάν είμαστε enqueuing null, ίσως θέλουμε να το χειριστεί, ίσως δεν το κάνουμε. Εμείς δεν θα το κάνουμε και πάλι εδώ, αλλά ίδια με την περίπτωση stack μας. Αν enqueue null, θα μπορούσαμε να θέλουμε να το αγνοήσει. Όποιος έχει κάποιο κώδικα μπορώ να σηκώσει; [Φοιτητικό] Έχω μόλις dequeue. Έκδοση 2 είναι ότι, εντάξει. Θέλετε να εξηγήσει; [Φοιτητικό] Κατ 'αρχάς, μπορείτε να βεβαιωθείτε ότι δεν υπάρχει κάτι στην ουρά και ότι το μέγεθος θα είναι κάτω από το 1. Θα πρέπει να το κάνουμε αυτό, και στη συνέχεια μπορείτε να επιστρέψετε το κεφάλι και στη συνέχεια μετακινήστε το κεφάλι μέχρι 1. Εντάξει, έτσι υπάρχει μια περίπτωση γωνία πρέπει να εξετάσουμε. Ναι. [Φοιτητικό] Αν το κεφάλι σας είναι το τελευταίο στοιχείο, τότε δεν θέλετε να το κεφάλι έξω από το σημείο του πίνακα. Ναι, έτσι ώστε μόλις το κεφάλι χτυπά το τέλος της σειρά μας, όταν εμείς dequeue, το κεφάλι μας θα πρέπει να modded πίσω στο 0. Δυστυχώς, δεν μπορούμε να το κάνουμε αυτό σε ένα βήμα. Υποθέτω ότι με τον τρόπο που θα καθορίσει κατά πάσα πιθανότητα θα είναι αυτό πρόκειται να είναι ένα char *, τι είμαστε επιστροφή, ό, τι όνομα της μεταβλητής σας θέλει να είναι. Στη συνέχεια, θέλουμε να mod το κεφάλι από την ικανότητά μας και στη συνέχεια επιστρέφουν ret. Πολλοί άνθρωποι εδώ θα μπορούσαν να κάνουν- αυτή είναι η περίπτωση της-θα δούμε αν οι άνθρωποι κάνουν το κεφάλι είναι μεγαλύτερη από την ικανότητα, κάντε το κεφάλι - ικανότητα. Και αυτό είναι ακριβώς που εργάζονται γύρω από το τι είναι mod. Επικεφαλής mod = ικανότητα είναι πολύ πιο καθαρά του περιτύλιγμα γύρω από ό, τι αν το κεφάλι μεγαλύτερη από το κεφάλι ικανότητα - ικανότητα. Ερωτήσεις; Εντάξει, το τελευταίο πράγμα που μας έχει απομείνει είναι συνδεδεμένη λίστα μας. Μπορεί να χρησιμοποιηθεί για μερικές από τις συμπεριφορές που συνδέονται με λίστα, αν κάνατε συνδεδεμένες λίστες σε πίνακες κατακερματισμού σας, αν κάνατε ένα πίνακα κατακερματισμού. Συνιστώ ανεπιφύλακτα να κάνει ένα πίνακα κατακερματισμού. Μπορεί να έχουν κάνει ήδη μια trie, αλλά προσπαθεί είναι πιο δύσκολο. Στη θεωρία, είναι ασυμπτωτικά καλύτερα. Αλλά μόλις δούμε τη μεγάλη του σκάφους, και προσπαθεί ποτέ να κάνουμε κάτι καλύτερο, και καταλαμβάνουν περισσότερο χώρο στη μνήμη. Τα πάντα προσπαθεί για καταλήγει να είναι χειρότερο για περισσότερη δουλειά. Είναι αυτό που ο David Malan λύση είναι πάντα είναι αυτός δημοσιεύσεις πάντα trie λύση του, και ας δούμε πού είναι σήμερα. Τι ήταν αυτός κάτω, David J; Είναι # 18, οπότε αυτό δεν είναι τρομερά κακό, και αυτό πρόκειται να είναι ένα από τα καλύτερα προσπαθεί μπορείτε να σκεφτείτε ή ένα από τα καλύτερα προσπαθεί ενός δραστήριoτητα. Δεν είναι καν πρωτότυπη λύση του; Νιώθω σαν trie λύσεις τείνουν να είναι περισσότερο σε αυτό το εύρος της χρήσης μνήμης RAM. Πηγαίνετε μέχρι την κορυφή, και μνήμη RAM χρήση είναι σε μονοψήφια. Κατεβείτε προς τα κάτω, και τότε θα αρχίσετε να βλέπετε προσπαθεί όπου μπορείτε να πάρετε απολύτως μαζική χρήση RAM, και προσπαθεί είναι πιο δύσκολη. Δεν είναι εντελώς αξίζει τον κόπο, αλλά μια εκπαιδευτική εμπειρία, αν κάνατε ένα. Το τελευταίο πράγμα που είναι συνδεδεμένη λίστα μας, και αυτά τα τρία πράγματα, στοίβες, ουρές, και συνδεδεμένες λίστες, οποιαδήποτε μελλοντική πράγμα που κάνετε πάντα στην επιστήμη των υπολογιστών Θα υποθέσουμε ότι έχετε εξοικείωση με αυτά τα πράγματα. Είναι ακριβώς τόσο θεμελιώδες για τα πάντα. Συνδέεται λίστες, και εδώ έχουμε μια μεμονωμένα συνδεδεμένη λίστα πρόκειται να είναι εφαρμογή μας. Τι σημαίνει μεμονωμένα συνδέονται σε αντίθεση με διπλά συνδέονται; Ναι. [Φοιτητικό] Επισημαίνει μόνο στο επόμενο δείκτη αντί για τους δείκτες, όπως εκείνη που προηγείται και το ένα μετά από αυτό. Ναι, έτσι σε μορφή εικόνας, τι έκανα ακριβώς κάνουν; Έχω δύο πράγματα. Έχω εικόνα και εικόνα. Σε μορφή εικόνας, μεμονωμένα συνδεδεμένες λίστες μας, αναπόφευκτα, θα έχουν κάποιο είδος του δείκτη στο κεφάλι του καταλόγου μας, και στη συνέχεια μέσα στη λίστα μας, έχουμε μόλις δείκτες, και ίσως αυτό δείχνει σε null. Είναι πρόκειται να είναι τυπικό το σχέδιό σας από μια λίστα που συνδέονται με μεμονωμένα. Μια διπλά συνδεδεμένη λίστα, μπορείτε να πάτε πίσω. Αν μπορώ να σας δώσω καμία κόμβος στη λίστα, τότε μπορείτε να πάρετε οπωσδήποτε να οποιοδήποτε άλλο κόμβο στον κατάλογο εάν είναι μια διπλά συνδεδεμένη λίστα. Αλλά αν σου φέρω το τρίτο κόμβο στη λίστα και είναι μια μεμονωμένα συνδεδεμένη λίστα, κανένας τρόπος εσείς πρόκειται ποτέ να φτάσουμε στην πρώτη και δεύτερη κόμβους. Και υπάρχουν οφέλη και μειονεκτήματα, και μία προφανής είναι να πάρετε περισσότερο το μέγεθος, και θα πρέπει να παρακολουθείτε πού αυτά τα πράγματα δείχνουν τώρα. Αλλά μόνο νοιάζονται για μεμονωμένα συνδέονται. Λίγα πράγματα θα πάμε να πρέπει να εφαρμόσουν. Typedef struct κόμβος σας, int i: struct node * επόμενος? Κόμβο. Αυτό typedef πρέπει να καεί στο μυαλό σας. Quiz 1 θα πρέπει να δώσει μια παρόμοια typedef ενός συνδεδεμένου κόμβου λίστα, και θα πρέπει να είναι σε θέση να κακογράφω ότι αμέσως κάτω χωρίς καν να το σκεφτούμε. Υποθέτω ότι ένα ζευγάρι ερωτήσεις, γιατί χρειαζόμαστε struct εδώ; Γιατί δεν μπορούμε να πούμε κόμβο *; [Φοιτητών] [δεν ακούγεται] Ναι. Το μόνο πράγμα που καθορίζει ένα κόμβο ως ένα πράγμα είναι το ίδιο το typedef. Αλλά από αυτό το σημείο, όταν είμαστε το είδος της ανάλυσης μέσω του κόμβου αυτού του ορισμού struct, δεν έχουμε τελειώσει ακόμα typedef μας, έτσι ώστε από το typedef δεν έχει τελειώσει, κόμβος δεν υπάρχει. Αλλά struct κόμβος κάνει, και αυτός ο κόμβος εδώ, αυτό θα μπορούσε επίσης να ονομάζεται οτιδήποτε άλλο. Αυτό θα μπορούσε να ονομαστεί n. Θα μπορούσε να ονομαστεί συνδεδεμένη κόμβο λίστας. Θα μπορούσε να λέγεται τίποτα. Αλλά αυτός ο κόμβος struct πρέπει να λέγεται το ίδιο πράγμα με αυτό τον κόμβο struct. Αυτό εσείς το λέτε αυτό, θα πρέπει επίσης να είναι εδώ, και έτσι ώστε να απαντά, επίσης, το δεύτερο σημείο της ερώτησης η οποία είναι ο λόγος, πολλές φορές όταν βλέπεις structs και typedefs της structs, θα δείτε ανώνυμο structs όπου θα δείτε ακριβώς typedef struct, εφαρμογή του struct, λεξικό, ή οτιδήποτε άλλο. Γιατί εδώ δεν χρειάζεται να πούμε κόμβο; Γιατί δεν μπορεί να είναι μια ανώνυμη struct; Είναι σχεδόν η ίδια απάντηση. [Φοιτητικό] Θα πρέπει να αναφερθεί ότι στο πλαίσιο του struct. Ναι, στο πλαίσιο του struct, θα πρέπει να αναφερθώ στην ίδια struct. Εάν δεν δώσει το struct ένα όνομα, αν είναι μια ανώνυμη struct, δεν μπορείτε να ανατρέχετε σε αυτό. Και τελευταίο αλλά όχι λιγότερο σημαντικό, αυτά θα πρέπει όλα να είναι κάπως απλό, και θα πρέπει να σας βοηθήσει να συνειδητοποιήσετε αν είστε γραπτώς αυτό κάτω ότι κάνεις κάτι λάθος, αν αυτά τα είδη των πραγμάτων δεν έχουν νόημα. Τελευταίο, αλλά όχι λιγότερο σημαντικό, γιατί αυτό πρέπει να είναι struct node *; Γιατί δεν μπορεί απλά να struct node το επόμενο βήμα; [Φοιτητικό] Δείκτης στο επόμενο struct. Αυτό είναι αναπόφευκτα ό, τι θέλουμε. Γιατί ποτέ δεν θα μπορούσε να είναι κόμβος struct το επόμενο βήμα; Γιατί πρέπει να είναι struct node * το επόμενο βήμα; Ναι. [Φοιτητικό] Είναι σαν ένα άπειρο βρόχο. Ναι. [Φοιτητικό] Θα είναι όλα σε ένα. Ναι, απλά σκεφτείτε πώς θα κάνουμε το μέγεθος του ή κάτι τέτοιο. Μέγεθος της struct είναι βασικά + ή - μερικές μοτίβο εδώ ή εκεί. Είναι ουσιαστικά θα είναι το άθροισμα των μεγεθών των πραγμάτων στο struct. Το δικαίωμα αυτό εδώ, χωρίς να αλλάξει τίποτα, το μέγεθος πρόκειται να είναι εύκολο. Μέγεθος struct του κόμβου θα είναι το μέγεθος του i + μέγεθος του επόμενου. Μέγεθος του i πρόκειται να είναι 4. Μέγεθος της επόμενης πρόκειται να είναι 4. Μέγεθος struct του κόμβου θα είναι 8. Αν δεν έχουμε την *, σκέφτεται sizeof, τότε sizeof (i) θα είναι 4. Μέγεθος struct του κόμβου είναι επόμενο θα είναι το μέγεθος του i + μέγεθος του κόμβου struct επόμενη + Μέγεθος του μεγέθους i + struct του κόμβου επόμενο. Θα ήταν μια άπειρη αναδρομή των κόμβων. Γι 'αυτό είναι πως τα πράγματα πρέπει να είναι. Και πάλι, σίγουρα απομνημονεύσει ότι, ή τουλάχιστον αυτό καταλαβαίνω αρκετά ώστε να μπορείτε να είναι σε θέση να λόγο μέσα από ό, τι πρέπει να μοιάσει. Τα πράγματα θα πάμε να θέλουν να εφαρμόσουν. Εάν το μήκος του καταλόγου- θα μπορούσε να εξαπατήσει και να κρατήσει γύρω από ένα παγκόσμια μήκος ή κάτι, αλλά εμείς δεν πρόκειται να το κάνουμε αυτό. Εμείς πάμε για να μετρήσετε το μήκος της λίστας. Έχουμε περιέχει, έτσι ώστε να είναι ουσιαστικά σαν μια αναζήτηση, έτσι έχουμε μια συνδεδεμένη λίστα ακεραίων για να δούμε αν αυτό είναι ακέραιος στην συνδεδεμένη λίστα. Βάλε πρόκειται να προστεθεί στην αρχή της λίστας. Προσάρτηση πρόκειται να προστεθεί στο τέλος. Insert_sorted πρόκειται να εισαγάγει την ταξινόμηση θέση στη λίστα. Insert_sorted είδους υποθέτει ότι ποτέ δεν χρησιμοποιείται ή βάλε το προσθέσετε σε κακή τρόπους. Insert_sorted όταν εφαρμογή insert_sorted- Ας πούμε ότι έχουμε συνδεδεμένη λίστα μας. Αυτό είναι ό, τι φαίνεται σήμερα, όπως, 2, 4, 5. Θέλω να εισαγάγετε 3, έτσι ώστε όσο η ίδια η λίστα είναι ήδη ταξινόμηση, Είναι εύκολο να βρείτε όπου 3 ανήκει. Αρχίζω στο 2. Εντάξει, 3 είναι μεγαλύτερο του 2, έτσι θέλω να συνεχίσω. Ω, 4 είναι πάρα πολύ μεγάλη, γι 'αυτό γνωρίζω 3 πρόκειται να πάει στο μεταξύ 2 και 4, και έχω να καθορίσει δείκτες και όλα αυτά τα πράγματα. Αλλά αν δεν είναι απολύτως χρησιμοποιούν insert_sorted, όπως ας πούμε ότι βάζουμε μπροστά 6, τότε συνδεδεμένη λίστα μου πρόκειται να γίνει αυτό. Δεν έχει πλέον κανένα νόημα, έτσι για insert_sorted, μπορείτε απλά να υποθέσουμε ότι η λίστα είναι ταξινομημένη, ακόμη και αν οι λειτουργίες υπάρχουν η οποία μπορεί να προκαλέσει το να μην ταξινόμηση, και αυτό είναι αυτό. Βρείτε ένα χρήσιμο ένθετο έτσι αυτά είναι τα κύρια πράγματα που πρόκειται να πρέπει να εφαρμόσουν. Προς το παρόν, πάρτε ένα λεπτό για να κάνει το μήκος και περιέχει, και εκείνοι θα πρέπει να είναι σχετικά γρήγορη. Πλησιάζει η ώρα κλεισίματος, έτσι ώστε ο καθένας έχει κάτι για το μήκος ή περιέχει; Θα πάμε να είναι σχεδόν ταυτόσημες. [Φοιτητικό] Μήκος. Ας δούμε, αναθεώρηση. Εντάξει. Θέλετε να εξηγήσει; [Φοιτητικό] θα δημιουργήσει μόνο έναν κόμβο δείκτη και η προετοιμασία για το πρώτο, το οποίο είναι καθολική μεταβλητή μας, και στη συνέχεια να ελέγξω αν είναι μηδενική, έτσι δεν παίρνω ένα σφάλμα SEG και να επιστρέψει 0 αν αυτή είναι η περίπτωση. Διαφορετικά, θα βρόχο μέσω, παρακολουθώντας μέσα ακέραιο πόσες φορές έχω πρόσβαση το επόμενο στοιχείο της λίστας και στην ίδια λειτουργία προσαύξησης πρόσβαση επίσης ότι η πραγματική στοιχείο, και στη συνέχεια θα κάνει συνεχώς ο έλεγχος για να δούμε αν είναι μηδενική, και αν είναι μηδενική, τότε από τη ματαίωση και απλά επιστρέφει τον αριθμό των στοιχείων που έχω πρόσβαση. [Rob Β.] Υπάρχει κάποιος που έχει κάποιες παρατηρήσεις σε τίποτα; Αυτό φαίνεται μια χαρά ορθότητα σοφός. [Φοιτητικό] Δεν νομίζω ότι θα πρέπει να έχετε τον κόμβο == null. Ναι, έτσι εάν ο κόμβος == null 0 επιστροφής. Αλλά αν ο κόμβος == null, τότε αυτό-OH, υπάρχει ένα ζήτημα ορθότητας. Ήταν απλά είστε i επιστρέφουν, αλλά δεν είναι στο πεδίο εφαρμογής αυτή τη στιγμή. Απλά πρέπει int i, έτσι ώστε i = 0. Αλλά αν ο κόμβος είναι μηδενική, τότε εγώ ακόμα θα είναι 0, και θα πάμε να επιστρέψει 0, οπότε αυτή η περίπτωση είναι όμοια. Ένα άλλο κοινό πράγμα είναι να κρατήσει τη δήλωση μέσα από τον κόμβο του για βρόχο. Θα μπορούσαμε να πούμε-ω, όχι. Ας κρατήσουμε ως αυτό. I θα μπορούσε πιθανότατα να τεθεί int i = 0 εδώ, τότε ο κόμβος * κόμβος = πρώτη εδώ. Και αυτό είναι πιθανώς το πώς-να απαλλαγούμε από αυτό τώρα. Αυτό είναι πιθανώς το πώς θα είχα γράψει. Θα μπορούσατε επίσης το μέλλον σε αυτό σαν αυτό. Αυτό για τη δομή βρόχου εδώ θα πρέπει να είναι σχεδόν τόσο φυσικό για εσάς και για int i = 0 i είναι μικρότερο από το μήκος της συστοιχίας i + +. Αν αυτό είναι το πώς θα επαναλάβει σε μια σειρά, αυτό είναι το πώς θα επαναλάβει σε μια συνδεδεμένη λίστα. Αυτό θα πρέπει να είναι δεύτερη φύση σε κάποιο σημείο. Με αυτό κατά νου, αυτό πρόκειται να είναι σχεδόν το ίδιο πράγμα. Θα πάμε να θέλουν να επαναλάβει πάνω από μια συνδεδεμένη λίστα. Αν ο κόμβος-δεν έχω ιδέα ποια είναι η αξία ονομάζεται. Κόμβου i. Εάν η τιμή στο συγκεκριμένο κόμβο i = επιστρέψει αλήθεια, και αυτό είναι αυτό. Παρατηρήστε ότι ο μόνος τρόπος για να επιστρέψει ποτέ ψευδή είναι αν θα επαναλάβει κατά τη διάρκεια της συνδέεται με ολόκληρη τη λίστα και να μην επιστρέψει ποτέ αλήθεια, έτσι αυτό είναι που κάνει αυτό. Ως μια πλευρά σημείωση, που κατά πάσα πιθανότητα δεν θα πάρετε για να προσθέσετε ή να βάζουμε μπροστά. Γρήγορη τελευταία σημείωση. Αν δείτε το στατικό λέξη-κλειδί, οπότε ας πούμε στατική μέτρηση int = 0, τότε μετράνε + +, μπορείτε να βασικά σκεφτείτε από το ως μια καθολική μεταβλητή, παρόλο που μόλις είπα αυτό δεν είναι το πώς θα πάμε να εφαρμόσει το μήκος. Το κάνω αυτό εδώ, και στη συνέχεια υπολογίζει + +. Κάθε τρόπος με τον οποίο μπορούν να εισέλθουν σε έναν κόμβο συνδεδεμένη λίστα μας, είμαστε προσαύξηση μας μετράνε. Το σημείο αυτό είναι ό, τι το στατικό λέξη-κλειδί μέσα. Αν είχα μόνο int count = 0 η οποία θα είναι μια τακτική παλιά παγκόσμια μεταβλητή. Τι σημαίνει στατική int count είναι ότι είναι μια καθολική μεταβλητή για αυτό το αρχείο. Είναι αδύνατο για κάποιο άλλο αρχείο, όπως σκέφτομαι PSET 5, αν έχετε ξεκινήσει. Έχετε τόσο speller.c, και έχετε dictionary.c, και αν δηλώνουν μόνο ένα πράγμα παγκόσμιο, τότε τίποτα σε speller.c Μπορείτε να έχετε πρόσβαση σε dictionary.c και αντίστροφα. Οι καθολικές μεταβλητές είναι προσβάσιμα από οποιοδήποτε αρχείο. C, αλλά στατικές μεταβλητές είναι προσβάσιμη μόνο μέσα από το ίδιο το αρχείο, τόσο στο εσωτερικό της ορθογραφικό έλεγχο ή στο εσωτερικό του dictionary.c, αυτό είναι το είδος του πώς θα κηρύξει μεταβλητή μου για το μέγεθος του πίνακα μου ή το μέγεθος του αριθμού μου των λέξεων στο λεξικό. Επειδή δεν θέλω να κηρύξει μια παγκόσμια μεταβλητή που ο καθένας έχει πρόσβαση, Πραγματικά μόνο ενδιαφέρονται για αυτό για τους δικούς τους σκοπούς μου. Το καλό πράγμα για αυτό είναι, επίσης, η όλη ουσία σύγκρουση όνομα. Αν κάποιο άλλο αρχείο προσπαθεί να χρησιμοποιήσει μια καθολική μεταβλητή που ονομάζεται μέτρηση, τα πράγματα πάνε πολύ, πολύ λάθος, έτσι αυτό κρατά ωραία πράγματα ασφαλή, και μόνο μπορείτε να έχετε πρόσβαση, και κανένας άλλος δεν μπορεί, και αν κάποιος άλλος δηλώνει μια μεταβλητή που ονομάζεται παγκόσμια καταμέτρηση, τότε δεν θα παρεμβαίνει με στατική μεταβλητή σας ονομάζεται μετράνε. Αυτό είναι ό, τι είναι στατική. Πρόκειται για ένα αρχείο global μεταβλητή. Ερωτήσεις για τίποτα; Όλα έτοιμα. Αντίο. [CS50.TV]