[Powered by Google Translate] Ας μιλήσουμε για πίνακες.
Επομένως, γιατί θα είμαστε ποτέ θέλετε να χρησιμοποιήσετε πίνακες;
Λοιπόν ας πούμε ότι έχετε ένα πρόγραμμα που χρειάζεται για την αποθήκευση 5 ταυτότητες των μαθητών.
Μπορεί να φαίνεται λογικό να έχουμε 5 ξεχωριστές μεταβλητές.
Για λόγους που θα δούμε σε λίγο, θα αρχίσουμε να μετράμε από το 0.
Οι μεταβλητές που θα έχουμε θα είναι int ID0, int id1, και ούτω καθεξής.
Οποιαδήποτε λογική που θέλουμε να εκτελεί, για μια φοιτητική τους ταυτότητα θα πρέπει να αντιγραφεί και επικολληθεί
για κάθε μια από αυτές τις ταυτότητες των σπουδαστών.
Αν θέλουμε να ελέγξετε ποια μαθητές τυχαίνει να είναι σε CS50,
θα πρέπει πρώτα να ελέγξετε αν ID0 αντιπροσωπεύει το μαθητή στο μάθημα.
Στη συνέχεια, να κάνουν το ίδιο για την επόμενη φοιτητής, θα πρέπει να αντιγράψετε και να επικολλήσετε τον κώδικα για ID0
και να αντικαταστήσετε όλες τις εμφανίσεις του με ID0 id1 και ούτω καθεξής για id2, 3, και 4.
>> Μόλις ακούσετε ότι πρέπει να αντιγράψετε και να επικολλήσετε,
θα πρέπει να αρχίσουμε να σκεφτόμαστε ότι υπάρχει μια καλύτερη λύση.
Τώρα τι γίνεται αν έχετε συνειδητοποιήσει ότι δεν χρειάζεται 5 ταυτότητες των φοιτητών αλλά 7;
Θα πρέπει να πάμε πίσω στο πηγαίο κώδικα σας και να προσθέσετε σε μια ID5, μια ID6,
και να αντιγράψετε και να επικολλήσετε τη λογική για τον έλεγχο αν οι ταυτότητες ανήκουν στην κατηγορία για αυτές τις 2 νέες ταυτότητες.
Δεν υπάρχει τίποτα που συνδέει όλες αυτές τις ταυτότητες μαζί, και έτσι δεν υπάρχει κανένας τρόπος για να ζητήσει
το πρόγραμμα για να το κάνετε αυτό για ταυτότητες 0 έως 6.
Λοιπόν τώρα έχετε συνειδητοποιήσει έχετε 100 ταυτότητες των μαθητών.
Είναι αρχίζουν να μοιάζουν λιγότερο από το ιδανικό να πρέπει να δηλώσουν ξεχωριστά κάθε ένα από αυτά τα αναγνωριστικά,
και να αντιγράψετε και να επικολλήσετε οποιαδήποτε λογική για αυτές τις νέες ταυτότητες.
Αλλά ίσως είμαστε αποφασισμένοι, και το κάνουμε για όλους τους 100 μαθητές.
Αλλά τι γίνεται αν δεν ξέρετε πόσοι μαθητές πραγματικά υπάρχουν;
Υπάρχουν μόνο μερικές n φοιτητές και το πρόγραμμά σας θα πρέπει να ζητήσει από το χρήστη τι είναι n.
Uh oh. Αυτό δεν πρόκειται να λειτουργήσει πολύ καλά.
Το πρόγραμμά σας λειτουργεί μόνο για κάποιο σταθερό αριθμό μαθητών.
>> Επίλυση όλα αυτά τα προβλήματα είναι η ομορφιά των πινάκων.
Έτσι τι είναι ένας πίνακας;
Σε μερικές γλώσσες προγραμματισμού ένας τύπος σειρά θα μπορούσε να είναι σε θέση να κάνει λίγο περισσότερο,
αλλά εδώ θα εστιάσουμε στη βασική δομή του πίνακα δεδομένων ακριβώς όπως θα το δείτε σε C.
Ένας πίνακας είναι απλά ένα μεγάλο μπλοκ μνήμης. Αυτό είναι όλο.
Όταν λέμε ότι έχουμε μια σειρά από 10 ακέραιους αριθμούς, που απλώς σημαίνει ότι έχουμε κάποια μπλοκ
της μνήμης που είναι αρκετά μεγάλο ώστε να περιέχει 10 ξεχωριστές ακέραιοι.
Υποθέτοντας ότι είναι ένας ακέραιος 4 byte, αυτό σημαίνει ότι μία συστοιχία 10 ακεραίων
είναι μια συνεχής μπλοκ 40 bytes στη μνήμη.
Ακόμα και όταν χρησιμοποιείτε πολυδιάστατους πίνακες, τα οποία εμείς δεν θα πάμε για να εδώ,
είναι ακόμα μόνο ένα μεγάλο μπλοκ μνήμης.
Η πολυδιάστατη σημειογραφία είναι απλά μια ευκολία.
Εάν έχετε ένα 3 από 3 πολυδιάστατη array ακεραίων,
τότε το πρόγραμμά σας θα είναι πραγματικά αντιμετωπίζουν ακριβώς αυτό ως ένα μεγάλο μπλοκ των 36 bytes.
Ο συνολικός αριθμός των ακεραίων είναι 3 φορές 3, και κάθε ακέραιος καταλαμβάνει 4 bytes.
>> Ας ρίξουμε μια ματιά σε ένα βασικό παράδειγμα.
Μπορούμε να δούμε εδώ 2 διαφορετικούς τρόπους δηλώνοντας συστοιχίες.
Θα πρέπει να σχολιάσω 1 από τους έξω για το πρόγραμμα για την κατάρτιση
από τη στιγμή που δηλώνουν x δύο φορές.
Θα ρίξουμε μια ματιά σε μερικές από τις διαφορές μεταξύ αυτών των 2 τύπων των δηλώσεων σε λίγο.
Και οι δύο αυτές γραμμές δηλώνουν μια σειρά από Ν μεγέθους,
όπου έχουμε ορίσει ως # N 10.
Θα μπορούσαμε κάλλιστα να ζητήσει από το χρήστη για ένα θετικό ακέραιο
και ότι χρησιμοποιείται ως ακέραιος αριθμός των στοιχείων σε σειρά μας.
Όπως φοιτητής παράδειγμα μας ταυτότητας πριν, αυτό είναι το είδος του σαν κηρύσσοντας την 10η εντελώς ξεχωριστή
φανταστικών μεταβλητών? x0, x1, x2, και ούτω καθεξής μέχρι να xN-1.
Αγνοώντας τις γραμμές όπου δηλώνουμε τον πίνακα, παρατηρούμε οι αγκύλες άθικτο
στο εσωτερικό του για βρόχους.
Όταν γράφουμε κάτι σαν x [3], το οποίο απλώς θα διαβάζεται ως στήριγμα x 3,
μπορείτε να σκεφτείτε από το όπως ζητά το φανταστικό x3.
Ανακοίνωση από ότι με ένα πίνακα μεγέθους Ν, αυτό σημαίνει ότι ο αριθμός εσωτερικό των παρενθέσεων,
το οποίο θα καλέσετε τον δείκτη, μπορεί να είναι οτιδήποτε, από 0 έως Ν-1,
το οποίο είναι ένα σύνολο Ν δεικτών.
>> Για να σκεφτούμε πώς αυτό λειτουργεί πραγματικά
να θυμάστε ότι η σειρά είναι ένα μεγάλο μπλοκ μνήμης.
Αν υποθέσουμε ότι ένας ακέραιος είναι 4 bytes, ολόκληρη η σειρά Χ είναι 40 byte μπλοκ μνήμης.
Έτσι x0 αναφέρεται στα πρώτα 4 bytes του μπλοκ.
Χ [1] αναφέρεται στις επόμενες 4 bytes και ούτω καθεξής.
Αυτό σημαίνει ότι η έναρξη του x είναι όλα το πρόγραμμα χρειάζεται ποτέ να παρακολουθείτε.
Αν θέλετε να χρησιμοποιήσετε x [400], τότε το πρόγραμμα ξέρει ότι αυτό είναι ισοδύναμο
σε μόλις 1.600 bytes μετά την έναρξη του x.
Πού έχουμε 1.600 bytes από; Είναι μόλις 400 φορές 4 bytes ανά ακέραιο.
>> Πριν προχωρήσουμε, είναι πολύ σημαντικό να συνειδητοποιήσουμε ότι σε C
δεν υπάρχει εφαρμογή του δείκτη που χρησιμοποιούμε στον πίνακα.
Μεγάλο μπλοκ μας είναι μόνο 10 ακέραιοι καιρό, αλλά τίποτα δεν θα φωνάζω σε μας αν γράφουμε x [20]
ή ακόμη x [-5].
Ο δείκτης δεν χρειάζεται καν να είναι ένας αριθμός.
Μπορεί να είναι οποιοδήποτε αυθαίρετο έκφραση.
Στο πρόγραμμα που χρησιμοποιείτε το i μεταβλητή από το βρόχο για να δείκτη μέσα στον πίνακα.
Αυτό είναι ένα πολύ κοινό μοτίβο, looping από i = 0 προς το μήκος της συστοιχίας,
και χρησιμοποιώντας i συνέχεια ως δείκτης για τη συστοιχία.
Με αυτόν τον τρόπο μπορείτε αποτελεσματικά βρόχο επί ολόκληρης της συστοιχίας,
και μπορείτε είτε να αντιστοιχίσετε σε κάθε σημείο του πίνακα ή να το χρησιμοποιήσετε για κάποιο υπολογισμό.
>> Στην πρώτη για το βρόχο, ί ξεκινά στις 0,
και έτσι θα μπορεί να αναθέτει στο σημείο 0 στον πίνακα, η τιμή 0 φορές 2.
Στη συνέχεια θ προσαυξήσεις, και έχουμε εκχωρήσει την πρώτη θέση στον πίνακα η τιμή 1 φορές 2.
Τότε θ προσαυξήσεις πάλι και ούτω καθεξής μέχρι να εκχωρήσει στη θέση Ν-1 στη συστοιχία
η τιμή Ν-1 φορές 2.
Έτσι έχουμε δημιουργήσει έναν πίνακα με τις πρώτες 10 ζυγούς αριθμούς.
Ίσως εξισώνει θα ήταν λίγο καλύτερο όνομα για τη μεταβλητή από ό, τι χ,
αλλά που θα έχουν δώσει τα πράγματα μακριά.
Ο δεύτερος βρόχος για τυπώνει έπειτα ακριβώς τις αξίες που έχουν ήδη αποθηκευτεί στο εσωτερικό του πίνακα.
>> Ας δοκιμάστε να τρέξετε το πρόγραμμα και με τους δύο τύπους των δηλώσεων σειρά
και ρίξτε μια ματιά στην έξοδο του προγράμματος.
Όσο μπορούμε να δούμε, το πρόγραμμα συμπεριφέρεται με τον ίδιο τρόπο και για τους δύο τύπους των δηλώσεων.
Ας ρίξουμε μια ματιά στο τι συμβαίνει αν αλλάξουμε το πρώτο loop να μην σταματήσει στο Ν
αλλά μάλλον να πω 10.000.
Way πέρα ​​από το τέλος του πίνακα.
Ωχ. Ίσως έχετε δει αυτό πριν.
Ένα σφάλμα κατάτμησης σημαίνει ότι το πρόγραμμά σας έχει συνετρίβη.
Θα αρχίσουμε να βλέπουμε αυτά όταν αγγίζετε περιοχές της μνήμης δεν θα πρέπει να αγγίζουν.
Εδώ έχουμε να κάνουμε 10.000 θέσεις μετά την έναρξη του x,
η οποία είναι προφανώς μια θέση στη μνήμη μας δεν θα πρέπει να αγγίζουν.
Έτσι, οι περισσότεροι από εμάς μάλλον δεν θα θέσει κατά λάθος 10.000 αντί του Ν,
αλλά τι γίνεται αν κάνουμε κάτι πιο λεπτές, όπως λένε εγγραφής μικρότερη ή ίση με Ν
στο βρόχο για την κατάσταση, σε αντίθεση με λιγότερο από Ν.
Θυμάστε ότι μια συστοιχία έχει μόνο δείκτες από 0 έως Ν-1,
πράγμα που σημαίνει ότι δείκτης Ν είναι πέρα ​​από το άκρο της συστοιχίας.
Το πρόγραμμα δεν θα μπορούσε να συντριβή σε αυτή την περίπτωση, αλλά είναι ακόμα ένα λάθος.
Στην πραγματικότητα, αυτό το λάθος είναι τόσο κοινό ότι έχει το δικό του το όνομά του,
μια off με 1 λάθος.
>> Αυτός είναι αυτό για τα βασικά.
Έτσι, ποιες είναι οι κύριες διαφορές μεταξύ των 2 τύπων των δηλώσεων πίνακα;
Μια διαφορά είναι όπου το μεγάλο μπλοκ μνήμης πηγαίνει.
Στην πρώτη δήλωση, η οποία θα καλέσω το στήριγμα συστοιχία τύπου,
αν και αυτό δεν είναι καθόλου ένα συμβατικό όνομα,
θα πάει στη στοίβα.
Ενώ στο δεύτερο, το οποίο θα καλέσω το δείκτη συστοιχία τύπου, θα πάει στο σωρό.
Αυτό σημαίνει ότι όταν οι αποδόσεις λειτουργίας, η συστοιχία βραχίονας αυτόματα θα deallocated,
λαμβάνοντας υπόψη ότι θα πρέπει να καλέσετε δωρεάν explicitily στη συστοιχία δείκτη
ή αλλιώς έχετε μια διαρροή μνήμης.
Επιπλέον, η συστοιχία βραχίονα δεν είναι στην πραγματικότητα μια μεταβλητή.
Αυτό είναι σημαντικό. Είναι απλά ένα σύμβολο.
Μπορείτε να σκεφτείτε από το ως μια σταθερή ότι ο μεταγλωττιστής επιλέγει για εσάς.
Αυτό σημαίνει ότι δεν μπορούμε να κάνουμε κάτι σαν x + + με τον τύπο βραχίονα,
αν και αυτό είναι απολύτως έγκυρη με τον τύπο δείκτη.
>> Ο τύπος δείκτης είναι μια μεταβλητή.
Για τον τύπο δείκτη, έχουμε 2 ξεχωριστά κομμάτια μνήμης.
Η μεταβλητή χ η ίδια είναι αποθηκευμένο στη στοίβα και είναι μόνο ένα δείκτη,
αλλά το μεγάλο μπλοκ μνήμης αποθηκεύεται στο σωρό.
Η μεταβλητή x στη στοίβα αποθηκεύει μόνο τη διεύθυνση
από το μεγάλο μπλοκ της μνήμης του σωρού.
Μια συνέπεια αυτού είναι με το μέγεθος της εκμετάλλευσης.
Αν ρωτήσετε για το μέγεθος του πίνακα βραχίονα, που θα σας δώσει το μέγεθος του μεγάλου μπλοκ της μνήμης,
κάτι σαν 40 bytes,
αλλά αν σας ρωτήσω για το μέγεθος του τύπου δείκτη του πίνακα,
θα σας δώσει το μέγεθος της μεταβλητής x η ίδια, η οποία για τη συσκευή είναι πιθανό μόλις 4 bytes.
Χρησιμοποιώντας τον τύπο του δείκτη συστοιχία, είναι αδύνατον να ζητήσει άμεσα
το μέγεθος του μεγάλου μπλοκ μνήμης.
Αυτό δεν είναι συνήθως πολύ ενός περιορισμού δεδομένου ότι πολύ σπάνια θέλουν το μέγεθος
από το μεγάλο μπλοκ μνήμης, και μπορούμε να υπολογίσουμε ότι συνήθως αν χρειαζόμαστε.
>> Τέλος, η σειρά βραχίονα συμβαίνει για να μας δώσει μια συντόμευση για την εκκίνηση μιας σειράς.
Ας δούμε πώς θα μπορούσαμε να γράψουμε τα πρώτα 10 ακόμη και ακέραιοι χρησιμοποιώντας τη συντόμευση initilization.
Με τη σειρά δείκτη, δεν υπάρχει ένας τρόπος για να κάνει μια συντόμευση σαν αυτό.
Αυτό είναι απλά μια εισαγωγή για το τι μπορείτε να κάνετε με συστοιχίες.
Δείχνουν σε σχεδόν σε κάθε πρόγραμμα που γράφετε.
Ας ελπίσουμε ότι μπορείτε να δείτε τώρα έναν καλύτερο τρόπο για να γίνει το παράδειγμα φοιτητή αναγνωριστικά
από την αρχή του βίντεο.
>> Το όνομά μου είναι Rob Bowden, και αυτό είναι CS50.