[ΜΟΥΣΙΚΗ ΠΑΙΖΟΝΤΑΣ]
>> DAVID J. MALAN: Εντάξει.
Αυτό είναι CS50.
Και αυτή είναι η αρχή της εβδομάδας 5.
Και όπως ίσως έχετε παρατηρήσει, μέρος του υλικού
είναι να πάρει λίγο περισσότερο συγκρότημα, το μικρό πυκνότερο.
>> Και είναι πολύ εύκολο, ειδικά αν ήσαστε στη συνήθεια για κάποιο χρονικό διάστημα,
να προσπαθεί να κακογραφία κάτω πιο οτιδήποτε κάνουμε, λέμε στην τάξη.
Αλλά συνειδητοποιούν, ότι δεν είναι ίσως η ιδανική παιδαγωγική προσέγγιση
στην εκμάθηση αυτό το είδος του υλικού, και το υλικό γενικότερα.
Και έτσι είμαστε στην ευχάριστη θέση να ανακοινώσει τις δικές Gheng αυτού του CS50 του
Gong έχει αρχίσει να προετοιμάζει μια κανονική σειρά των σημειώσεων
για την πορεία, η ελπίδα η οποία είναι ότι, ένα, αυτά
όχι μόνο να χρησιμεύσει ως μια αναφοράς και ένας πόρος
για την αναθεώρηση υλικό και θα πίσω διαμέσου του υλικού που μπορεί να έχουν
θα ξεφύγει από την πρώτη φορά, αλλά Επίσης, έτσι ώστε το κεφάλι σας μπορεί να είναι πιο
up από τα κάτω, όταν έρχεται η ώρα να μιλήσει,
έτσι ώστε να μπορεί να συμμετάσχει πιο προσεκτικά, όπως
σε αντίθεση με πιο scribbly.
>> Με αυτόν εν λόγω, αυτό που θα βρείτε στο η ιστοσελίδα είναι τέτοια έγγραφα όπως αυτό.
Και προειδοποίηση, στο επάνω αριστερό μέρος, υπάρχει όχι μόνο έναν πίνακα περιεχομένων,
αλλά και τους κωδικούς του χρόνου ότι θα πηδήξει αμέσως
στο κατάλληλο μέρος σε απευθείας σύνδεση βίντεο.
Και τι Chang εδώ έχει γίνει είναι, κατ 'ουσίαν, τεκμηριωμένη
τι συνέβη σε αυτό το Ειδικότερα διάλεξη.
Και πολλές από τις διαλέξεις είναι ήδη σε απευθείας σύνδεση τώρα με αυτό το URL.
Και θα συνεχίσουμε να δημοσιεύσετε το υπόλοιπο των στοιχείων αυτών από το τέλος αυτής της εβδομάδας,
έτσι ώστε να επωφεληθούν αυτού του πόρου.
>> Έτσι, χωρίς άλλη καθυστέρηση, αρχίσαμε να ξεκολλήσετε
το στρώμα που έχει κορδόνι για κάποιο χρονικό διάστημα.
Και τι να πούμε ένα string στην πραγματικότητα είναι η τελευταία εβδομάδα;
Έτσι char αστέρι.
Και char αστέρι, καλά, τι έκανε ότι πραγματικά σημαίνει;
Λοιπόν, όλο αυτό το διάστημα, αν έχουμε ζητούν μια λειτουργία,
όπως GetString και αποθήκευση η λεγόμενη επιστροφή
αξία των GetString σε ένα variable-- λέγεται
s τύπου string-- έχουμε γράψει η γραμμή του κώδικα μέχρι εκεί πάνω.
Και αυτό είναι μόνο όταν βλέπω μου χειρογράφου μεγεθύνονται εδώ
μπορώ να συνειδητοποιήσουμε πόσο φρικτό είναι αυτό.
>> Ωστόσο, ας υποθέσουμε ότι, στη δεξιά πλευρά
Είναι, ωστόσο, μια λογική απεικόνιση του τι είναι
συνεχίζεται σε όλα αυτά χρόνο με GetString.
GetString, φυσικά, παίρνει ένα string.
Αλλά τι σημαίνει αυτό στην πράξη;
Αυτό σημαίνει ότι παίρνει ένα κομμάτι της μνήμη από το λειτουργικό σύστημα
καλώντας μια συνάρτηση, που ονομάζεται malloc.
Αλλά περισσότερα για αυτό αργότερα.
Και τότε συμπληρώνει ότι κομμάτι της μνήμης
με τις επιστολές που ο χρήστης έχει πληκτρολογήσει, ακολουθούμενη από, φυσικά,
ένα κενό χαρακτήρα, ή backslash μηδέν στο τέλος.
>> Εν τω μεταξύ, από την αριστερή πλευρά από αυτή την ιστορία, όλο αυτό το διάστημα,
έχουμε δηλώνοντας μια μεταβλητή, όπως το s.
Και αυτή η μεταβλητή είναι ό, τι τώρα θα ξεκινήσει την κλήση ενός δείκτη.
Δεν είναι ένα κουτί στο εσωτερικό του οποίου βάζουμε το string, Daven, per se,
αλλά μάλλον βάζουμε σε αυτό το τετράγωνο κουτί στα αριστερά τι ακριβώς;
Ναι;
>> ΚΟΙΝΟ: Η διεύθυνση της όπου βρίσκονται στη μνήμη.
>> DAVID J. MALAN: Ακριβώς.
Η διεύθυνση του όπου Daven βρίσκεται στη μνήμη.
Και όχι όπου όλα Daven βρίσκεται, per se, αλλά ειδικά η διεύθυνση
από τι;
Ναι;
>> ΚΟΙΝΟ: Πρώτη χαρακτήρα.
>> DAVID J. MALAN: Ο πρώτος χαρακτήρας σε Daven, η οποία, στην περίπτωση αυτή,
Μου πρότεινε ήταν αυθαίρετα και εξωπραγματικά 1, ΟΧ1,
που απλά σημαίνει ότι η δεκαεξαδικό αριθμό 1.
Αλλά κατά πάσα πιθανότητα θα να είναι ένα πολύ μεγαλύτερο αριθμό
ότι θα μπορούσαμε να επιστήσει με 0x ως πρόθεμα,
αντιπροσωπεύει ένα δεκαεξαδικό χαρακτήρα.
Και επειδή εμείς δεν χρειάζεται να γνωρίζουν πού το υπόλοιπο από τους χαρακτήρες του Daven
είναι, γιατί από ό, τι απλό σχεδιασμό απόφαση που είχε γίνει πριν από πολλά χρόνια;
Ναι;
>> ΚΟΙΝΟ: Backslash 0.
DAVID J. MALAN: Ναι, ακριβώς.
Το backslash 0 σας επιτρέπει, έστω και σε γραμμικό χρόνο, για να διασχίσει το string,
με τα πόδια από τα αριστερά προς τα δεξιά, με ένα βρόχο for, ή λίγο
βρόχου, ή κάτι παρόμοιο ότι, και καθορίζουν, oh, εδώ
είναι το τέλος αυτής της συγκεκριμένης σειράς.
Έτσι, με μόνο τη διεύθυνση η αρχή μιας συμβολοσειράς,
μπορούμε να έχουμε πρόσβαση το σύνολο των αυτό, γιατί όλο αυτό το διάστημα,
ένα string έχει μόλις ένα αστέρι char.
>> Έτσι, είναι σίγουρα μια χαρά να συνεχίσετε να χρησιμοποιείτε η βιβλιοθήκη CS50 και αυτή η αφαίρεση,
να το πω έτσι, αλλά θα αρχίσετε να βλέπετε ακριβώς
τι συμβαίνει στις κάτω από όλο αυτό το χρονικό διάστημα.
Έτσι, μπορείτε να ανακαλέσετε αυτό το παράδειγμα, πάρα πολύ, από την τελευταία φορά, να συγκρίνουν 0,
η οποία στην πραγματικότητα δεν συγκρίνετε.
Αλλά αρχίσαμε να λύσουμε αυτό.
>> Αλλά, όπως ίσως μια επανεκπαίδευση, θα μπορούσα να ενδιαφέρουν κάποιον
σε ένα ροζ ελέφαντα σήμερα, επίσης από Chang;
Πώς για σας μπροστά; [Δεν ακούγεται].
Έλα πάνω.
>> Και εν τω μεταξύ, καθώς έρχεστε επάνω, ας
σκεφτείτε για μια στιγμή τι αυτός ο κώδικας ήταν στην πραγματικότητα κάνει.
Είναι δηλώνοντας δύο μεταβλητές up κορυφή, s και t, και καλώντας GetString.
Αυτό δεν είναι ένα πολύ φιλικό προς το χρήστη πρόγραμμα, γιατί δεν σας πω τι να κάνετε.
Αλλά το αφήσουμε υποθέσουμε είμαστε με επίκεντρο το ζουμερό μέρος.
Και τότε θα κάνουμε, αν s ισούται ισούται με t, θα πρέπει να πούμε printf,
έχετε πληκτρολογήσει το ίδιο πράγμα.
Γεια σας.
Ποιο είναι το όνομά σου;
>> Janelle: Janelle.
DAVID J. MALAN: Janelle, Χαίρω πολύ.
Έτσι πρόκληση σας σε χέρι για αυτό το ελέφαντα
είναι η πρώτη για να επιστήσει μας μια εικόνα του τι είναι που εκπροσωπούνται σε αυτά τα δύο πρώτα
γραμμές.
Έτσι s και το t μπορεί να είναι αντιπροσώπευε το πώς εμφανίζονται στην οθόνη;
Και μπορείτε να σχεδιάσετε μόνο με το δάχτυλό σας για αυτή τη μεγάλη οθόνη.
>> Έτσι, υπάρχουν δύο μισά να κάθε πλευρά αυτής της εξίσωσης.
Έτσι, υπάρχει s για την αριστερά, και Στη συνέχεια GetString στα δεξιά.
Και έπειτα υπάρχει t στα αριστερά, και στη συνέχεια GetString στα δεξιά.
Λοιπόν, πώς θα μπορούσαμε να αρχίσουμε με βάση μια εικόνα ότι
αντιπροσωπεύει ό, τι συμβαίνει εδώ στη μνήμη, θα λέγατε;
Και επιτρέψτε μου να σας εξηγήσω τι κάνεις as you go.
>> Janelle: OK.
Λοιπόν, πρώτα, θα πρέπει να ζητά μπορείτε να πάρετε το string εισόδου.
Και θα store-- Ω, συγγνώμη.
DAVID J. MALAN: OK.
Καλή.
Και αυτό λέγεται αυτό;
Ω, εντάξει.
Συνεχίστε.
Δεν ήθελα να διακόψω.
Janelle: Συγγνώμη.
Έτσι θα εισόδου του σε η διεύθυνση δεν of-- σίγουρος.
Δεν μπορώ να θυμηθώ ακριβώς τον αριθμό, αλλά πιστεύω ότι είχε αρχίσει με 0.
>> DAVID J. MALAN: Αυτό είναι εντάξει, γιατί έκανα τους αριθμούς επάνω,
οπότε δεν υπάρχει σωστή απάντηση.
>> Janelle: Ξεκινώντας με το 0 τόξο.
>> DAVID J. MALAN: Εντάξει, έτσι το στοιχείο 0.
Σίγουρα.
>> Janelle: Και στη συνέχεια, αν ήταν όπως ακριβώς ένα δύο-letter--
>> DAVID J. MALAN: Εντάξει, πίσω σε σας.
>> Janelle: Έτσι στοιχείο 0, και τότε το στοιχείο 1 ή στοιχείο 2.
DAVID J. MALAN: Και ποιο κομμάτι της η εικόνα σας σύρουν τώρα;
Η κλήση προς GetString;
Ή η δήλωση του s;
>> Janelle: Η δήλωση του s, πιστεύω.
Ω, η GetString, επειδή θα να εισάγονται σε κάθε [? περιοχή. ?]
>> DAVID J. MALAN: Καλή.
Ακριβώς.
Ακόμα κι αν αυτό αποτελεσματικά επιστρέφει ένα array, ανάκληση,
όταν παίρνουμε πίσω ένα string, μπορούμε δείκτη σε αυτή string χρησιμοποιώντας 01 και 2.
Από τεχνική άποψη, αυτοί είναι πιθανώς αντιπροσωπεύεται από μεμονωμένες διευθύνσεις,
αλλά αυτό είναι εντάξει.
>> Έτσι, ας υποθέσουμε ότι, αν μπορώ απλά γρήγορα διαβιβάσει στο σημείο όπου είχαμε μείνει
τελευταία φορά, εάν ένας από οι χορδές ήταν g α β ε,
backslash 0, πράγμα που σημαίνει ότι ο Gabe του εισόδου, πώς θα μπορούσαμε να εκπροσωπεί s τώρα;
Αν αυτή είναι η μνήμη που είναι έχουν επιστραφεί από GetString;
>> Janelle: Θα ήταν αντιπροσωπεύεται από ένα τόξο;
>> DAVID J. MALAN: Με ένα τόξο;
Λοιπόν, όχι.
Ας πούμε, εικαστικά, επιτρέψτε μου να πάμε μπροστά
και προτείνει ότι, εάν αυτό είναι s, αυτό είναι η τιμή επιστροφής της GetString.
Και έχετε αυτό που ως 0, 1, 2, η οποία είναι απολύτως λογικό, γιατί εμείς
μπορεί δείκτη σε string, ως τέτοιο.
Αλλά ακριβώς για να είναι συνεπείς με τελευταία φορά, επιτρέψτε μου να πάμε μπροστά
και αυθαίρετα προτείνουν ότι αυτή η είναι η διεύθυνση 1, αυτό είναι διεύθυνση 2,
Αυτή είναι η διεύθυνση 3, και ούτω καθεξής.
Και αυτό, ακριβώς για να είναι super σαφής, τι συμβαίνει
να πάει σε s ως αποτέλεσμα του ότι πρώτη γραμμή του κώδικα, θα λέγατε;
>> Janelle: Διεύθυνση 1;
>> DAVID J. MALAN: Ακριβώς.
Έτσι αντιμετώπιση 0x1.
Και εν τω μεταξύ, επιτρέψτε μου να πάει μπροστά και επαναλαμβάνουν πολλά από αυτά που έχετε κάνει
και να προσθέσετε το δικό μου t εδώ.
Αν ήταν να πληκτρολογήσετε Gabe πάλι, μια δεύτερη φορά,
όταν σας ζητηθεί με GetString, όπου, Φυσικά, είναι Gabe πρόκειται να πάει;
Λοιπόν, presumably--
>> Janelle: Όπως εδώ;
DAVID J. MALAN: Ναι.
Janelle: Ή είναι, επίσης, στις ίδιες θέσεις;
DAVID J. MALAN: Επιτρέψτε μου να προτείνω, ναι, ακριβώς, οπότε σε αυτές τις πρόσθετες θέσεις.
Αλλά τι είναι το κλειδί τώρα είναι ότι, ακόμα και αν και έχω σχεδιάσει αυτά αρκετά κοντά
together-- 0x1, αυτό είναι 0x2-- στην πραγματικότητα,
Αυτό τώρα μπορεί να είναι η διεύθυνση 0x10, για παράδειγμα, και 0x11 και 0x12,
και ούτω καθεξής.
Και έτσι, αν αυτή είναι η περίπτωση, τι πρόκειται να καταλήξουμε εδώ σε t;
>> Janelle: 0x10;
DAVID J. MALAN: Ακριβώς.
Έτσι, 0x10.
Και έτσι τώρα, τελευταία ερώτηση.
Έχετε, κατά πολύ, έπρεπε να λειτουργήσει το πιο δύσκολο για έναν ελέφαντα μέχρι στιγμής.
Μέχρι τώρα, αν έχω σηκώσει τον κωδικό και πάλι, όταν το κάνω, στην γραμμή των τριών,
αν s ισούται ισούται με t, τι είμαι πραγματικά συγκρίνοντας ότι έχουμε που εδώ;
>> Janelle: Οι δύο διευθύνσεις;
DAVID J. MALAN: Ακριβώς.
Γι 'αυτό λέω είναι s ίση ίσο με t;
Με άλλα λόγια, είναι ίση 1 ίσο με 10;
Και φυσικά, ο προφανής απάντηση είναι τώρα, όχι.
Και έτσι αυτό το πρόγραμμα είναι τελικά πρόκειται να εκτυπώσετε ό, τι θα λέγατε;
>> Janelle: Θα ήταν, έχετε πληκτρολογήσει το ίδιο πράγμα;
>> DAVID J. MALAN: Έτσι, αν το s είναι 1 και το t είναι 10;
>> Janelle: Έχετε πληκτρολογήσει διαφορετικά πράγματα.
>> DAVID J. MALAN: Ακριβώς.
Έχετε πληκτρολογήσει διαφορετικά πράγματα.
Εντάξει.
Έτσι, ένας γύρος χειροκρότημα, αν μπορούσαμε, εδώ.
[Χειροκρότημα]
Αυτό ήταν οδυνηρή.
Το ξέρω.
Όμορφα γίνει.
Έτσι, τώρα ας δούμε αν δεν μπορούμε πειράζω χώρια ό, τι η λύση ήταν.
Και φυσικά, όταν έχουμε σταθερό αυτό-- η οποία θα εκπροσωπεί τώρα στην green--
κάναμε μερικές βελτιώσεις εδώ.
Πρώτον, όπως ακριβώς μια λογική ελέγχει, είμαι πρώτα τον έλεγχο
αν s ισούται με μηδέν και t ισούται με μηδέν.
Και ακριβώς για να είναι σαφής, όταν θα μπορούσε s ή t να είναι μηδενική σε κώδικα όπως αυτό;
Πότε μπορεί να s ή t να είναι null.
Ναι;
>> ΚΟΙΝΟ: [δεν ακούγεται].
>> DAVID J. MALAN: Ακριβώς.
Εάν η συμβολοσειρά ότι ο χρήστης πληκτρολογήσει είναι πάρα πολύ καιρό
να χωρέσει σε μνήμη, ή κάποια παράξενο υπόθεση γωνία, όπως ότι,
GetString, όπως θα δούμε, κυριολεκτικά Σήμερα, στην τεκμηρίωση του,
λέει ότι θα επιστρέψει null ως μια ιδιαίτερη αξία φρουρού,
ή ακριβώς το είδος της ένα ειδικό σύμβολο αυτό σημαίνει ότι κάτι πήγε στραβά.
Θέλουμε, λοιπόν, να ελέγξετε για ότι, επειδή αποδεικνύεται
ότι null είναι μια πολύ επικίνδυνη αξία.
>> Συχνά, αν προσπαθήσετε να κάνετε κάτι με null περιλαμβάνει ένα function-- περνώντας
ως πρώτη ύλη, για instance-- ότι η λειτουργία ίσως πολύ θα συντριβή και, με αυτό,
πάρει κάτω από ολόκληρο το πρόγραμμα σας.
Έτσι, αυτή η τρίτη γραμμή τώρα είναι απλά μια λογική ελέγχει, έλεγχος σφαλμάτων, αν θέλετε.
Αυτό είναι μια καλή συνήθεια τώρα μας να μπει σε οποιαδήποτε στιγμή έχουμε
προσπαθήστε να χρησιμοποιήσετε μια τιμή που θα μπορούσε, ενδεχομένως, να είναι null.
>> Τώρα, στην τέταρτη γραμμή εδώ, "Αν strcmp (s, t)," καλά,
Τι είναι αυτό αναφέρεστε;
Λοιπόν, είπαμε ότι αυτό ήταν ένα πολύ συνοπτικά ονομάζεται συνάρτηση σύγκρισης συμβολοσειράς.
Και ο σκοπός του στη ζωή είναι να συγκρίνετε το πρώτο επιχείρημα της εναντίον της δεύτερης,
αλλά όχι όσον αφορά τις διευθύνσεις τους, όπως κάναμε λάθος μια στιγμή
πριν με το κόκκινο κώδικα, αλλά αντί να συγκρίνει αυτά τα δύο
χορδές του ανθρωπίνως διαισθητικό τρόπος συγκρίνοντας αυτό, ενάντια σε αυτό,
ενάντια σε αυτό, ενάντια σε αυτό, και τότε σταματώντας εάν και όταν ένας
ή και τα δύο από τα δάχτυλά μου χτυπά μια ανάστροφη κάθετο 0.
Έτσι, κάποιος χρόνια πριν εφαρμοστεί strcmp να εφαρμόσουν για εμάς η λειτουργικότητα
ότι ελπίζαμε ότι θα έχουν πάρει με απλά συγκρίνοντας δύο απλές αξίες.
>> Τώρα ειλικρινά, έχω κρατήσει σχέδιο όλες αυτές διάφορους αριθμούς.
Αλλά η πραγματικότητα είναι, έχω πάει καθιστώντας αυτά τα επάνω όλη την ώρα.
Και έτσι επιτρέψτε μου να πάμε μπροστά και scribble αυτών έξω
να κάνω μια παρατήρηση ότι, στο τέλος της ημέρας και κινείται προς τα εμπρός,
δεν είμαστε πραγματικά πρόκειται να νοιάζονται για τι αντιμετωπίζει τα πράγματα είναι στην πραγματικότητα
στη μνήμη.
Γι 'αυτό και δεν πρόκειται να μπω σε αυτά τα είδη των αριθμών τόσο πολύ πια,
Είμαι απλά ένα αφηρημένο αυτό μακριά ένα λίγο πιο φιλικό με απλά βέλη.
>> Με άλλα λόγια, εάν το s είναι ένας δείκτης, καλά, ας το συντάξει, κυριολεκτικά,
ως δείκτη, ένα βέλος που δείχνει από μόνη της σε κάτι άλλο,
και μην ανησυχείτε πάρα πολύ για η minutia από αυτές τις διευθύνσεις
η οποία, και πάλι, έκανα έτσι κι αλλιώς.
Αλλά θα δούμε αυτές τις διευθύνσεις, Μερικές φορές, όταν τον εντοπισμό σφαλμάτων κώδικα.
>> Τώρα, εν τω μεταξύ, το πρόγραμμα εδώ διορθώσεις, φυσικά,
ότι πρόβλημα συγκρίνοντας οι δύο χορδές.
Αλλά τρέξαμε σε ένα άλλο πρόβλημα.
Αυτό ήταν από το αντίγραφο προγραμματίσετε την τελευταία φορά,
σύμφωνα με την οποία, προσπαθούσα να κεφαλαιοποιήσει μόνο ο πρώτος χαρακτήρας σε μια σειρά.
Αλλά αυτό ήταν το σύμπτωμα είδαμε την τελευταία φορά, όταν
ένας χρήστης πληκτρολογήσει σε μια αξία, όπως Gabe σε πεζά, για s,
Στη συνέχεια βάλαμε s στο t, όπως στην τρίτη γραμμή εκεί,
και στη συνέχεια προσπάθησα να κεφαλαιοποιήσει t βραχίονα 0;
Ποιο ήταν το αποτέλεσμα της Αλλάζοντας το t βραχίονα 0 εδώ;
>> ΚΟΙΝΟ: Θα αλλάξει s.
>> DAVID J. MALAN: Ναι, Άλλαξα s, καθώς και.
Επειδή ό, τι πραγματικά συμβαίνει;
Λοιπόν, επιτρέψτε μου να δω αν μπορώ να καθαρίσετε μέχρι αυτή την εικόνα, ως εξής.
>> Εάν το s είναι, και πάλι, η λέξη g, a, b, e, backslash, 0, και δ
εμείς θα συνεχίσουμε το σχέδιο ως ένα κουτί εδώ, αλλά όχι περισσότερες διευθύνσεις.
Ας σταματήσουμε να κάνουμε πράγματα.
Ας σχεδιάσετε μια εικόνα να απλοποιήσει τον κόσμο.
>> Όταν t δηλώνουμε με κορδόνι t, που δημιουργεί αυτό το κομμάτι της μνήμης.
Πλατεία συμβαίνει να είναι 32 bits σε περισσότερους υπολογιστές.
Στην πραγματικότητα, αν έχετε ποτέ ακούσει για ένα υπολογιστή που έχει μία αρχιτεκτονική 32-bit,
πολύ φανταχτερό-μιλούν, που μόλις σημαίνει ότι χρησιμοποιεί διευθύνσεις 32-bit.
Και ως ένα τεχνικό μέρος, αν έχετε αναρωτηθεί ποτέ
γιατί παλαιότερους υπολογιστές, αν πραγματικά Προσπάθησα να σούπα τους με μεγάλο μέρος της RAM,
θα μπορούσε να έχει μόνο ένα μέγιστο από τέσσερα gigabytes μνήμης RAM,
και αυτό γιατί, κυριολεκτικά, παλιό υπολογιστή σας θα μπορούσε μόνο
μετράει ως 4 δισεκατομμύρια, 4 δις bytes,
διότι χρησιμοποιούσε 32-bit αριθμούς για τις διευθύνσεις.
>> Αλλά σε κάθε περίπτωση, σε αυτό παράδειγμα, η ιστορία είναι πολύ πιο απλή.
t είναι απλώς άλλο ένα δείκτη, ή πραγματικά ένα αστέρι char, γνωστός και κορδόνι.
Και πώς μπορώ να θέλετε να ενημερώσετε αυτή την εικόνα τώρα με τη δεύτερη γραμμή του κώδικα,
μετά την τελεία, τελεία, τελεία;
Όταν κάνω κορδόνι t ισούται με s ερωτηματικό, πώς αλλάζει αυτή η εικόνα;
Ναι;
>> ΚΟΙΝΟ: [δεν ακούγεται].
>> DAVID J. MALAN: Ναι.
Ακριβώς.
Μόλις έβαλα ένα βέλος από το t κουτί στην ίδια διεύθυνση,
το ίδιο το πρώτο γράμμα στο έδωσε.
Ή τεχνικώς, εάν αυτό τύπος ήταν ακόμα σε 0x1,
Είναι σαν να είχα 0x1 εδώ και 0x1 εδώ.
Αλλά και πάλι, ποιος νοιάζεται σχετικά με τις διευθύνσεις;
Είναι ακριβώς η ιδέα που έχει σημασία τώρα.
Έτσι, αυτό είναι ό, τι συμβαίνει εδώ.
Έτσι, φυσικά, αν το κάνετε t βραχίονα 0, η οποία είναι σημειογραφία συστοιχία,
από course-- και ειλικρινά, φαίνεται σαν να υπάρχει μια σειρά πάνω από εδώ,
αλλά τώρα υπάρχει αυτό το παράξενο πράγμα.
Να ξέρετε ότι η γλώσσα προγραμματισμού, C, σας προσφέρει αυτή τη δυνατότητα,
σύμφωνα με την οποία, ακόμη και εάν το t είναι ένα δείκτη, ή s είναι ένας δείκτης,
μπορείτε ακόμα να χρησιμοποιήσετε εκείνο το γνωστό, άνετα αγκύλη
σημειογραφία για να μεταβείτε στο πρώτο στοιχείο, ή το δεύτερο στοιχείο, ή κάθε στοιχείο
ότι ο δείκτης δείχνει να γιατί, προφανώς, αυτό
είναι, όπως στην προκειμένη περίπτωση, δείχνοντας κάποια σειρά.
>> Λοιπόν, πώς μπορούμε να το διορθώσω αυτό;
Ειλικρινά, αυτό είναι όπου πήρε ένα λίγο συντριπτική με την πρώτη ματιά.
Αλλά εδώ είναι μια νέα και βελτιωμένη έκδοση.
>> Έτσι, η πρώτη, παίρνω απαλλαγούμε από τη βιβλιοθήκη CS50,
μόνο για να εκθέσει ότι s είναι πράγματι ένα αστέρι char, απλά ένα συνώνυμο.
Και t είναι επίσης ένα αστέρι char.
Αλλά τι συμβαίνει σχετικά με την δεξιά πλευρά της εν λόγω γραμμής
όπου t αποδίδεται αξία;
>> Τι είναι η malloc;
Τι είναι strlen;
Τι είναι sizeof (char);
Γιατί στο καλό κάνει αυτό γραμμή ματιά τόσο περίπλοκο;
Τι κάνει σε υψηλό επίπεδο;
Τι είναι αυτό αποθήκευση σε t;
Ναι;
ΚΟΙΝΟ: Είναι μια κατανομή ορισμένο ποσό του χώρου μνήμης.
Είναι για την αποθήκευση, υποθέτω, γράμματα [δεν ακούγεται].
>> DAVID J. MALAN: Perfect.
Τέλεια.
Είναι κατανομή ένα ορισμένο ποσό του χώρου μνήμης
για την αποθήκευση, κατά πάσα πιθανότητα, στο μέλλον γράμματα.
Και ιδίως, malloc Ως εκ τούτου, επιστρέφοντας τι;
>> ΚΟΙΝΟ: Η επιστροφή του [δεν ακούγεται];
DAVID J. MALAN: Ακριβώς.
Επιστρέφοντας τη διεύθυνση της μνήμης, το οποίο είναι ένα φανταχτερό τρόπο λέγοντας,
επιστρέφει τη διεύθυνση του πρώτο byte της εν λόγω μνήμης.
Η ευθύνη είναι για μένα να θυμάμαι πόση μνήμη έχω πραγματικά
διατίθενται ή ζήτησε malloc για.
>> Τώρα, πόσο είναι αυτό;
Λοιπόν, ακόμα κι αν δεν υπάρχει πολλοί από παρενθέσεις εδώ,
malloc παίρνει ένα μόνο επιχείρημα.
Και είμαι διευκρινίζοντας strlen του s, έτσι ώστε να δώσει με όσες bytes, καθώς υπάρχουν σε s,
αλλά προσθέστε ένα.
Γιατί;
Ναι;
>> ΚΟΙΝΟ: Το backslash 0.
DAVID J. MALAN: Ακριβώς.
Έχουμε να κάνουμε ένα μικρό νοικοκυριό.
Έτσι, επειδή υπάρχει μια ανάστροφη κάθετο 0, εμείς θα θυμούνται καλύτερα αυτό.
Διαφορετικά, θα πάμε για να δημιουργήσει μια σειρά ότι
δεν διαθέτει το εν λόγω ειδικό τερματισμού.
>> Εν τω μεταξύ, ακριβώς για να είναι super πρωκτικό, I sizeof (char) έχει,
μόνο σε περίπτωση που κάποιος τρέχει μου κωδικός δεν την συσκευή CS50,
αλλά ίσως ένα διαφορετικό υπολογιστή συνολικά, όπου χαρακτήρες
είναι ένα byte, κατά συνθήκη, αλλά δύο bytes, ή κάτι μεγαλύτερο από αυτό.
Είναι ακριβώς για να είναι σούπερ, super αντίθετος σε λάθη.
Ακόμη και αν, στην πραγματικότητα, είναι πιθανότατα πρόκειται να είναι ένα 1.
>> Τώρα, εν τω μεταξύ, θα πάω μπροστά και να αντιγράψετε το εγχόρδων, t βραχίονα i ισούται με t βραχίονα s.
Και εγώ θα αναβάλει για την τελευταία εβδομάδα κώδικα για να δείτε τι συμβαίνει.
Αλλά το βασικό πακέτο, και η λόγο έβαλα τον κώδικα τώρα σε πράσινο,
Είναι επειδή αυτό το πολύ τελευταία γραμμή, t βραχίονα 0 ισούται toupper,
έχει ως αποτέλεσμα την Αξιοποιώντας τα οποία κορδόνι;
t ή / και s;
Η τελευταία γραμμή του κώδικα.
>> Απλά t, γιατί ό, τι είναι συνέβη αυτή τη φορά,
αν μπορώ να αναιρέσω λίγο αυτό το τελευταίο βήμα, τι συνέβηκε, όταν καλώ malloc,
Παίρνω ουσιαστικά ένα κομμάτι της μνήμης ότι είναι το ίδιο μέγεθος με το πρωτότυπο,
γιατί αυτή είναι η αριθμητική έκανα.
Είμαι αποθήκευση σε t διεύθυνση του εν λόγω κομμάτι της μνήμης.
Ακόμα κι αν αυτό φαίνεται ωραίο και όμορφη, ωραία και κενό,
η πραγματικότητα είναι εκεί, τι θα κρατήσει καλώντας, τιμές σκουπίδια εδώ.
Αυτό το κομμάτι της μνήμης θα μπορούσε πολύ και έχουν χρησιμοποιηθεί στο παρελθόν,
μερικά δευτερόλεπτα, πριν από λίγα λεπτά.
Έτσι, θα μπορούσε απολύτως να υπάρξουν αριθμοί ή γράμματα εκεί, μόνο από ατύχημα.
Αλλά δεν είναι έγκυρη, μέχρι να εγώ συμπληρώσετε αυτό το κομμάτι της μνήμης
με πραγματικό χαρακτήρες, όπως κάνουμε ότι για βρόχο εκεί.
Εντάξει;
>> Μέχρι τώρα, το αποκορύφωμα της αυτά τα τρία παραδείγματα
που χρησιμοποιήθηκαν με φαινομενικά σπασμένα τελευταία φορά, αυτό το Swap παράδειγμα, αυτή η λειτουργία
εργαστεί με την έννοια ότι άλλαζε a και b.
Αλλά αυτό δεν λειτούργησε σε ό, τι άλλο νόημα;
Ναι;
>> ΚΟΙΝΟ: [δεν ακούγεται].
>> DAVID J. MALAN: Ακριβώς.
Αν ήταν να καλέσετε τη λειτουργία αυτή από another-- για παράδειγμα,
από μια συνάρτηση σαν κύριο, όπου Έχω μια μεταβλητή, χ και γ, καθώς εγώ
έκανε την περασμένη εβδομάδα, ίδιο κωδικό, και έχω περάσει σε x και y
να Swap, και στη συνέχεια να καλέσετε Swap-- αυτό, φυσικά, είναι η σωστή εκδοχή
είναι ό, τι είμαστε έτοιμοι να see-- δεν λειτούργησε.
Έτσι ποια είναι η λύση;
>> Λοιπόν, έτσι απλά να είναι σαφής, επιτρέψτε μου να πάμε μπροστά
και-- μου δώσει ένα δευτερόλεπτο εδώ, και να δείτε αν μπορώ να σας δείξω το τελευταίο, το οποίο
θα είναι in-- ας δούμε αν μπορώ να βρω αυτό το πραγματικό fast-- OK, [δεν ακούγεται].
Εντάξει, εκεί είναι.
Έτσι αγνοούν τις εντολές είμαι απλά πληκτρολογώντας.
Θέλω να ανακτήσετε σε την τελευταία στιγμή ένα παράδειγμα
από την τελευταία φορά, που καλείται τώρα δεν Swap.
>> Έτσι, δεν Swap είναι όπου φύγαμε από την τελευταία φορά,
σύμφωνα με την οποία, θα προετοιμαστεί x με 1 και y 2.
Στη συνέχεια καλέστε Swap, περνώντας σε 1 και 2.
Και στη συνέχεια αυτή η λειτουργία εργαστεί σε κάποια έννοια,
αλλά δεν είχε μόνιμη επίδραση στην x και y.
Έτσι, το ερώτημα στο χέρι είναι, πώς τώρα Δεν έχουμε καθορίσει πραγματικά αυτό το πρόβλημα;
Ποια είναι η λύση στο χέρι;
>> Λοιπόν, σε swap.c, η οποία είναι νέα και σήμερα, παρατηρήσετε ένα ζευγάρι των διαφορών.
Χ και Υ είναι τα ίδια.
Αλλά αυτό είναι σαφώς διαφορετικά για την γραμμή 25;
Τι νέο υπάρχει εκεί, αν θυμάστε τι έμοιαζε πριν από ένα δευτερόλεπτο;
>> ΚΟΙΝΟ: [δεν ακούγεται].
>> DAVID J. MALAN: Ναι.
Έτσι, τα συμπλεκτικά σύμβολα είναι ένα νέο κομμάτι της σύνταξης, όχι μόνο σε αυτό το πρόγραμμα,
αλλά και γενικότερα σε CS50.
Μέχρι σήμερα, δεν νομίζω έχουμε δει κάποια παραδείγματα
ή πραγματικά μίλησε για τους σε οποιαδήποτε λεπτομέρεια, πλην, ίσως, προληπτικά
στο τμήμα, ένα εμπορικό και σαν αυτό.
Λοιπόν, αποδεικνύεται εμπορικό και είναι ένα από τα τελευταία κομμάτια της νέας σύνταξης
θα πάμε για να μάθουν.
Όλα αυτό σημαίνει ότι είναι η διεύθυνση κάποιας μεταβλητής.
Σε ποια διεύθυνση έχει x ζουν;
Αλλά ποια διεύθυνση δεν y ζει;
Διότι, αν η θεμελιώδες πρόβλημα πριν
ήταν ότι οι x και y έχουν μετακυλιστεί αντίγραφα, αυτό που πραγματικά θέλουμε να κάνουμε
είναι να παρέχει Swap με σαν ένα θησαυρό χάρτης που οδηγεί σε όπου x και y πράγματι
βρίσκονται στη μνήμη RAM, έτσι ώστε Swap μπορεί να ακολουθήσει αυτό το χάρτη
και να πάει οπουδήποτε x ή y σηματοδοτεί το σημείο και να αλλάξετε τις πραγματικές τιμές 1 και 2
εκεί.
>> Έτσι Swap πρέπει να αλλάξει ελαφρώς πάρα πολύ.
Και με την πρώτη ματιά, αυτό θα μπορούσε φαίνεται λίγο παρόμοια με char αστέρι.
Και πράγματι είναι.
Έτσι, ένα είναι ένας δείκτης για το τι είδος των δεδομένων, με βάση αυτό το επισημασμένο μέρος;
Έτσι είναι ένα int.
>> Έτσι, ένα δεν είναι πλέον ένα int, είναι η διεύθυνση ενός int.
Και ομοίως, b είναι τώρα σε εξέλιξη να είναι η διεύθυνση ενός ενδ.
Έτσι, όταν Καλώ τώρα Swap από τον κεντρικό, Είμαι δεν πρόκειται να δώσει Swap 1 και 2.
Πάω να το δώσει, όπως Ox-κάτι και Ox-κάτι,
δύο διευθύνσεις που θα οδηγήσει Εναλλαγή σε πραγματικές θέσεις τους
στη μνήμη του υπολογιστή μου.
>> Μέχρι τώρα, απομένει η εφαρμογή μου χρειάζεται να αλλάξει ένα αγοράκι.
Τι είναι προφανώς διαφορετικά τώρα σε αυτές τις τρεις γραμμές κώδικα;
Υπάρχουν αυτά τα αστέρια δεκάρα όλα όλη τη χώρα, εντάξει;
Λοιπόν, τι συμβαίνει εδώ;
Ναι;
>> ΚΟΙΝΟ: Είναι προφανές ότι [δεν ακούγεται].
>> DAVID J. MALAN: Ακριβώς.
Έτσι, σε αυτό το context-- και αυτό δεν ήταν η καλύτερη απόφαση σχεδιασμού, κατά γενική ομολογία,
χρόνια πριν.
Σε αυτό το πλαίσιο, όπου έχετε μόνο ένα αστέρι,
και δεν έχετε έναν τύπο δεδομένων, όπως int, αμέσως προς τα αριστερά,
αντί να έχετε ένα σύμβολο της ισότητας, σαφώς, Στο πλαίσιο αυτό, όταν λέτε πρωταγωνιστήσει ένα,
αυτό σημαίνει ότι πάει για το διεύθυνση που είναι στο ένα.
Ακολουθήστε το χάρτη θησαυρού, να το πω έτσι.
>> Και εν τω μεταξύ, σε γραμμή 37, αυτό σημαίνει το ίδιο πράγμα.
Πηγαίνετε στη διεύθυνση μια, και να θέσει ό, τι υπάρχει;
Όποια και αν είναι η θέση που β ορίζει.
Με άλλα λόγια, πηγαίνετε στο b.
Πάρτε αυτή την τιμή.
Πηγαίνετε στο ένα και, ανά την ίση υπογράψει, ο τελεστής ανάθεσης,
τεθεί η αξία εκεί.
>> Ομοίως, int temp είναι απλά ένας int.
Τίποτα δεν πρέπει να αλλάξει για temp.
Είναι απλά ένα ανταλλακτικό γυαλί από Annenberg για κάποιο γάλα ή χυμό πορτοκαλιού.
Αλλά δεν χρειάζεται να πω, πηγαίνετε στο b.
Πηγαίνετε προς τον προορισμό και θέσει την αξία σε θερμοκρασία εκεί.
Έτσι τι συμβαίνει τότε;
Όταν πραγματικά καλέστε Swap αυτή τη φορά, αν αυτό το πρώτο δίσκο εδώ αντιπροσωπεύει Main,
αυτό το δεύτερο δίσκο αντιπροσωπεύει Swap, όταν Περνώ ampersand x και y ampersand
από τον κεντρικό προς Swap, ακριβώς για να είναι σαφής, τι είναι αυτό στοίβα λήψης καρέ;
Ναι;
>> ΚΟΙΝΟ: [δεν ακούγεται].
DAVID J. MALAN: Ακριβώς.
Η διεύθυνση του x και η διεύθυνση του y.
Και μπορείτε να σκεφτείτε αυτά όπως ταχυδρομικές διευθύνσεις.
33 Oxford Street και 35 Oxford Street, και σας
θέλετε να μετακινήσετε τα δύο κτίρια που βρίσκονται σε αυτές τις τοποθεσίες.
>> Είναι το είδος της μια γελοία ιδέα, αλλά αυτό είναι όλο εννοούμε με τη διεύθυνση.
Σε περίπτωση που στον κόσμο μπορεί να μπορείτε να βρείτε αυτές τις δύο ints;
Σε περίπτωση που στον κόσμο μπορεί να σας βρείτε αυτά τα δύο κτίρια;
Έτσι, αν τελικά, μετά από όλο αυτό το διάστημα I πηγαίνετε στον πηγαίο κώδικα του σήμερα και την κατάρτιση
Swap και να τρέξει ./swap, τέλος, για το πρώτη φορά δεν μπορούμε πραγματικά να δείτε ότι
αξίες μου έχουν όντως έχει μετατραπεί επιτυχώς.
Και τώρα, μπορούμε να πάρουμε ακόμα σημειώματος αυτού, ας πούμε, gdb.
>> Έτσι, επιτρέψτε μου να πάω στο ίδιο αρχείο.
Επιτρέψτε μου να πάει μπροστά και να τρέξει gdb της ./swap.
Και τώρα, το Swap, Πάω να πάει μπροστά και να ορίσετε ένα σημείο καμπής στο Main.
Και τώρα είμαι πρόκειται να πάει μπροστά και να τρέξει το πρόγραμμα.
Και τώρα βλέπουμε τον κωδικό μου παύση σε αυτή τη γραμμή.
>> Αν πάω μπροστά και εκτύπωση x, τι πρέπει να δούμε εδώ;
Είναι ένα ερώτημα.
Πείτε ξανά;
>> ΚΟΙΝΟ: [δεν ακούγεται].
>> DAVID J. MALAN: Έτσι, τυχαίους αριθμούς, ίσως.
Ίσως είμαι τυχερός, και είναι ωραίο και απλό, όπως το 0.
Αλλά ίσως είναι κάποιο τυχαίο αριθμό.
Σε αυτή την περίπτωση, ήμουν τυχερός.
Απλά τυχαίνει να είναι 0.
Αλλά είναι πράγματι τύχη, γιατί όχι μέχρι να
πληκτρολογήστε το επόμενο και στη συνέχεια να εκτυπώσετε x έχει ότι γραμμή κώδικα, γραμμή 19, έχουν εκτελεστεί.
>> Εν τω μεταξύ, αν πληκτρολογήσετε την επόμενη φορά, και τώρα να εκτυπώσετε y, Πάω να δείτε 2.
Τώρα, αν πληκτρολογήσετε την επόμενη, πρόκειται να να πάρει μια μικρή σύγχυση, γιατί τώρα,
η printf πρόκειται να εμφανιστεί στην η οθόνη, όπως το έκανε. το χ είναι 1.
>> Ας το κάνουμε και πάλι.
Και τώρα, εδώ είναι όπου τα πράγματα γίνονται ενδιαφέροντα.
Πριν Καλώ Swap ή ακόμη βήμα σε αυτό, ας ρίξουμε μια μικρή ματιά.
χ είναι, πάλι, 1.
Υ είναι, φυσικά, γρήγορη λογική ελέγχει, 2, έτσι δεν είναι δύσκολο εκεί.
Αλλά τι είναι εμπορικό και x;
Απάντηση, αυτό είναι το είδος του funky αναζητούν.
Αλλά το αστέρι int στις παρενθέσεις είναι απλά τρόπο αεπ της λέγοντας ότι αυτό είναι μια διεύθυνση.
Είναι δεν είναι int, είναι ένας δείκτης σε μια Int, ή αλλιώς γνωστή ως μια διεύθυνση.
>> Τι είναι αυτό το τρελό πράγμα;
Εμείς ποτέ δεν έχω δει κάτι αρκετά όπως αυτό πριν.
Έτσι, αυτή είναι η διεύθυνση του υπολογιστή μου μνήμη όπου x συμβαίνει να ζήσουν.
Είναι Ox-κάτι.
Και αυτό είναι, ειλικρινά, γιατί Έχω αρχίσει να τραβούν βέλη,
αντί για αριθμούς, γιατί ποιος πραγματικά νοιάζεται
ότι int σας είναι σε μια συγκεκριμένη διεύθυνση που είναι τόσο μεγάλο.
Αλλά bffff0c4, αυτά είναι όλα Πράγματι δεκαεξαδικά ψηφία,
που είναι από 0 έως f.
>> Γι 'αυτό και δεν πρόκειται να σταθώ πάρα πολύ καιρό για το τι είναι αυτά τα πράγματα.
Αλλά αν εκτυπώσετε y, Φυσικά, βλέπω 2.
Αλλά ampersand y, βλέπω αυτή τη διεύθυνση.
Και ειδοποίηση, για την περίεργη, πόσο μακριά είναι x και y;
Μπορείτε να αγνοήσετε το μεγαλύτερο μέρος της διεύθυνσης.
Τέσσερα bytes.
Και αυτό είναι σύμφωνο με μας νωρίτερα ισχυρίζονται ότι το πόσο μεγάλο είναι ένα int;
Τέσσερα bytes.
Έτσι μοιάζει με επένδυση τα πάντα είναι μέχρι όμορφα, όπως ίσως ελπίδα, στη μνήμη.
>> Μέχρι τώρα, ας fast forward στο τέλος αυτής της ιστορίας.
Ας πάμε μπροστά και πληκτρολογήστε το βήμα, να βουτήξει τη λειτουργία Swap.
Τώρα, προσέξτε, αν πληκτρολογήσετε ένα, είναι ταυτόσημη με την διεύθυνση του x.
Αν πληκτρολογήσετε b, είναι πανομοιότυπα στη διεύθυνση του y.
Λοιπόν, τι πρέπει να δω αν έχω ας πούμε, πηγαίνετε στη διεύθυνση ενός;
Έτσι εκτυπώσετε ένα αστέρι.
Έτσι αστέρι σημαίνει ότι εκεί, σε αυτό το πλαίσιο.
Ampersand σημαίνει ποια είναι η διεύθυνση του.
Έτσι πρωταγωνιστήσει ένα μέσο 1.
Και αστέρων εκτύπωσης b μου δίνει 2.
>> Και επιτρέψτε μου να υποθέσουμε, προς το παρόν, ότι τουλάχιστον ο κώδικας που
εκτελέσει την πλέον μπορεί να αιτιολογημένη με αυτόν τον τρόπο.
Αλλά εμείς θα επανεξετάσουμε αυτή την ιδέα πριν από καιρό.
Έτσι, αυτή η έκδοση του Swap είναι τώρα σωστό και επιτρέπει
μας για να ανταλλάξουν το συγκεκριμένο τύπο δεδομένων.
>> Έτσι, οποιεσδήποτε ερωτήσεις, στη συνέχεια, στο Swap;
Την αστέρι;
Την διεύθυνση της;
Και θα δείτε, με πρόβλημα που 4, είδος,
αλλά το πρόβλημα που 5, σίγουρα, πως αυτά τα πράγματα είναι χρήσιμα και να πάρει πολύ περισσότερα
άνετα μαζί τους, ως αποτέλεσμα.
Τίποτα από όλα αυτά;
Εντάξει.
Έτσι malloc είναι, και πάλι, αυτή η λειτουργία ότι διαθέτει μόνο τη μνήμη, τη μνήμη
κατανομής.
Και γιατί είναι αυτό χρήσιμο;
Λοιπόν, όλο αυτό το διάστημα, έχετε χρησιμοποιήσει malloc.
Αν εξετάσουμε τώρα πώς GetString έργα, προφανώς, είναι
έχουν ζητήσει κάποιος για ένα κομμάτι της μνήμη, οποτεδήποτε ο χρήστης πληκτρολογεί ένα string
σε, γιατί σίγουρα Δεν ήξερε, όπως το προσωπικό CS50,
πόσο μεγάλη είναι αυτοί οι χορδές που οι άνθρωποι πρόκειται να πληκτρολογείτε μπορεί να είναι.
>> Οπότε ας, για πρώτη φορά, να αρχίσει να φλούδα πίσω το πώς λειτουργεί η βιβλιοθήκη CS50,
με τον τρόπο του ένα ζευγάρι των παραδειγμάτων ότι θα μας οδηγήσει εκεί.
Έτσι, αν ανοίξει το gedit και να ανοίξει scanf 0,
θα πάμε να δούμε τον παρακάτω κώδικα.
Scanf 0, διατίθεται στον δικτυακό τόπο για την σήμερα, έχει σχετικά λίγες γραμμές κώδικα
Εδώ, 14 έως 20.
Και ας δούμε τι κάνει.
Δηλώνει μια int, που ονομάζεται x.
Λέει κάτι σαν, τον αριθμό παρακαλώ.
Και τώρα λέει, scanf% i, & x.
Έτσι, υπάρχει ένα σωρό νέα πράγματα εκεί.
>> Αλλά scanf, μπορείτε να σκεφτείτε το είδος των της ως το αντίθετο της printf.
printf, φυσικά, εκτυπώσεις στην οθόνη.
scanf είδος των σαρώσεων από το χρήστη κάτι πληκτρολόγιο αυτός ή αυτή έχει πληκτρολογήσει.
>> % I είναι ακριβώς όπως printf.
Αυτό σημαίνει ότι αναμένουμε η χρήστη να πληκτρολογήσει έναν int.
Και τώρα, γιατί νομίζεις ότι μπορεί να περνά scanf & x;
Αν ο σκοπός της ζωής της scanf είναι να πάρει κάτι από το χρήστη,
ποια είναι η έννοια του περνώντας, και x, τώρα;
Ναι;
>> ΚΟΙΝΟ: [δεν ακούγεται].
DAVID J. MALAN: Ακριβώς.
Ό, τι εγώ, ο άνθρωπος, πληκτρολογήστε το, είσοδος μου πρόκειται να αποθηκευτεί σε αυτή τη θέση.
Δεν είναι επαρκής, υπενθυμίζουν, απλά περάσει σε x, επειδή έχουμε ήδη δει,
κάθε φορά που θα περάσει μόνο μια ακατέργαστη μεταβλητή, σαν int, σε κάποια άλλη λειτουργία,
Σίγουρα, μπορεί να το αλλάξει αυτό μεταβλητή, αλλά όχι μόνιμα.
Δεν μπορεί να έχει μια επίδραση στο Main.
Μπορεί να αλλάξει μόνο τη δική τοπικό αντίγραφο της.
Αλλά αν, αντ 'αυτού, δεν έχετε να μου δώσει την πραγματική int,
αλλά να μου δώσει οδηγίες για ότι int, εγώ τώρα, είναι scanf,
σίγουρα, μπορώ να ακολουθήσω ότι αντιμετωπίσει και να βάλει έναν αριθμό εκεί
έτσι ώστε να έχουν πρόσβαση σε αυτό, καθώς και.
>> Έτσι, όταν τρέχω το πρόγραμμα αυτό, ας δούμε.
Κάντε scanf 0 dot κάθετος, scanf 0.
Και αν τώρα πληκτρολογήστε έναν αριθμό όπως 50, ευχαριστώ για την 50.
Αν τώρα πληκτρολογήσετε έναν αριθμό, όπως αρνητικός 1, για την αρνητική 1.
Τώρα πληκτρολογήστε έναν αριθμό όπως το 1,5, hm.
Γιατί το πρόγραμμά μου αγνοήσει μου;
Λοιπόν, γιατί απλά, είπα να αναμένουν μόνο μια int.
Εντάξει.
Έτσι, αυτό είναι μια έκδοση του αυτό.
Ας πάρουμε όμως τα πράγματα επάνω μια εγκοπή και προτείνουν ότι αυτό δεν είναι καλό.
Και εδώ βρίσκεται ένα πολύ απλό παράδειγμα πώς μπορούμε να αρχίσουμε το γράψιμο κώδικα
ότι οι άλλοι άνθρωποι μπορούν να εκμεταλλευτούν ή συμβιβαστεί με το να κάνουν κακά πράγματα.
Έτσι η γραμμή 16, τόσο όμοια στο πνεύμα με πριν,
αλλά δεν είμαι δηλώνοντας ότι int αυτή τη φορά.
Είμαι δηλώνοντας ότι char αστέρι, γνωστός και κορδόνι.
>> Αλλά τι σημαίνει αυτό στην πράξη;
Έτσι, αν δεν καθορίσετε μια address-- και Είμαι χαρακτηρίζοντάς αυθαίρετα, ρυθμιστικό,
αλλά θα μπορούσα να το ονομάσουμε s, να simple-- και, στη συνέχεια, να κάνω αυτό, να μου εξηγήσει,
αν μπορούσε, με βάση την προηγούμενη λογική, αυτό που κάνει scanf στη γραμμή 18,
εάν πέρασμα% s και ρυθμιστικό, η οποία είναι μια διεύθυνση;
Τι είναι η scanf, αν ισχύει η ακριβώς την ίδια λογική με την έκδοση 0,
Θα προσπαθήσουμε να κάνουμε εδώ, όταν το κάτι τύπους χρηστών σε;
Ναι;
>> ΚΟΙΝΟ: [δεν ακούγεται].
>> DAVID J. MALAN: Ακριβώς.
Scanf, με τη λογική νωρίτερα, πρόκειται να πάρει το string
ότι το ανθρώπινο δακτυλογραφημένο in-- είναι τώρα ένα κορδόνι,
δεν είναι ένας αριθμός, κατά πάσα πιθανότητα, αν αυτός ή αυτή cooperates--
και πρόκειται να προσπαθήσω να θέσω κορδόνι στη μνήμη, ανεξάρτητα από τη διεύθυνση
ρυθμιστικό καθορίζει.
Και αυτό είναι μεγάλη, επειδή ρυθμιστικό πράγματι προορίζεται να είναι μια διεύθυνση.
>> Αλλά εγώ υποστηρίζουν το πρόγραμμα αυτό είναι προβληματικό σε μια πολύ σοβαρό τρόπο, επειδή ό, τι αξία είναι
ρυθμιστικό από προεπιλογή;
Τι έχω προετοιμαστεί μέσα;
Ποιο κομμάτι της μνήμης;
Δεν έχω, σωστά;
>> Έτσι, ακόμα κι αν έχω διατεθεί ένα αστέρι char που έχει πλέον ονομάζεται s,
αυτό είναι αντ 'αυτού που ονομάζεται, buffer-- έτσι ας συντάξει το όνομα της μεταβλητής
τώρα όπως buffer-- αν δεν έχουν ονομάζεται GetString ή malloc εδώ,
Αυτό σημαίνει ουσιαστικά ότι buffer είναι μόνο κάποια αξία σκουπίδια.
>> Τώρα τι σημαίνει αυτό;
Αυτό σημαίνει ότι έχω πει scanf να αναμένουν μια σειρά από το χρήστη.
Και ξέρετε τι;
Όποια και αν είναι αυτό το πράγμα που δείχνει να-- και ήθελα να επιστήσω ερωτηματικό,
αλλά στην πραγματικότητα, πρόκειται να κάτι σαν ΟΧ1, 2, 3, σωστά;
Είναι μερικές ψεύτικες αξία ότι μόνο συμβαίνει να είναι εκεί από πριν.
Έτσι, με άλλα λόγια, είναι σαν buffer είναι απλά
δείχνουν προς κάτι στη μνήμη.
Δεν έχω ιδέα τι.
>> Έτσι, αν πληκτρολογήσετε Gabe τώρα, πρόκειται να προσπαθήσει να βάλει g-a-b-e / 0 εκεί.
Αλλά ποιος ξέρει τι είναι αυτό;
Και κατά το παρελθόν, οποιαδήποτε φορά που έχουμε προσπαθήσει να αγγίξει
μνήμης που δεν ανήκουν για μας, ό, τι έχει συμβεί;
Ή σχεδόν κάθε χρόνο.
Τμηματοποίηση σφάλμα, σωστά;
>> Αυτό το βέλος, δεν έχω καμία ιδέα για το πού είναι κατάδειξης. είναι μερικά μόνο τυχαία τιμή.
Και φυσικά, αν ερμηνεύσει μια τυχαία τιμή ως μια διεύθυνση,
θα πάμε για να πάει στο κάποιο τυχαίο προορισμό.
Έτσι, Gabe μπορεί πράγματι να συντριβή το πρόγραμμά μου σε αυτήν την περίπτωση εδώ.
>> Τι μπορούμε λοιπόν να κάνουμε ότι είναι σχεδόν τόσο κακή;
Σκεφτείτε το τρίτο και τελευταίο παράδειγμα της scanf.
Αυτή η έκδοση είναι καλύτερη με ποια έννοια;
Εάν είστε άνετοι με το προηγούμενο πρόβλημα, αυτό είναι καλύτερο.
Γιατί;
>> ΚΟΙΝΟ: [δεν ακούγεται].
DAVID J. MALAN: Καλή.
Έτσι, η υπόθεση της γραμμής 16 είναι καλύτερη, με την έννοια
ότι είμαστε σαφώς την κατανομή κάποια μνήμη.
Εμείς δεν χρησιμοποιείτε malloc, είμαστε χρησιμοποιώντας την εβδομάδα 2
προσέγγιση του απλά δηλώνοντας μια σειρά.
Και έχουμε ξαναπεί ότι ένα string είναι απλά μια σειρά από χαρακτήρες,
έτσι αυτό είναι απολύτως θεμιτό.
Αλλά είναι, φυσικά, καθώς μπορείτε να σημειώσετε, σταθερού μεγέθους, 16.
>> Έτσι, αυτό το πρόγραμμα είναι απόλυτα ασφαλής, αν πληκτρολογήσετε
στις χορδές ενός χαρακτήρα, δύο χαρακτήρων χορδές, 15 στοιχειοσειρές.
Αλλά μόλις αρχίσω να πληκτρολογείτε 16, 17, 18, 1000 χορδές χαρακτήρα,
όπου αυτή η συμβολοσειρά θα καταλήξουμε;
Είναι πρόκειται να καταλήξει εν μέρει εδώ.
Αλλά τότε ποιος ξέρει τι άλλο είναι πέρα ​​από τα όρια
της συγκεκριμένης συστοιχίας;
>> Είναι σαν να έχω δηλωθεί 16 κουτιά εδώ.
Έτσι, αντί να αντλήσει από όλες τις 16, θα προσποιηθείς ότι έχω σχεδιάσει 16.
Αλλά αν στη συνέχεια, δοκιμάστε να διαβάσετε ένα string ότι είναι πολύ περισσότερο, όπως και 50 χαρακτήρες,
Πάω να αρχίσει η εφαρμογή α, β, γ, δ, χ, y, z.
Και αυτό είναι προφανώς κάποιο άλλο τμήμα μνήμης
ότι, και πάλι, μπορεί να προκαλέσει το πρόγραμμά μου για να συντρίψει,
γιατί δεν έχω ζητήσει τίποτα περισσότερο από ό, τι μόλις 16 bytes.
>> Έτσι, ποιος νοιάζεται;
Λοιπόν, εδώ είναι η βιβλιοθήκη CS50.
Και τα περισσότερα από αυτά είναι απλά όπως οδηγίες επάνω στην κορυφή.
Η βιβλιοθήκη CS50, όλο αυτό το διάστημα, είχε αυτή τη γραμμή στην γραμμή 52.
Έχουμε δει typedef, ή θα δείτε typedef
σε 4 το chipset, το οποίο δημιουργεί μόνο ένα συνώνυμο με την οποία char αστέρι μπορεί να είναι πιο
απλά αναφέρεται ως συμβολοσειρά.
Έτσι, αυτό είναι ένα από τα λίγα ρόδες
έχουμε χρησιμοποιήσει κρυφά κάτω από το καπό.
>> Εν τω μεταξύ, εδώ είναι η λειτουργία, getchar.
Τώρα, προφανώς, δεν υπάρχει σώμα για να το.
Και στην πραγματικότητα, αν κρατώ κύλιση, δεν το κάνω πραγματικότητα
δείτε οποιεσδήποτε εφαρμογές από αυτές τις λειτουργίες.
Ως έλεγχος λογική, γιατί είναι αυτό;
>> ΚΟΙΝΟ: [δεν ακούγεται].
DAVID J. MALAN: Ναι.
Έτσι, αυτό είναι το αρχείο κεφαλίδας.
Και τα αρχεία header περιέχει πρωτότυπα, συν κάποια άλλα πράγματα, όπως φαίνεται,
όπως typedefs.
Αλλά σε CS50.c, που έχουμε Ποτέ δεν θα δοθεί οριστικές,
αλλά έχει στην συσκευή CS50 όλα αυτή τη φορά, βαθιά μέσα από τους φακέλους της,
παρατηρήσετε ότι υπάρχει μια ολόκληρη δέσμη των λειτουργιών εδώ.
>> Στην πραγματικότητα, ας κύλιση προς τα κάτω.
Ας αγνοήσουμε τα περισσότερα από αυτά, για τώρα.
Όμως, μετακινηθείτε προς τα κάτω για να getInt και να δούμε πώς λειτουργεί getInt.
Έτσι, εδώ είναι getInt.
Και αν ποτέ νοιαζόταν πραγματικά πώς να πάρει int λειτουργεί, εδώ είναι η τεκμηρίωση της.
Και ανάμεσα στα πράγματα λέει ότι είναι αυτό που λέει
τι οι σειρές των τιμών μπορεί να επιστρέψει.
Είναι ουσιαστικά αρνητικό 2000000000 σε θετική 2000000000, ή να δώσει.
>> Και αποδεικνύεται, όλα αυτά χρόνο, ακόμα κι αν έχουμε ποτέ
είχε να ελέγξετε για αυτό, αν κάτι πάει στραβά,
αποδεικνύεται ότι όλα αυτή τη φορά, getInt έχει
έχουν επιστροφή ενός ειδικού σταθερή, δεν είναι μηδενική,
αλλά μάλλον INT_MAX, η οποία είναι σύμβαση μόνο ενός προγραμματιστή.
Αυτό σημαίνει ότι εδώ είναι μια ιδιαίτερη αξία.
Σιγουρευτείτε για να ελέγξετε για αυτό, απλά σε περίπτωση που κάτι πάει στραβά.
Αλλά ποτέ δεν έχω ενοχλήσει με ότι μέχρι σήμερα,
επειδή πάλι, αυτό έχει ως στόχο να απλοποιήσει.
>> Αλλά πώς getInt να εφαρμοστεί;
Λοιπόν, το ένα, αυτό δεν παίρνει επιχειρήματα.
Γνωρίζουμε ότι.
Επιστρέφει έναν int.
Γνωρίζουμε ότι.
Έτσι, πώς λειτουργεί κάτω από την κουκούλα;
>> Έτσι, υπάρχει προφανώς μια άπειρη βρόχος, τουλάχιστον η εμφάνιση του ενός.
Παρατηρήστε ότι είμαστε χρησιμοποιώντας GetString.
Έτσι, αυτό είναι ενδιαφέρον. getInt καλεί τη δική μας λειτουργία, GetString.
Και τώρα γιατί θα μπορούσε αυτό να συμβεί;
Γιατί είναι αμυντικός εδώ στη γραμμή 165;
Τι θα μπορούσε να συμβεί στη γραμμή 164, ακριβώς για να είναι σαφές;
Είναι η ίδια απάντηση όπως και πριν.
Θα μπορούσε απλώς να είναι έξω από τη μνήμη.
Κάτι πάει στραβά με GetString, έχουμε για να είναι σε θέση να χειριστεί αυτό.
Και ο λόγος που δεν επιστρέφουν null είναι ότι, από τεχνική άποψη, η μηδενική είναι ένας δείκτης.
getInt πρέπει να επιστρέψει ένα int.
Έτσι έχω αυθαίρετα αποφάσισε, κατ 'ουσίαν,
ότι 2 δισεκατομμύρια, ή να δώσει, πρόκειται να είναι μια ιδιαίτερη αξία, τι μπορώ ποτέ
πραγματικά να πάρει από το χρήστη.
Είναι μόνο η μία τιμή Πάω τα απόβλητα να αποτελούν έναν κωδικό σφάλματος.
>> Μέχρι τώρα, τα πράγματα παίρνουν λίγο φανταχτερό.
Και αυτό δεν είναι ακριβώς το ίδιο λειτουργία όπως και πριν, αλλά είναι πολύ παρόμοια.
Έτσι παρατηρήσετε, δηλώνω εδώ, στη γραμμή 172, και ένα int n και ένα char c.
Και τότε μπορώ να χρησιμοποιήσω αυτό το funky γραμμή, sscanf, η οποία αποδεικνύεται
δεν σαρώνει ένα string από το πληκτρολόγιο.
Στέκεται μια υπάρχουσα συμβολοσειρά που ο χρήστης έχει ήδη πληκτρολογήσει.
Γι 'αυτό και ήδη ονομάζεται GetString, η οποία σημαίνει ότι έχω ένα string στη μνήμη.
sscanf είναι αυτό που έπαιρνα καλέσετε μια συνάρτηση ανάλυσης.
Εξετάζει το κορδόνι που έχω πληκτρολογήσει, χαρακτήρα προς χαρακτήρα,
και να κάνει κάτι χρήσιμο.
Αυτό κειμένου αποθηκεύεται στη γραμμή.
Και ξέρω ότι μόνο με τη μετάβαση δημιουργήσετε αντίγραφα ασφαλείας εδώ και λέει, OH, OK,
Μου ζήτησε να μην s αυτή τη φορά, αλλά γραμμή.
>> Και τώρα αυτή είναι λίγο διαφορετική.
Αλλά αυτό σημαίνει ουσιαστικά, για λόγους θα κύμα κάπως τα χέρια μας σήμερα,
ότι έχουμε τον έλεγχο για να δείτε αν ο χρήστης πληκτρολογήσει το
και int και ίσως ένα άλλο χαρακτήρα.
Εάν ο χρήστης πληκτρολογήσει σε ένα int, είναι πρόκειται να αποθηκευτούν σε n, επειδή είμαι
πέρασμα αυτό από τη διεύθυνση, η νέο τέχνασμα που είδαμε σήμερα.
Εάν ο χρήστης πληκτρολογήσει επίσης σε παρόμοια 123x, ότι x
πρόκειται να τελειώσει μέχρι ένα επιστολή στον χαρακτήρα c.
>> Τώρα αποδεικνύεται ότι sscanf Θα μου πείτε, έξυπνα,
πόσες μεταβλητές ήταν sscanf με επιτυχία σε θέση να καλύψει.
Έτσι, με αυτή τη λογική, εάν η λειτουργία Είμαι εφαρμογή είναι getInt,
αλλά είμαι έλεγχο, δυνητικά, για τον χρήστη
να έχετε πληκτρολογήσει σε ένα int ακολουθείται από κάτι άλλο,
τι θέλω sscanf του τιμή επιστροφής πραγματικά να είναι;
Αν ο σκοπός είναι να πάρετε μόλις ένα int από το χρήστη;
>> Έτσι, αν sscanf αποδόσεις 2, τι σημαίνει αυτό;
Ο χρήστης πληκτρολογήσει κάτι σαν, κυριολεκτικά,
123x, το οποίο είναι απλά ανοησίες.
Είναι μια κατάσταση σφάλματος, και Θέλω να ελέγξει για αυτό.
>> Έτσι, αν ο χρήστης πληκτρολογεί αυτό το, από αυτή η λογική, αυτό που κάνει sscanf επιστρέψει,
θα λέγατε;
Έτσι πρόκειται να επιστρέψει 2, επειδή η 123 πρόκειται να πάει εδώ,
και το χ πρόκειται να καταλήξετε εδώ.
Αλλά δεν θέλω το x για να γεμίσει.
Θέλω να sscanf μόνο για να πετύχει στο συμπληρώνοντας την πρώτη από τις μεταβλητές του.
Και έτσι γι 'αυτό sscanf θέλουν να επιστρέψουν 1.
>> Και, εάν αυτό είναι λίγο πάνω από το κεφάλι Προς το παρόν, αυτό είναι εντελώς καλά.
Συνειδητοποίησε όμως, ότι ένα από τα τιμές των getInt και GetString
είναι ότι κάνουμε ένα καλό από μια Πολλοί από έλεγχο σφαλμάτων, όπως αυτό έτσι
ότι, μέχρι σήμερα, μπορείτε λίγο πολύ πληκτρολογήσετε τίποτα στο πληκτρολόγιό σας,
και εμείς θα το πιάσει.
Και σίγουρα, η προσωπικό, σίγουρα δεν θα
να είναι η πηγή ενός σφάλματος σε σας πρόγραμμα, γιατί είμαστε αμυντικά
έλεγχο για όλα τα ηλίθια πράγματα που ένας χρήστης μπορεί να κάνει,
όπως πληκτρολογώντας μια σειρά, όταν ήθελες πραγματικά int.
Έτσι, για now-- θα έρθει πίσω σε αυτό πριν long--
αλλά όλο αυτό το διάστημα, GetString και getInt έχουν
ήταν κάτω από την κουκούλα χρησιμοποιώντας αυτό βασική ιδέα των διευθύνσεων της μνήμης.
>> Μέχρι τώρα, ας κάνει τα πράγματα λίγο πιο φιλική προς το χρήστη.
Όπως ίσως θυμάστε, από Binky τελευταία time-- αν το ποντίκι μου θα συνεργαστείτε ώστε
είχαμε αυτόν τον κώδικα, η οποία ειλικρινά, είναι αρκετά ανόητο.
Ο κωδικός αυτός δεν επιτυγχάνει τίποτα χρήσιμος, αλλά ήταν ο παράδειγμα
ο καθηγητής Parlante χρησιμοποιείται για να αντιπροσωπεύσει
ό, τι συνέβαινε σε μια πρόγραμμα που θα περιλαμβάνει τη μνήμη.
>> Οπότε ας ξαναλέγω αυτό ιστορία super σύντομα.
Αυτές οι δύο πρώτες γραμμές, σε Αγγλικά, κάνει ό, τι θα λέγατε;
Ακριβώς σε λογικά ανθρώπινα, αλλά ελαφρώς τεχνικούς όρους, να λάβει μια μαχαιριά.
ΚΟΙΝΟ: [δεν ακούγεται].
>> DAVID J. MALAN: Εντάξει, είστε για την ίδρυση διευθύνσεις x και y μεταβλητές.
Όχι ακριβώς, επειδή το x και το y δεν είναι μεταβλητές με την παραδοσιακή έννοια.
x και y είναι οι διευθύνσεις ή θα αποθηκεύσετε τη διεύθυνση.
Οπότε ας προσπαθήσουμε άλλη μία φορά.
Δεν είναι ένα κακό ξεκίνημα, όμως.
Ναι;
>> ΚΟΙΝΟ: [δεν ακούγεται].
DAVID J. MALAN: Καλή.
Νομίζω ότι είναι λίγο καθαρότερο.
Δηλώνοντας δίποντα, δύο ακέραιοι.
Και είμαστε καλώντας τους x και y.
Ή αν ήταν να συντάξει αυτό ως μια εικόνα, και πάλι,
Υπενθυμίζουμε απλώς ότι όλα κάνουμε με την πρώτη γραμμή
πλησιάζει ένα κουτί σαν αυτό, με κάποια αξία σκουπίδια σε αυτό,
και καλώντας x, και στη συνέχεια, ένα άλλο πλαίσιο, όπως αυτό,
με κάποια αξία σκουπίδια σε αυτό, καλώντας y.
Έχουμε δηλώσει δύο δείκτες που τελικά
θα αποθηκεύσει τη διεύθυνση ενός int.
Έτσι ώστε να είναι όλα εκεί.
>> Έτσι, όταν Binky έκανε αυτό, η πηλό ακριβώς έμοιαζε με αυτό.
Και Nick ακριβώς το είδος της συνόψισε τα βέλη,
σαν να μην είστε δείχνουν πουθενά ιδίως, επειδή είναι ακριβώς
τιμές σκουπίδια.
Δεν είστε προετοιμαστεί ρητά οπουδήποτε ειδικότερα.
>> Τώρα, η επόμενη γραμμή κώδικα, ανάκληση, ήταν αυτό.
Έτσι, σε λογικά φιλική προς το χρήστη, αλλά κάπως τεχνικά Αγγλικά,
τι είναι αυτή η γραμμή του κώδικα που κάνει;
Ναι;
>> ΚΟΙΝΟ: [δεν ακούγεται].
>> DAVID J. MALAN: Perfect.
Είναι κατανομή της κομμάτι της μνήμης που είναι το μέγεθος ενός int.
Και αυτό είναι η μισή απάντηση.
Απαντήσατε το δικαίωμα ήμισυ της έκφρασης.
Τι συμβαίνει σχετικά με την αριστερή πλευρά του συμβόλου του ίσον;
Ναι;
ΚΟΙΝΟ: Και εκδοχείς αυτό με τη μεταβλητή x;
>> DAVID J. MALAN: Και εκδοχείς να την μεταβλητή x.
Έτσι, για να ανακεφαλαιώσουμε, δεξιά πλευρά διαθέτει η αρκετή μνήμη για την αποθήκευση ενός int.
Αλλά malloc ειδικά επιστρέφει τη διεύθυνση
του εν λόγω κομμάτι της μνήμης, το οποίο έχετε ακριβώς προτείνεται παίρνει αποθηκεύονται στο x.
>> Έτσι, ό, τι Νικ έκανε την τελευταία φορά με Binky είναι έσυρε αυτό το δείκτη έξω, ο πηλός,
να επισημάνω τώρα σε ένα λευκό κομμάτι της μνήμης ότι είναι ίση με το μέγεθος ενός ενδ.
Και πράγματι, αυτό σήμαινε να εκπροσωπεί τέσσερα bytes.
>> Τώρα, η επόμενη γραμμή κώδικα έκανε αυτό, αστέρι x παίρνει 42.
Έτσι, 42 είναι απλή για το δεξιά πλευρά, νόημα της ζωής.
Αριστερή πλευρά, αστέρι x σημαίνει αυτό;
Αυτό επίσης θα μπορούσε να έχει gone-- αυτό είναι εντάξει.
OK.
>> ΚΟΙΝΟ: Βασικά, πηγαίνετε στο [δεν ακούγεται]
DAVID J. MALAN: Καλή.
ΚΟΙΝΟ: [δεν ακούγεται].
DAVID J. MALAN: Ακριβώς.
Αριστερή πλευρά σημαίνει να πάει στο x.
x είναι η διεύθυνση.
Είναι σαν 33 Oxford Street, ή OX1.
Και αστέρι x σημαίνει να πάει στο ότι αντιμετωπίσει και να θέσει ό, τι υπάρχει;
42.
>> Έτσι, πράγματι, αυτό είναι ακριβώς ό, τι έκανε ο Νικ.
Ξεκίνησε με με, κατ 'ουσίαν, διανοητικά
δείχνοντας με το δάχτυλο χ, μετά από το βέλος
στο λευκό κουτί με το δεξί χέρι πλευρά, και βάζοντας τον αριθμό 42 εκεί.
Αλλά τότε τα πράγματα πήραν μια λίγο επικίνδυνο, σωστά;
Binky είναι έτοιμος να χάσει το κεφάλι του.
>> Κατηγορία y ισούται με 13, κακή τύχη, σημαίνει τι;
Έτσι αστέρι y μέσα πάει στην διεύθυνση y.
Αλλά ποια είναι η διεύθυνση του y;
Εντάξει, είναι αξία σκουπίδια, σωστά;
I επέστησε ως ένα ερωτηματικό.
Nick επέστησε ως κουλουριαστεί βέλος.
Και μόλις θα προσπαθήσουμε να κάνει αστέρι y, λέγοντας ότι πάει εκεί,
αλλά δεν υπάρχει νόμιμη διεύθυνση, είναι μερικές ψεύτικες θέση,
το πρόγραμμα πρόκειται να συντριβή.
Και το κεφάλι του Binky πρόκειται να πετάξει από εδώ, όπως έκανε.
>> Έτσι, στο τέλος, αυτό το πρόγραμμα ήταν μόνο κατ 'έξω ελάττωμα.
Ήταν ένα πρόγραμμα λάθη.
Και θα έπρεπε να καθοριστεί.
Και ο μόνος τρόπος, πραγματικά, για να το φτιάξω θα ήταν, για παράδειγμα, αυτή η γραμμή,
που δεν είχαμε ακόμη και να, επειδή το πρόγραμμα έπεσε πολύ σύντομα.
Αλλά αν ήταν να το διορθώσετε αυτό, ό, τι επίδραση έχει κάνει y ίση x έχουν;
Λοιπόν, αυτό δείχνει ουσιαστικά y σε ανεξαρτήτως της αξίας x είναι δείχνοντας.
>> Έτσι, στην ιστορία του Νικ, ή ιστορία Binky, τόσο
x και y έχουν δείχνοντας το λευκό κομμάτι της μνήμης,
έτσι ώστε, τελικά, όταν να πρωταγωνιστήσει y ισούται με 13 και πάλι,
θα καταλήξετε βάζοντας σε 13 η κατάλληλη τοποθεσία.
Έτσι, όλες αυτές οι γραμμές είναι τέλεια νόμιμο, εκτός από αυτό,
όταν αυτό συνέβη πριν σας στην πραγματικότητα αποδίδεται y κάποια αξία.
>> Τώρα, ευτυχώς, δεν το κάνετε πρέπει να τον λόγο με όλα
από αυτά τα είδη των θεμάτων για τη δική σας.
Επιτρέψτε μου να πάει μπροστά και να ανοίξει μέχρι ένα παράθυρο τερματικού εδώ
και να ανοίξει, για μια στιγμή, ένα σούπερ μικρό πρόγραμμα το οποίο
Επίσης, είναι το είδος της νόημα.
Είναι άσχημο.
Δεν έχει επιτευχθεί τίποτα χρήσιμο.
Αλλά αυτό δεν αποδεικνύει θέματα της μνήμης, οπότε ας ρίξουμε μια ματιά.
>> Main, εξαιρετικά απλή.
Καλεί προφανώς μια λειτουργία, f, και στη συνέχεια επιστρέφει 0.
Είναι λίγο δύσκολο να το χάος αυτό επάνω.
Έτσι Main είναι αρκετά καλή, μέχρι στιγμής.
>> Έτσι f είναι προβληματική.
Και απλά δεν έθεσε πολύ προσπάθεια σε ονομάζοντάς
εδώ, για να κρατήσει την εστίαση σχετικά με τον κώδικα.
f έχει δύο γραμμές.
Και ας δούμε τι συμβαίνει σήμερα στην.
Έτσι αφενός here-- και επιτρέψτε μου να
Αυτό το σύμφωνο με την προηγούμενη example-- αφενός,
η αριστερή πλευρά είναι κάνει ό, τι, στα αγγλικά;
Είναι is--
ΚΟΙΝΟ: Δημιουργία ενός δείκτη.
DAVID J. MALAN: Δημιουργία ενός δείκτη σε int και αποκαλώντας το x.
Έτσι είναι η δημιουργία ενός από αυτά τα κουτιά Συνεχίζω με βάση την οθόνη αφής.
Και τώρα, στη δεξιά πλευρά πλευρά, malloc, φυσικά,
κατανέμει ένα μεγάλο κομμάτι της μνήμης.
Και ακριβώς για να είναι σαφές, πώς πολύ μνήμη είναι προφανώς
κατανομή, αν απλά το είδος του κάνει τα μαθηματικά εδώ;
>> Έτσι είναι 40 bytes.
Και ξέρω ότι μόνο και μόνο επειδή γνωρίζω ότι μια int, σχετικά με τη συσκευή CS50, τουλάχιστον,
είναι τέσσερα bytes.
Έτσι, 10 φορές 4 είναι 40.
Έτσι, αυτό είναι η αποθήκευση ενός x, η διεύθυνση του πρώτου από 40 ints ότι
έχουν διατεθεί χώρος πίσω, προς τα πίσω, προς τα πίσω, προς τα πίσω.
>> Και αυτό είναι το κλειδί για την malloc.
Δεν παίρνει μια μικρή μνήμη Εδώ, λίγο εδώ, λίγο εδώ.
Σας δίνει ένα κομμάτι της μνήμης, εφαπτόμενα, από το λειτουργικό
σύστημα.
>> Τώρα τι γίνεται με αυτό, x βραχίονα 10 ισούται με 0;
Αυθαίρετη γραμμή κώδικα.
Δεν έχει επιτευχθεί τίποτα χρήσιμο.
Αλλά είναι ενδιαφέρον, επειδή x στήριγμα 10--;
Ναι;
>> ΚΟΙΝΟ: [δεν ακούγεται];
>> DAVID J. MALAN: x βραχίονα 10 δεν πρέπει να είναι μηδενική.
Η λεπτομέρεια null έρχεται μόνο στο παιχνίδι με χορδές, στο τέλος μιας συμβολοσειράς.
Αλλά μια καλή σκέψη.
>> Πόσο μεγάλη είναι αυτή η σειρά, ακόμα και αν έχω διατεθεί 40 bytes;
Είναι 0 έως εννέα, σωστά;
Είναι 10 πόντους, κάτι συνολικά.
40 bytes, αλλά 10 πόντους, κάτι αναπροσαρμόζονται από 0 έως 0.
>> Έτσι τι είναι αυτό βραχίονα x 10;
Είναι πραγματικά κάποια άγνωστης αξίας σκουπίδια.
Είναι μνήμη που δεν ανήκει σε μένα.
Δεν θα πρέπει να αγγίζετε ότι byte αριθμό 41, 42, 43, 44.
Πάω λίγο πολύ μακριά.
>> Και πράγματι, αν τρέχω προγράμματος, θα μπορούσε κάλλιστα συντριβή.
Αλλά μερικές φορές, να σταθούμε τυχεροί.
Και έτσι απλά για να επιδείξουν Αυτό-- και ειλικρινά,
ποτέ δεν ξέρεις προτού Δεν it-- ας τρέξει αυτό.
Είναι στην πραγματικότητα δεν συντριβή.
>> Αλλά αν μπορώ να αλλάξω αυτό, για παράδειγμα, να είναι σαν 1000,
να κάνει αυτό πραγματικά σκόπιμη, ας δούμε
αν μπορούμε να το πάρει για να συντρίψει αυτή τη φορά.
Εντάξει, αυτό δεν συντριβή.
Πόσο περίπου 100.000;
Ας το ξανακάνω, και τώρα επαναληφθεί.
OK.
Φτου.
Εντάξει.
Έτσι προφανώς, πάλι, αυτά τμήματα της μνήμης, να το πω έτσι,
είναι αρκετά μεγάλο, ώστε να μπορούμε να να πάρει και πάλι και πάλι τυχεροί.
Αλλά τελικά, μόλις πάρετε γελοίο και πραγματικά να πάει μακριά από την οθόνη,
αγγίξετε τη μνήμη που πραγματικά, πραγματικά δεν ανήκει σε σας.
>> Αλλά ειλικρινά, αυτά του είδους τα προβλήματα θα
να είναι όλο και πιο δύσκολο για να καταλάβω από μόνος σας.
Αλλά ευτυχώς, όπως προγραμματιστές, έχουμε εργαλεία που μας επιτρέπουν να το κάνουμε αυτό για μας.
Έτσι, αυτό είναι, ίσως, ένας από τις πιο άσχημες προγραμμάτων,
ακόμα πιο άσχημο από έξοδο gdb του.
Αλλά έχει πάντα μια γραμμή ή δύο που είναι εξαιρετικά χρήσιμο.
>> Valgrind είναι ένα πρόγραμμα που βοηθά δεν debug ένα πρόγραμμα, per se,
αλλά να βρει μνήμη-σχετικές προβλήματα, συγκεκριμένα.
Θα τρέξει αυτόματα τον κωδικό σας για σας και να αναζητήσουν τουλάχιστον δύο πράγματα.
Ένα, έκανες κάτι τυχαία όπως η μνήμη αφής
ότι δεν ανήκει σε σας;
Θα σας βοηθήσει να βρείτε τις υποθέσεις αυτές.
>> Και τα δύο, θα βοηθήσει μπορείτε να βρείτε κάτι που ονομάζεται
διαρροές μνήμης, το οποίο έχουμε αγνοείται παντελώς, αφελώς,
για κάποιο χρονικό διάστημα και μακάρια.
Αλλά τελικά, όλα Αυτή τη φορά, όποτε
έχετε καλέσει GetString σε έτσι πολλά από τα προγράμματά μας,
ζητάς το λειτουργικό συστήματος για τη μνήμη,
αλλά έχετε κάποια ανάμνηση από αυτό δίνει ποτέ
πίσω, κάνει UNALLOC, ή δωρεάν, όπως λέγεται.
Όχι, γιατί έχουμε ποτέ σας ζητηθεί να το πράξουν.
>> Αλλά όλο αυτό το διάστημα, τα προγράμματα έχετε γράψει σε C
έχουν διαρροή μνήμης, ζητώντας από το λειτουργικό
συστήματος για όλο και περισσότερο μνήμη για έγχορδα και εταζέρα,
αλλά ποτέ δεν παραδίδοντας πίσω.
Και τώρα αυτό είναι ένα κομμάτι μιας υπεραπλούστευση,
αλλά αν έχετε τρέξει ποτέ Mac σας ή PC σας για αρκετό καιρό, το άνοιγμα
πολλά από τα προγράμματα, ίσως το κλείσιμο των προγραμμάτων,
και ακόμα κι αν σας ο υπολογιστής δεν έχει συνετρίβη,
είναι να πάρει τόσο πολύ πιο αργή, σαν να είναι πραγματικά
χρησιμοποιούν πολλή μνήμη ή πόροι, παρότι,
αν δεν είστε ακόμη αγγίξετε το πληκτρολόγιο,
ότι θα μπορούσε να είναι-- αλλά δεν μπορούσα always-- είναι ότι τα προγράμματα που τρέχετε
έχουν οι ίδιοι διαρροές μνήμης.
Και να κρατήσει ζητώντας από το λειτουργικό σύστημα για περισσότερες και περισσότερη μνήμη, αλλά ξεχνώντας γι 'αυτό,
στην πραγματικότητα δεν το χρησιμοποιεί, αλλά Ως εκ τούτου, λαμβάνοντας μνήμης μακριά
από άλλα προγράμματα που μπορεί να το θέλουν.
Έτσι, αυτό είναι μια κοινή εξήγηση.
Τώρα εδώ είναι όπου Valgrind του εξόδου είναι τελείως
αποτρόπαια στους λιγότερο και όσο πιο άνετα.
Αλλά το ενδιαφέρον πράγματα είναι ακριβώς εδώ.
Αυτό μου λέει μια μη έγκυρη εγγραφή του μέγεθος τέσσερις συμβαίνει σε αυτό το πρόγραμμα,
ειδικότερα, στη γραμμή 21 του memory.c.
>> Αν πάω στην γραμμή 21, hm, πράγματι, υπάρχει είναι μια άκυρη εγγραφής του μεγέθους τέσσερα.
Γιατί το μέγεθος τέσσερα;
Λοιπόν, αυτό number-- και θα μπορούσε να είναι anything-- είναι ένα int.
Έτσι είναι τέσσερα bytes.
Έτσι Βάζω τέσσερα bytes όπου δεν ανήκουν.
Αυτό είναι ό, τι Valgrind είναι στην πραγματικότητα μου λέει.
Επιπλέον, θα είναι επίσης πες μου, όπως θα δούμε,
καθώς τρέχετε αυτό σε ένα μέλλον το chipset, αν και όταν έχετε διέρρευσαν μνήμη, η οποία μάλιστα
Δεν έχω, γιατί έχω ονομάζεται malloc, αλλά δεν έχουν στην πραγματικότητα
ονομάζεται, στην περίπτωση αυτή, ελεύθερο, που θα δούμε τελικά
είναι το αντίθετο της malloc.
>> Μέχρι τώρα, νομίζω, ένα τελευταίο παράδειγμα.
Έτσι, αυτό είναι λίγο πιο απόκρυφες, αλλά είναι ίσως
ο μεγαλύτερος λόγος για να να είστε προσεκτικοί με τη μνήμη,
και ο λόγος που πολλά προγράμματα ή / και web servers, ακόμα και σε αυτήν την ημέρα,
έχουν ληφθεί πάνω από κακούς κάπου στο διαδίκτυο που είναι κατά κάποιο τρόπο
αποστολή ψευδών πακέτα στον server σας προσπαθούν να θέσουν σε κίνδυνο τους λογαριασμούς σας,
ή να πάρετε τα δεδομένα σας, ή απλά γενικά αναλάβει μια μηχανή.
Υπερχείλιση μνήμης, καθώς η υποδηλώνει το όνομα, μέσα
ξεχειλίζει όχι ένα int, αλλά ένα buffer.
Και ένα ρυθμιστικό είναι μόνο ένα φανταχτερό τρόπο του λέγοντας ότι είναι ένα μάτσο μνήμης.
>> Και πράγματι, κάλεσα ένα string πριν από ρυθμιστικό διάλυμα, αντί του s.
Διότι αν είναι ένα ρυθμιστικό, όπως και με την έννοια του YouTube,
ή κάθε φορά που βλέπετε ένα βίντεο, μπορεί να έχετε δει τη λέξη buffering,
τελεία, τελεία, τελεία.
Είναι απίστευτα ενοχλητικό.
Και αυτό σημαίνει ότι μόνο ότι το video player σας
προσπαθεί να κατεβάσετε πολλά των bytes, πολλά bytes
από ένα βίντεο από το διαδίκτυο.
Αλλά η διαδικασία είναι αργή, γι 'αυτό προσπαθεί για να κατεβάσετε ένα σωρό από αυτούς
για να γεμίσει ένα ρυθμιστικό διάλυμα, ένα δοχείο, έτσι ώστε έχετε αρκετά bytes ότι μπορεί στη συνέχεια
σας δείξει το βίντεο, χωρίς να σταματάτε συνεχώς.
Αλλά τελικά, μπορείτε να έχουν ένα ρυθμιστικό διάλυμα σε αυτό το μεγάλο.
Αλλά προσπαθήστε να βάλετε αυτό το πολύ τα δεδομένα σε αυτό, και πολύ κακά πράγματα μπορούν να συμβούν.
Έτσι, για παράδειγμα, ας εξετάσουμε αυτό το τελικό τρέιλερ ενός παραδείγματος.
Αυτό είναι ένα άλλο πρόγραμμα ότι, με την πρώτη ματιά,
δεν κάνει τίποτα σούπερ χρήσιμο.
Έχει μια Κύρια λειτουργία που καλεί τη λειτουργία, f.
Και αυτή η λειτουργία, f, μέχρι εδώ, έχει μια σειρά char, που ονομάζεται c, μεγέθους 12.
Και τότε είναι που χρησιμοποιούν αυτό το νέα λειτουργία που ονομάζεται strncpy.
>> Αποδεικνύεται ότι, με αυτό το απλό, απλή γραμμή κώδικα, μόλις δύο γραμμές,
έχουμε κάνει ολόκληρο το πρόγραμμα μου, και, ως εκ τούτου, ολόκληρο τον υπολογιστή μου,
και ο λογαριασμός χρήστη μου, και τη σκληρή μου οδηγούν δυνητικά ευάλωτα σε κανέναν
ποιος ξέρει και είναι αρκετά καλή για να τρέξει αυτό το πρόγραμμα με μια ορισμένη γραμμή εντολών
επιχείρημα.
Με άλλα λόγια, εάν αυτό το κακό βάζει μέσα από argvargv [1] πληκτρολογώντας
στο πληκτρολόγιο ένα πολύ ειδικά δημιουργημένο εγχόρδων, δεν abc, 123, αλλά κατ 'ουσίαν,
δυαδικά σύμβολα που αντιπροσωπεύουν εκτελέσιμο κώδικα, ένα πρόγραμμα που αυτός ή αυτή έγραψε,
με αυτό το απλό πρόγραμμα, το οποίο είναι εκπρόσωπος των χιλιάδων προγραμμάτων
που είναι εξίσου ευάλωτες, daresay, αυτός ή αυτή μπορεί τελικά να διαγράψετε όλα
τα αρχεία στο σκληρό δίσκο μου, να πάρει ένα αναβοσβήνει εντολών, έτσι ώστε αυτός ή αυτή μπορεί να
πληκτρολογήστε τις εντολές για τη δική τους, email όλα τα αρχεία για τον εαυτό μου.
Ό, τι μπορώ να κάνω, αυτός ή μπορεί να το κάνει με αυτόν τον κωδικό.
>> Εμείς δεν θα λύσει εντελώς αυτό ακόμα.
Και στην πραγματικότητα, πρόκειται για περιλαμβάνει μια μικρή εικόνα
όπως αυτό, το οποίο θα έρθει σύντομα να κατανοήσουν τόσο το καλύτερο.
Αλλά για σήμερα, ας καταλήξει σε τι είναι, ελπίζω, μια ελαφρώς πιο
κατανοητό αστείο XKCD, μέχρι να επαναλάβει την επόμενη φορά.
Εντάξει.
Τα λέμε την Τετάρτη.
>> [ΜΟΥΣΙΚΗ ΠΑΙΖΟΝΤΑΣ]
>> ΟΜΙΛΗΤΗΣ: Και τώρα, βαθιά σκέψεις, από Daven Farnham.
Η μνήμη είναι σαν το άλμα σε ένα σωρό από χρυσά φύλλα σε ένα απόγευμα Κυριακής.
Άνεμος φυσά, πετώντας σας hair-- OH, μου λείπει τις ημέρες when--
>> [Γέλια]