[Powered by Google Translate] [ΤΜΗΜΑ 5: λιγότερο άνετα]
[Nate Hardison, Πανεπιστήμιο Χάρβαρντ]
[Αυτό είναι CS50.] [CS50.TV]
Έτσι, καλώς ήρθατε πίσω, παιδιά.
Καλώς ήρθατε στο τμήμα 5.
Σε αυτό το σημείο, έχοντας ολοκληρώσει κουίζ 0 και έχοντας δει πώς έχετε κάνει,
ελπίζω να αισθάνεστε πολύ καλά, γιατί ήμουν πολύ εντυπωσιασμένος από τα αποτελέσματα σε αυτή την ενότητα.
Για τους θεατές σε απευθείας σύνδεση μας, είχαμε μερικές ερωτήσεις
για τα τελευταία δύο προβλήματα για το σύνολο πρόβλημα - ή στο κουίζ, μάλλον.
Έτσι θα πάμε για να πάει πέρα ​​από τα πραγματικά γρήγορα, έτσι ώστε ο καθένας βλέπει ό, τι συνέβη
και πώς να περάσει μέσα από την πραγματική λύση και όχι μόνο την προβολή της ίδιας λύση.
Εμείς πάμε για να πάει πέρα ​​από το τελευταίο ζεύγος των προβλημάτων πραγματικά γρήγορα, 32 και 33.
Ακριβώς, και πάλι, έτσι ώστε οι τηλεθεατές σε απευθείας σύνδεση μπορούν να δουν αυτό.
>> Εάν ενεργοποιήσετε το πρόβλημά σας 32, η οποία βρίσκεται στη σελίδα 13,
13 από 16, 32 είναι πρόβλημα για όλες τις ανταλλαγές.
Ήταν όλα σχετικά με την εναλλαγή δύο ακέραιοι.
Είναι το πρόβλημα που είχαμε περάσει πάνω από μια-δυο φορές σε διάλεξη.
Και εδώ, αυτό που ζητούσαν να κάνετε είναι μια γρήγορη ίχνος μνήμης.
Για να συμπληρώσουμε τα τιμές των μεταβλητών όπως είναι στη στοίβα
όπως ο κώδικας περνάει μέσα από αυτή τη λειτουργία swap.
Συγκεκριμένα, αυτό που ψάχνουμε σε - Πάω να θέσει αυτό το iPad κάτω -
ειδικότερα, αυτό που ψάχνουμε είναι σε αυτή τη γραμμή αριθμό 6 δεξιά εδώ.
Και αυτό είναι αριθμημένα 6 για λίγο γειτνίαση με το προηγούμενο πρόβλημα.
Αυτό που θέλουμε να κάνουμε είναι να εμφανίσετε ή να επισημαίνουν την κατάσταση της μνήμης
όπως είναι κατά τη στιγμή εκτελούμε αυτό τον αριθμό της γραμμής 6,
το οποίο είναι ουσιαστικά μια επιστροφή από την λειτουργία ανταλλαγής μας εδώ.
Αν μετακινηθείτε προς τα κάτω εδώ, είδαμε ότι οι διευθύνσεις των πάντων στη μνήμη δόθηκε για μας.
Αυτό είναι πολύ βασικό? Θα επανέλθουμε σε αυτό σε λίγο.
Και τότε εδώ κάτω στο κάτω μέρος, είχαμε ένα μικρό διάγραμμα μνήμης που θα πάμε να αναφερθώ.
Έχω κάνει πραγματικά αυτό έξω στο iPad μου.
Έτσι, Πάω να εναλλάσσονται εμπρός και πίσω μεταξύ του iPad και αυτόν τον κώδικα μόνο για αναφορά.
>> Ας ξεκινήσει. Κατ 'αρχάς, ας επικεντρωθεί στο πρώτο ζευγάρι των γραμμών του κύριου εδώ.
Για να ξεκινήσετε, θα πάμε να προετοιμαστεί για x 1 και y για να 2.
Έτσι έχουμε δύο ακέραιες μεταβλητές, από όπου και αν και οι δύο πρόκειται να τοποθετηθούν στη στοίβα.
Εμείς πάμε για να βάλετε ένα 1 και ένα 2 σε αυτούς.
Έτσι, αν flip πάνω στο iPad μου, ελπίζω, ας δούμε -
Apple TV mirroring, και εκεί πάμε. Εντάξει.
Έτσι, αν flip πάνω στο iPad μου,
Θέλω να προετοιμαστεί για x 1 και y για να 2.
Εμείς το κάνουμε αυτό πολύ απλά γράφοντας ένα 1 στο κουτί με την ένδειξη x
και 2 στο κουτί με την ένδειξη y. Αρκετά απλό.
Έτσι τώρα ας πάμε πίσω στο φορητό υπολογιστή, να δούμε τι θα συμβεί στη συνέχεια.
Έτσι, αυτή η επόμενη γραμμή είναι όπου τα πράγματα παίρνουν δύσκολο.
Περνάμε τη διεύθυνση του x και τη διεύθυνση του y ως τις παραμέτρους a και b με τη λειτουργία ανταλλαγής.
Η διεύθυνση του x και τη διεύθυνση του y είναι πράγματα που δεν μπορούμε να υπολογίσουμε
χωρίς να αναφερθεί σε αυτά τα σημεία δεξιά σφαίρα εδώ κάτω.
Και ευτυχώς, οι δύο πρώτες κουκκίδες να μας πει τι ακριβώς είναι οι απαντήσεις.
Η διεύθυνση του χ είναι στη μνήμη 10, και η διεύθυνση του y στη μνήμη είναι 14.
Έτσι, αυτές είναι οι αξίες που παίρνουν πέρασε στην ως α και β επάνω στην κορυφή σε λειτουργία ανταλλαγής μας.
Έτσι, και πάλι, η μετάβαση πίσω στο διάγραμμα μας, μπορώ να γράψω ένα 10 σε μια
και 14 στο β.
Τώρα, αυτό είναι το σημείο όπου έχουμε προχωρήσει με τη συμφωνία ανταλλαγής.
Έτσι το κτύπημα πίσω στο laptop και πάλι,
βλέπουμε ότι ο τρόπος που λειτουργεί η ανταλλαγή είναι για πρώτη φορά dereference ένα κατάστημα και το αποτέλεσμα στο tmp.
Έτσι, ο χειριστής dereference λέει, "Hey. Αντιμετωπίστε τα περιεχόμενα της μεταβλητής ως μια διεύθυνση.
Μετάβαση σε ό, τι είναι αποθηκευμένο σε αυτή τη διεύθυνση, και το φορτίο αυτό. "
Τι τοποθετήσετε έξω από τη μεταβλητή πρόκειται να αποθηκευτούν σε μεταβλητή tmp μας.
Flipping πίσω στο iPad.
Αν πάμε να αντιμετωπίσει 10, γνωρίζουμε ότι η διεύθυνση 10 είναι το μεταβλητό x
γιατί μας είπαν από την κουκίδα μας ότι η διεύθυνση του x στη μνήμη είναι 10.
Έτσι, μπορούμε να πάμε εκεί, να πάρει την αξία του, η οποία είναι 1, όπως βλέπουμε στο iPad μας,
και να φορτώσετε ότι σε tmp.
Και πάλι, αυτό δεν είναι το τελικό περιεχόμενο.
Εμείς πάμε για να περπατήσει μέσα και θα φτάσουμε στον τελικό μας κατάσταση του προγράμματος στο τέλος.
Αλλά αυτή τη στιγμή, έχουμε την τιμή 1 αποθηκεύονται σε tmp.
>> Και υπάρχει μια γρήγορη ερώτηση εδώ.
[Αλέξανδρος] Είναι ο χειριστής dereference - αυτό είναι ακριβώς το σωστό αστέρι μπροστά από τη μεταβλητή;
Ναι >>. Έτσι, ο χειριστής dereference, όπως κτύπημα πίσω στο laptop μας για άλλη μια φορά,
είναι αυτό το αστέρι μπροστά.
Υπό αυτή την έννοια, είναι - να το αντιπαραβάλει με το διαχειριστή του πολλαπλασιασμού
η οποία απαιτεί δύο πράγματα? ο χειριστής dereference είναι ένας μοναδιαίος τελεστής.
Μόλις εφαρμοστεί σε μία τιμή, σε αντίθεση με ένα φορέα δυαδικό
όπου θα ισχύουν για δύο διαφορετικές τιμές.
Έτσι, αυτό είναι ό, τι συμβαίνει σε αυτή τη γραμμή.
Φορτώσαμε την τιμή 1 και να αποθηκεύονται προσωρινά σε ακέραια μεταβλητή μας.
Η επόμενη γραμμή, αποθηκεύουμε το περιεχόμενο του β σε -
ή, μάλλον, έχουμε αποθηκεύσει τα περιεχόμενα που β δείχνει να σε τόπο όπου δείχνει να.
Αν αναλύσουμε αυτό από τα δεξιά προς τα αριστερά, πρόκειται να dereference β,
πρόκειται να αντιμετωπίσει 14, πρόκειται να αρπάξει την ακέραιος που είναι εκεί,
και στη συνέχεια πρόκειται να πάει στην διεύθυνση 10,
και πρόκειται να ρίξει το αποτέλεσμα της dereference μας του β σε αυτό το χώρο.
Flipping πίσω στο iPad μας, όπου μπορούμε να κάνουμε αυτό το λίγο πιο συγκεκριμένο,
θα μπορούσε να βοηθήσει αν γράφω αριθμούς σε όλες τις διευθύνσεις εδώ.
Έτσι, γνωρίζουμε ότι στο y, είμαστε στη διεύθυνση 14, x είναι στη διεύθυνση 10.
Όταν ξεκινούν β, εμείς dereference β, θα πάμε να αρπάξει την τιμή 2.
Θα αρπάξει αυτή την τιμή, διότι αυτή είναι η αξία που ζει στην διεύθυνση 14.
Και θα πάμε για να το θέσω στη μεταβλητή που ζει στην διεύθυνση 10,
το οποίο είναι ακριβώς εκεί, που αντιστοιχεί σε μια μεταβλητή x μας.
Έτσι, μπορούμε να κάνουμε ένα μικρό κομμάτι από την αντικατάσταση εδώ
όπου μπορούμε να απαλλαγούμε από 1 μας και αντί να γράφουμε ένα 2.
Έτσι, όλα είναι ωραία και καλά στον κόσμο, ακόμα κι αν έχουμε αντικατασταθούν x τώρα.
Έχουμε αποθηκεύονται παλιά τιμή του x σε μεταβλητή tmp μας.
Έτσι, θα μπορέσουμε να ολοκληρώσουμε τη συμφωνία ανταλλαγής με την επόμενη γραμμή.
Flipping πίσω στο φορητό υπολογιστή μας.
Τώρα το μόνο που απομένει είναι να λάβει το περιεχόμενο από την προσωρινή μεταβλητή ακέραιου μας
και να τις αποθηκεύσετε στην μεταβλητή που ζει στην διεύθυνση που κρατά b.
Έτσι θα πάμε για την αποτελεσματική β dereference για να αποκτήσετε πρόσβαση στη μεταβλητή
δηλαδή στη διεύθυνση που κατέχει β σε αυτό,
και θα πάμε για να γεμίσει την αξία που tmp κρατά σε αυτό.
Flipping πίσω στο iPad για μια ακόμη φορά.
Μπορώ να διαγράψετε αυτή την τιμή, εδώ 2,
και αντ 'αυτού θα αντιγράψει το 1 δικαίωμα σε αυτό.
Στη συνέχεια, η επόμενη γραμμή που εκτελεί, φυσικά -
αν γυρίσετε πίσω στο φορητό υπολογιστή - αυτό είναι το σημείο 6,
το οποίο είναι το σημείο στο οποίο θέλουμε να έχουμε διάγραμμα μας συμπληρωμένη.
Έτσι το κτύπημα πίσω στο iPad για μια ακόμη φορά, ακριβώς έτσι μπορείτε να δείτε το ολοκληρωμένο διάγραμμα,
μπορείτε να δείτε ότι έχουμε ένα 10 σε μια, σε ένα 14 β, σε αναλογία 1 προς tmp, 2 σε x, και 1 στο y.
Υπάρχουν ερωτήσεις σχετικά με αυτό;
Μήπως αυτό κάνει πιο λογικό, αφού περπάτησαν μέσα από αυτό;
Κάντε λιγότερο νόημα; Ας ελπίσουμε ότι δεν είναι. Εντάξει.
>> Οι δείκτες είναι ένα πολύ δύσκολο θέμα.
Ένα από τα παιδιά που εργάζονται με έχει ένα πολύ κοινό ρητό:
"Για να καταλάβουμε δείκτες, θα πρέπει πρώτα να καταλάβουμε δείκτες."
Ποια πιστεύω ότι είναι πολύ αληθινό. Κάνει να πάρει λίγο χρόνο για να το συνηθίσεις.
Με πολλές φωτογραφίες, κλήρωση των διαγραμμάτων μνήμης όπως αυτή είναι πολύ χρήσιμη,
και αφού σας καθοδηγήσει παράδειγμα μετά παράδειγμα μετά παράδειγμα,
αυτό θα αρχίσει να κάνει λίγο περισσότερο νόημα και λίγο περισσότερο νόημα και λίγο περισσότερο νόημα.
Τέλος, μια μέρα, θα έχετε όλα πλήρως κατακτηθεί.
Οποιεσδήποτε ερωτήσεις πριν προχωρήσουμε στο επόμενο πρόβλημα; Εντάξει.
Έτσι, γυρίστε πίσω στο φορητό υπολογιστή.
Το επόμενο πρόβλημα που έχουμε είναι το νούμερο 33 στο πρόβλημα αρχείο I / O.
Μεγέθυνση σε αυτό το λίγο.
Πρόβλημα 33 - Ναι;
>> [Daniel] Είχα μόλις μια γρήγορη ερώτηση. Αυτό το αστέρι, ή ο αστερίσκος,
λέγεται εύρεση τιμών, όταν χρησιμοποιείτε έναν αστερίσκο πριν.
Τι είναι αυτό που ονομάζεται όταν χρησιμοποιείτε το εμπορικό και πριν;
>> Το εμπορικό είναι πριν από την διεύθυνση του-χειριστή.
Ας μετακινηθείτε προς τα πίσω επάνω.
Ωχ. Είμαι σε λειτουργία ζουμ, έτσι δεν μπορώ πραγματικά κύλισης.
Αν κοιτάξουμε αυτόν τον κώδικα πολύ γρήγορα εδώ,
και πάλι, το ίδιο πράγμα συμβαίνει.
Αν κοιτάξουμε αυτόν τον κώδικα ακριβώς εδώ, σε αυτή τη γραμμή, όπου θα γίνει η κλήση για να ανταλλάξουν,
Το εμπορικό είναι ακριβώς λέγοντας "να πάρει τη διεύθυνση στην οποία ζει μεταβλητή x."
Όταν μεταγλωττιστή σας μεταγλωττίζει τον κωδικό σας,
πρέπει να σηματοδοτήσει πραγματικά φυσικά μια θέση στη μνήμη για όλες τις μεταβλητές σας για να ζήσουν.
Και έτσι αυτό που ο μεταγλωττιστής μπορεί να κάνει τότε τη στιγμή που θα καταρτίζονται τα πάντα,
γνωρίζει, "Ω, έβαλα στη διεύθυνση x 10. έβαλα στη διεύθυνση y 14."
Μπορεί στη συνέχεια να συμπληρώσετε σε αυτές τις τιμές για εσάς.
Έτσι, μπορείτε στη συνέχεια - μπορεί να περάσει στη συνέχεια σε αυτό και να περάσει και στο y, καθώς και.
Αυτοί οι τύποι παίρνουν τη διεύθυνση, αλλά επίσης, όταν τα περάσει στη λειτουργία ανταλλαγής,
αυτό το είδος πληροφοριών, αυτό int * δικαίωμα εδώ, λέει ο compiler,
«Εντάξει, θα πάμε να την ερμηνεία αυτή ως διεύθυνση τη διεύθυνση της μεταβλητής ακεραίου."
Ως μια διεύθυνση ενός int, η οποία είναι διαφορετική από τη διεύθυνση μιας μεταβλητής χαρακτήρα
επειδή ένας int καταλαμβάνει, σε 32-bit μηχανή, καταλαμβάνει 4 bytes του χώρου,
ενώ ένας χαρακτήρας παίρνει μόνο το 1 byte του χώρου.
Γι 'αυτό είναι σημαντικό να γνωρίζουμε τι είναι, επίσης, - ό, τι ζει, το είδος της αξίας
ζει στη διεύθυνση που έχεις περάσει μέσα
Ή η διεύθυνση ότι έχουμε να κάνουμε με.
Με αυτόν τον τρόπο, ξέρεις πόσα bytes πληροφοριών πραγματικά να φορτώσει από RAM σας.
Και τότε, ναι, αυτό το χειριστή dereference, σαν να ζητούσαν,
πηγαίνει και πρόσβαση στις πληροφορίες σε μια συγκεκριμένη διεύθυνση.
Έτσι, λέει, με αυτό εδώ μια μεταβλητή, τη θεραπεία των περιεχομένων του ως μια διεύθυνση,
μεταβεί στη συγκεκριμένη διεύθυνση, και τραβήξτε προς τα έξω, τοποθετήστε στον επεξεργαστή, το φορτίο σε ένα μητρώο
οι πραγματικές τιμές ή τα περιεχόμενα που ζουν σε αυτή τη διεύθυνση.
Κάθε άλλες ερωτήσεις; Αυτές είναι καλές ερωτήσεις.
Είναι πολλά νέα ορολογία πάρα πολύ.
Είναι επίσης το είδος του funky, βλέποντας & * και σε διαφορετικά μέρη.
>> Εντάξει.
Έτσι, πίσω στο πρόβλημα 33, file I / O.
Αυτό ήταν ένα από εκείνα τα προβλήματα που πιστεύω ότι μερικά πράγματα συνέβησαν.
Ένας, είναι ένα αρκετά νέο θέμα.
Παρουσιάστηκε πολύ σύντομα πριν από τη κουίζ,
και τότε νομίζω ότι ήταν κάτι σαν ένα από αυτά τα προβλήματα λέξη μαθηματικά σε
όπου θα σας δώσει πολλές πληροφορίες, αλλά στην πραγματικότητα δεν καταλήγουν να χρειάζεται να χρησιμοποιούν έναν τόνο του.
Το πρώτο μέρος αυτού του προβλήματος που περιγράφει τι είναι αρχείο CSV.
Τώρα, ένα αρχείο CSV, σύμφωνα με την περιγραφή, είναι διαχωρισμένες με κόμμα αρχείο αξίες.
Ο λόγος που αυτές είναι καθόλου ενδιαφέρουσα, και ο λόγος που τα χρησιμοποιούν ποτέ,
είναι, γιατί, πόσοι από σας έχουν χρησιμοποιήσει ποτέ τα πράγματα όπως το Excel;
Εικόνα οι περισσότεροι από εσάς έχουν, κατά πάσα πιθανότητα, ή θα χρησιμοποιήσει σε κάποιο σημείο στη ζωή σας.
Θα χρησιμοποιήσετε κάτι όπως το Excel.
Για να πάρετε τα δεδομένα από ένα υπολογιστικό φύλλο Excel ή να κάνετε οποιοδήποτε είδος της επεξεργασίας με αυτό,
αν θέλετε να γράψετε ένα πρόγραμμα C ή Python πρόγραμμα, Java πρόγραμμα,
να ασχοληθεί με τα δεδομένα που έχετε αποθηκεύσει εκεί,
ένας από τους πιο κοινούς τρόπους για να βγούμε είναι σε ένα αρχείο CSV.
Και μπορείτε να ανοίξετε το Excel και όταν θα πάτε στο "Save As" διαλόγου,
μπορείτε να πάρετε από ένα πραγματικό αρχείο CSV.
>> Handy για να μάθετε πώς να ασχοληθεί με αυτά τα πράγματα.
Ο τρόπος που λειτουργεί είναι ότι είναι παρόμοια με - Θέλω να πω, αυτό είναι ουσιαστικά μιμείται ένα υπολογιστικό φύλλο,
όπου, όπως βλέπουμε εδώ, σε πολύ πιο αριστερά-κομμάτι,
έχουμε όλα τα τελευταία ονόματα.
Έτσι έχουμε Malan, τότε Hardison, και στη συνέχεια Bowden, MacWilliam, και στη συνέχεια Chan.
Όλα τα τελευταία ονόματα. Και τότε ένα κόμμα διαχωρίζει τα τελευταία ονόματα από τα πρώτα ονόματα.
David, Nate, Rob, Tommy, και Zamyla.
Πάντα ανακατεύουμε μέχρι Robby και Τομ.
Και τότε, τελικά, η τρίτη στήλη είναι οι διευθύνσεις ηλεκτρονικού ταχυδρομείου.
Μόλις καταλάβετε ότι, το υπόλοιπο του προγράμματος είναι αρκετά απλή στην εφαρμογή της.
Αυτό που κάναμε, προκειμένου να μιμηθεί την ίδια δομή στο Γ πρόγραμμα μας
το έχουμε χρησιμοποιήσει μια δομή.
Θα αρχίσετε να παίζετε με αυτά λίγο περισσότερο, καθώς και.
Τους είδαμε για πρώτη λίγο πρόβλημα στο σύνολο 3, όταν είχαμε να κάνουμε με τα λεξικά.
Αλλά αυτό το struct προσωπικό αποθηκεύει ένα επώνυμο, το όνομα, και ένα email.
Ακριβώς όπως CSV αρχείο μας αποθήκευση.
Έτσι, αυτό είναι απλά τη μετατροπή από τη μία μορφή στην άλλη.
Πρέπει να μετατρέψετε, σε αυτή την περίπτωση, ένα struct προσωπικό σε μια γραμμή,
μια διαχωρισμένη με κόμματα γραμμή, έτσι απλά.
Μήπως αυτό έχει νόημα; Εσείς έχετε πάρει όλα τα κουίζ,
έτσι φαντάζομαι έχετε τουλάχιστον είχε λίγο χρόνο για να σκεφτεί για αυτό.
>> Σε λειτουργία μίσθωση, το πρόβλημα μας ζητά να λάβει - we'll ζουμ σε αυτό το λίγο -
να λάβει σε μια δομή του προσωπικού, ένα struct προσωπικό, με το όνομα s,
επισυνάπτει και το περιεχόμενό της να staff.csv αρχείο μας.
Αποδεικνύεται ότι αυτό είναι αρκετά απλό στη χρήση.
Θα είδος του παίζουν με αυτές τις λειτουργίες λίγο περισσότερο σήμερα.
Αλλά στην περίπτωση αυτή, η συνάρτηση fprintf είναι πραγματικά το κλειδί.
Έτσι, με fprintf, μπορούμε να εκτυπώσετε, όπως ακριβώς εσείς έχουν χρησιμοποιήσει printf όλο αυτό το διάστημα.
Μπορείτε να printf μια γραμμή σε ένα αρχείο.
Έτσι, αντί να κάνουμε απλώς τη συνήθη κλήση printf όπου δίνετε τη συμβολοσειρά μορφοποίησης
και τότε θα αντικαταστήσει όλες τις μεταβλητές με τα ακόλουθα επιχειρήματα,
με fprintf, το πρώτο επιχείρημά σας είναι αντ 'αυτού το αρχείο που θέλετε να γράψετε.
Αν θέλαμε να δούμε αυτό στη συσκευή, για παράδειγμα, ο άνθρωπος fprintf,
μπορούμε να δούμε τη διαφορά μεταξύ printf και fprintf.
Θα μεγέθυνση εδώ λίγο.
Έτσι, με την printf, δίνουμε μια συμβολοσειρά μορφής, και στη συνέχεια τα επόμενα επιχειρήματα
είναι όλες οι μεταβλητές για την αντικατάσταση ή υποκατάσταση σε συμβολοσειρά μορφής μας.
Ότι, με fprintf, το πρώτο επιχείρημα είναι πράγματι αυτό το αρχείο * ονομάζεται ρεύμα.
>> Μετακίνηση πίσω εδώ για ενοικίαση μας,
έχουμε ήδη πήρε το αρχείο μας ρεύμα * άνοιξε για μας.
Αυτό είναι ό, τι αυτή η πρώτη γραμμή κάνει? Ανοίγει το αρχείο staff.csv,
αυτό ανοίγει σε λειτουργία προσάρτησης, και το μόνο που μένει να κάνουμε είναι
γράψετε τη δομή του προσωπικού του αρχείου.
Και, ας δούμε, μπορώ να θέλετε να χρησιμοποιήσετε το iPad;
Θα χρησιμοποιήσω το iPad. Έχουμε κενό - ας βάλουμε αυτό στο τραπέζι ώστε να μπορώ να γράψω λίγο καλύτερα -
ακυρώσουν την ενοικίαση και παίρνει σε ένα επιχείρημα, μια δομή που ονομάζεται s προσωπικό.
Πήρε τιράντες μας, έχουμε * αρχείο που ονομάζεται αρχείο μας,
έχουμε γραμμή fopen μας που μας δόθηκαν,
και θα γράψω ακριβώς όπως τελείες, δεδομένου ότι είναι ήδη στην ΠΑΙΔΙΑ.
Και στη συνέχεια, στην επόμενη γραμμή μας, θα πάμε για να πραγματοποιήσετε μια κλήση με fprintf
και θα πάμε να περάσει στο αρχείο που θέλετε να εκτυπώσετε σε,
και στη συνέχεια συμβολοσειρά μορφής μας, η οποία -
Θα σας αφήσω να μου πείτε ρε παιδιά τι μοιάζει.
Εσύ τι λες, Στέλλα; Ξέρετε ποιο είναι το πρώτο μέρος του string format μοιάζει;
[Στέλλα] Δεν είμαι σίγουρος. >> Διστάσετε να ρωτήσετε τον Jimmy.
Ξέρετε, ο Jimmy;
[Jimmy] Θα ήταν απλώς να είναι η τελευταία; Δεν ξέρω. Δεν είμαι απόλυτα σίγουρος.
Εντάξει >>. Τι θα λέγατε, έκανε κανέναν να πάρει αυτό το σωστό για τις εξετάσεις;
Όχι Εντάξει.
Αποδεικνύεται ότι εδώ το μόνο που έχουμε να κάνουμε είναι να θέλουμε κάθε μέρος της δομής του προσωπικού μας
να εκτυπωθεί ως συμβολοσειρά στο αρχείο μας.
Εμείς απλά χρησιμοποιήστε το χαρακτήρα υποκατάστασης σειρά τρεις διαφορετικές φορές, γιατί έχουμε ένα επώνυμο
ακολουθείται από κόμμα, τότε το πρώτο όνομα που ακολουθείται από ένα κόμμα,
και στη συνέχεια, τελικά η διεύθυνση ηλεκτρονικού ταχυδρομείου που ακολουθείται - η οποία δεν είναι
τοποθέτηση στην οθόνη μου - αλλά αυτό είναι που ακολουθείται από ένα χαρακτήρα νέας γραμμής.
Έτσι, Πάω να το γράψετε ακριβώς κάτω από εκεί.
Και μετά από τότε συμβολοσειρά μορφής μας,
έχουμε μόνο τις αντικαταστάσεις, το οποίο έχουμε πρόσβαση χρησιμοποιώντας το συμβολισμό dot
που είδαμε στο σύνολο προβλήματος 3.
Μπορούμε να χρησιμοποιήσουμε s.last, s.first, και s.email
να υποκαταστήσει σε αυτές τις τρεις τιμές σε μορφή συμβολοσειράς μας.
Λοιπόν, πώς πήγε; Κάντε νόημα;
Ναι; Όχι; Ενδεχομένως; Εντάξει.
>> Το τελευταίο πράγμα που κάνουμε μετά έχουμε τυπωμένο και μετά ανοίξαμε το αρχείο μας:
κάθε φορά που έχουμε ανοίξει ένα αρχείο, πρέπει πάντα να θυμόμαστε για να το κλείσετε.
Γιατί αλλιώς θα καταλήξετε διαρροή της μνήμης,
χρησιμοποιώντας μέχρι και περιγραφείς αρχείων.
Έτσι, για να το κλείσετε, που λειτουργούν χρησιμοποιούμε; Daniel;
[Daniel] Αδυναμία εγγραφής αρχείου; >> Fclose, ακριβώς.
Έτσι, το τελευταίο μέρος του προβλήματος αυτού ήταν να έχετε κλείσει σωστά το αρχείο, χρησιμοποιώντας τη λειτουργία fclose,
το οποίο μοιάζει με αυτό.
Δεν είναι πολύ τρελό.
Cool.
Έτσι, αυτό είναι πρόβλημα 33 στο κουίζ.
Θα έχουμε σίγουρα πιο αρχείο I / O ανεβαίνει.
Θα κάνουμε λίγο περισσότερο σε διάλεξη σήμερα, ή στο τμήμα σήμερα,
γιατί αυτό είναι που πρόκειται να αποτελέσουν το μεγαλύτερο μέρος του αυτό το επερχόμενο PSET.
Ας περάσουμε από το κουίζ σε αυτό το σημείο. Ναι;
>> [Charlotte]] Γιατί Αδυναμία εγγραφής αρχείου (αρχείο) αντί του fclose (staff.csv);
>> Ah. Επειδή αποδεικνύεται ότι - έτσι το ερώτημα, το οποίο είναι ένα μεγάλο,
Γι 'αυτό, όταν γράφουμε fclose, είμαστε εγγράφως Αδυναμία εγγραφής αρχείου (αρχείο) μεταβλητό αστέρι
σε αντίθεση με το όνομα του αρχείου, staff.csv; Είναι αυτό σωστό; Ναι.
Έτσι, ας ρίξουμε μια ματιά. Αν επιστρέψετε στο laptop μου,
και ας δούμε την λειτουργία Αδυναμία εγγραφής αρχείου.
Έτσι, η λειτουργία fclose κλείνει ένα ρεύμα και παίρνει το δείκτη στο ρεύμα που θέλουμε να κλείσει,
σε αντίθεση με το πραγματικό όνομα του αρχείου που θέλουμε να κλείσουμε.
Και αυτό οφείλεται στο γεγονός ότι πίσω από τις σκηνές, όταν πραγματοποιείτε μια κλήση με fopen,
όταν ανοίγετε ένα αρχείο, είστε πραγματικά κατανομή μνήμης για την αποθήκευση πληροφοριών σχετικά με το αρχείο.
Έτσι έχετε δείκτης αρχείο που περιέχει πληροφορίες σχετικά με το αρχείο,
όπως είναι ανοικτό, το μέγεθός του, όπου κι αν βρίσκεστε σήμερα στο αρχείο,
έτσι ώστε να μπορείτε να κάνετε ανάγνωση και τη γραφή κλήσεις για τη συγκεκριμένη θέση μέσα στο αρχείο.
Θα καταλήξετε το κλείσιμο του δείκτη αντί να κλείνουν το όνομα του αρχείου.
>> Ναι; [Δανιήλ] Έτσι, προκειμένου να χρησιμοποιήσει ενοικίασης, θα σας πω - πώς να πάρει την είσοδο του χρήστη;
Μήπως fprintf ενεργούν σαν GetString, υπό την έννοια ότι θα πρέπει ακριβώς να περιμένει για την είσοδο χρήστη
και να σας ζητήσει να πληκτρολογήσετε αυτό - ή να περιμένετε για να πληκτρολογήσετε αυτά τα τρία πράγματα;
Ή μήπως θα πρέπει να χρησιμοποιήσετε κάτι για την εφαρμογή ενοικίαση;
Ναι >>. Έτσι δεν είμαστε - το ερώτημα, πώς μπορούμε να πάρει την είσοδο του χρήστη
για την εφαρμογή της ενοικίασης; Και αυτό που έχουμε εδώ είναι ο καλών της μίσθωσης,
πέρασε στην παρούσα struct προσωπικού με το σύνολο των δεδομένων που αποθηκεύονται στο struct ήδη.
Έτσι fprintf είναι σε θέση να γράψει απλά ότι τα δεδομένα απευθείας στο αρχείο.
Δεν υπάρχει καμία αναμονή για την είσοδο του χρήστη.
Ο χρήστης είναι ήδη από την είσοδο σωστά το θέτει σε αυτό το struct του προσωπικού.
Και τα πράγματα, βέβαια, θα σπάσει αν οποιαδήποτε από αυτές τις υποδείξεις ήταν μηδενική,
έτσι ώστε να μετακινηθείτε προς τα πίσω μέχρι εδώ και κοιτάμε struct μας.
Έχουμε τελευταία σειρά, σειρά πρώτη, e-mail string.
Γνωρίζουμε τώρα ότι όλα αυτά τα πραγματικά, κάτω από την κουκούλα, είναι char μεταβλητές *.
Αυτό μπορεί ή δεν μπορεί να δείχνει σε null.
Μπορούν να δείχνει προς τη μνήμη στο σωρό,
ίσως μνήμης στην στοίβα.
Εμείς πραγματικά δεν ξέρω, αλλά αν οποιαδήποτε από αυτούς τους δείκτες είναι άκυρη, ανίσχυρη ή,
ότι αυτό θα καταρρεύσει σίγουρα λειτουργία ενοικίαση μας.
Αυτό ήταν κάτι που ήταν το είδος της πέρα ​​από το πεδίο της εξέτασης.
Εμείς δεν ανησυχούμε για αυτό.
Μεγάλη. Εντάξει. Έτσι κινείται από το κουίζ.
>> Ας κλείσει αυτός ο τύπος, και θα πάμε να δούμε PSET 4.
Έτσι, αν εσείς δείτε το spec PSET, όταν μπορείτε να έχετε πρόσβαση, cs50.net/quizzes,
πρόκειται να περάσουν από μερικά από τα προβλήματα που σήμερα τμήμα.
Είμαι κύλιση προς τα κάτω - το τμήμα των ερωτήσεων ξεκινά την τρίτη σελίδα του spec PSET.
Και το πρώτο μέρος σας ζητά να πάτε και να δείτε το σύντομο για τον αναπροσανατολισμό και σωλήνες.
Ποιο ήταν το είδος του ένα δροσερό λίγα λόγια, σας παρουσιάζει κάποια νέα, δροσερά κόλπα γραμμής εντολών που μπορείτε να χρησιμοποιήσετε.
Και μετά έχουμε μερικές ερωτήσεις για σας επίσης.
Η πρώτη ερώτηση σχετικά με ρεύματα, με την οποία printf γράφει από προεπιλογή,
έχουμε το είδος της άγγιξε μόλις λίγο πριν από λίγο.
Αυτή η fprintf ότι συζητούσαμε παίρνει σε ένα ρεύμα * αρχείο ως επιχείρημα.
Αδυναμία εγγραφής αρχείου παίρνει σε ένα ρεύμα * αρχείο, καθώς,
και η τιμή επιστροφής της fopen σας δίνει ένα ρεύμα * αρχείο, καθώς και.
Ο λόγος που δεν έχουμε δει αυτά πριν, όταν έχουμε αντιμετωπίζονται με printf
είναι επειδή έχει ένα ρεύμα printf προεπιλογή.
Και το ρεύμα προεπιλογή στην οποία γράφει
θα μάθετε για το μικρό.
Έτσι οπωσδήποτε να ρίξετε μια ματιά σε αυτό.
>> Στο τμήμα του σήμερα, θα πάμε να μιλήσουμε λίγο για την GDB,
αφού η πιο εξοικειωμένοι είστε με αυτό, η πιο πρακτική μπορείτε να πάρετε με αυτό,
η καλύτερη θέση θα είστε πραγματικά να κυνηγήσουν κάτω από σφάλματα στο δικό σας κώδικα.
Αυτό επιταχύνει τη διαδικασία του debugging μέχρι δραματικά.
Έτσι, με τη χρήση printf, κάθε φορά που το κάνουμε αυτό θα πρέπει να μεταγλωττίσετε τον κωδικό σας,
θα πρέπει να το τρέξει και πάλι, μερικές φορές θα πρέπει να μετακινήσετε το printf κλήση γύρω,
σε σχόλιο κώδικα, χρειάζεται μόνο μια στιγμή.
Στόχος μας είναι να προσπαθήσουμε και να σας πείσει ότι με το GDB, μπορείτε ουσιαστικά
printf οτιδήποτε σε οποιοδήποτε σημείο του κώδικα σας και ποτέ δεν πρέπει να το μεταγλωττίσετε.
Ποτέ δεν πρέπει να ξεκινήσει και να μαντέψουν πού να printf επόμενο.
Το πρώτο πράγμα που πρέπει να κάνετε είναι να αντιγράψετε αυτή τη γραμμή και να πάρετε τον κώδικα από το τμήμα του ιστού.
Είμαι αντιγραφή αυτή τη γραμμή του κώδικα που λέει, "wget ​​http://cdn.cs50.net".
Πάω να το αντιγράψετε.
Πάω να πάει πέρα ​​να μου συσκευή, σμίκρυνση ώστε να μπορείτε να δείτε τι κάνω,
επικόλληση εκεί μέσα, και όταν χτύπησα το Enter, η εντολή wget είναι κυριολεκτικά ένα web πάρει.
Είναι πρόκειται να γκρεμίσει αυτό το αρχείο από το Διαδίκτυο,
και πρόκειται να το αποθηκεύσετε στον τρέχοντα κατάλογο.
Τώρα, αν μου λίστα μου τρέχοντα κατάλογο μπορείτε να δείτε ότι έχω αυτό το δικαίωμα section5.zip αρχείο εκεί.
Ο τρόπος για να ασχοληθεί με το εν λόγω τύπος είναι να το αποσυμπιέσετε,
που μπορείτε να κάνετε στη γραμμή εντολών, ακριβώς όπως αυτό.
Section5.zip.
Αυτό θα το αποσυμπιέσετε, να δημιουργήσετε το φάκελο για μένα,
διογκώνουν όλα τα περιεχόμενα, τους βάλει εκεί.
Έτσι τώρα μπορώ να πάω στο τμήμα 5 κατάλογο μου χρησιμοποιώντας την εντολή cd.
Καταργήστε την οθόνη με σαφείς. Έτσι καθαρίσετε την οθόνη.
Τώρα έχω ένα ωραίο καθαρό τερματικό για να ασχοληθούν μαζί τους.
>> Τώρα, αν μου λίστα με όλα τα αρχεία που βλέπω σε αυτόν τον κατάλογο,
θα δείτε ότι έχω τέσσερα αρχεία: buggy1, buggy2, buggy3, και buggy4.
Έχω, επίσης, αντίστοιχα. Αρχεία τους γ.
Εμείς δεν πάμε να δούμε τα αρχεία. Γ. για τώρα.
Αντ 'αυτού, θα πάμε να τα χρησιμοποιήσουν όταν θα ανοίξει GDB.
Έχουμε τους κράτησε γύρω έτσι ώστε να έχουμε πρόσβαση στον πηγαίο κώδικα όταν είμαστε με GDB,
αλλά ο στόχος του μέρους αυτού του τμήματος είναι να κολλήσουμε γύρω με GDB
και να δούμε πώς μπορούμε να το χρησιμοποιήσουμε για να καταλάβουμε τι πηγαίνει στραβά με κάθε ένα από αυτά τα τέσσερα προγράμματα λάθη.
Έτσι, είμαστε ακριβώς πρόκειται να γύρω από το δωμάτιο πολύ γρήγορα,
και θα πάω να ρωτήσω κάποιον να τρέξει ένα από τα λάθη των προγραμμάτων,
και στη συνέχεια θα πάμε ως ομάδα μέσα από GDB, και θα δούμε τι μπορούμε να κάνουμε για να διορθώσετε αυτά τα προγράμματα,
ή τουλάχιστον να προσδιορίσει τι συμβαίνει λάθος σε κάθε μία από αυτές.
Ας ξεκινήσουμε εδώ με τον Daniel. Θα τρέχετε buggy1; Ας δούμε τι θα συμβεί.
[Daniel] Είναι λέει ότι υπάρχει ένα σφάλμα εφαρμογής. Ναι >>. Ακριβώς.
Έτσι, αν τρέξω buggy1, να πάρω ένα σφάλμα SEG.
Σε αυτό το σημείο, θα μπορούσα να πάω και να ανοίξουν buggy1.c,
προσπαθήσουμε και να καταλάβουμε τι πηγαίνει στραβά,
αλλά ένα από τα πιο απεχθή πράγματα σχετικά με αυτό το σφάλμα σφάλμα seg
είναι ότι δεν σας πω για το τι γραμμή από τα πράγματα που πραγματικά το πρόγραμμα πήγε στραβά και έσπασε.
Μπορείτε είδους πρέπει να εξετάσουμε τον κώδικα
και να καταλάβω τη χρήση εικασία και ελέγξτε ή printf για να δείτε τι συμβαίνει λάθος.
Ένα από τα πιο cool πράγματα για GDB είναι ότι είναι πραγματικά, πραγματικά εύκολο
να καταλάβουμε τη γραμμή στην οποία κολλάει το πρόγραμμά σας.
Είναι εντελώς αξίζει τον κόπο να το χρησιμοποιήσει, ακόμη και αν μόνο για αυτό.
Έτσι, για την εκκίνηση GDB, τύπου Ι GDB, και στη συνέχεια δίνω τη διαδρομή προς το εκτελέσιμο αρχείο που θέλετε να εκτελέσετε.
Εδώ γράφω gdb ./buggy1.
Πατήστε Enter. Μου δίνει όλες αυτές τις πληροφορίες πνευματικών δικαιωμάτων,
και εδώ κάτω θα δείτε αυτή τη γραμμή που λέει, "Διαβάζοντας τα σύμβολα από / home /
jharvard/section5/buggy1. "
Και αν όλα πάνε καλά, θα δείτε να εκτυπώσετε ένα μήνυμα που μοιάζει με αυτό.
Θα διαβάσετε τα σύμβολα, αυτό θα πει «Είμαι ανάγνωση συμβόλων από το εκτελέσιμο αρχείο σας,"
και στη συνέχεια θα έχει αυτό το "κάνει" μήνυμα εδώ.
Αν δείτε κάποια άλλη παραλλαγή αυτού, ή βλέπετε ότι δεν μπορούσε να βρει τα σύμβολα
ή κάτι τέτοιο, τι σημαίνει αυτό είναι ότι απλά δεν έχουν συνταχθεί εκτελέσιμο σας σωστά.
Όταν καταρτίζουν προγράμματα για χρήση με το GDB, θα πρέπει να χρησιμοποιεί το εν λόγω ειδικό-g σημαία,
και ότι έχει κάνει από προεπιλογή αν μεταγλωττίσετε τα προγράμματα σας, απλά πληκτρολογώντας make
ή να κάνει λάθη ή να ανακτήσει, κάποια από αυτά.
Αλλά αν είστε με το χέρι με την κατάρτιση Clang, τότε θα πρέπει να πάμε μέσα και ότι περιλαμβάνουν-g σημαία.
>> Σε αυτό το σημείο, τώρα που έχουμε GDB προτροπή μας,
Είναι αρκετά απλό να τρέξει το πρόγραμμα.
Μπορούμε να πληκτρολογήσετε run, ή μπορούμε να πληκτρολογήσετε μόνο r.
Οι περισσότερες εντολές GDB μπορεί να συντμηθεί.
Συνήθως σε μόλις ένα ή δύο γράμματα, το οποίο είναι πολύ ωραίο.
Έτσι Saad, αν πληκτρολογήσετε r και πατήστε Enter, τι συμβαίνει;
[Saad] Πήρα SIGSEGV, σφάλμα κατάτμησης, και στη συνέχεια, όλη αυτή αλαμπουρνέζικα.
Ναι >>.
Όπως βλέπουμε στην οθόνη αυτή τη στιγμή, και όπως είπε ο Saad,
όταν γράφουμε τρέξιμο ή r και πατήστε Enter, έχουμε ακόμα το ίδιο σφάλμα SEG.
Έτσι, χρησιμοποιώντας GDB δεν λύσει το πρόβλημά μας.
Αλλά αυτό μας δίνει κάποια αλαμπουρνέζικα, και αποδεικνύεται ότι αυτή η αλαμπουρνέζικα
στην πραγματικότητα μας λέει όπου αυτό συμβαίνει.
Για να αναλύσει αυτό το λίγο, αυτό το πρώτο κομμάτι είναι η λειτουργία κατά την οποία ό, τι συμβαίνει λάθος.
Υπάρχει αυτή η __ strcmp_sse4_2, και μας λέει ότι αυτό συμβαίνει σε αυτό το αρχείο
που ονομάζεται sysdeps/i386, όλα αυτά, και πάλι, το είδος της ένα χάος - αλλά γραμμή 254.
Αυτό είναι το είδος του σκληρά για να αναλύσει. Συνήθως όταν βλέπεις τα πράγματα όπως αυτό,
αυτό σημαίνει ότι είναι προβληματική σε διαχωρίζονται από μία από τις βιβλιοθήκες του συστήματος.
Έτσι, κάτι που κάνει με strcmp. Εσείς έχετε δει πριν strcmp.
Όχι πάρα πολύ τρελό, αλλά αυτό σημαίνει ότι strcmp έχει σπάσει ή ότι υπάρχει ένα πρόβλημα με strcmp;
Τι νομίζετε, Αλέξανδρος;
[Αλέξανδρος] είναι ότι - είναι 254 η γραμμή; Και το - δεν το δυαδικό, αλλά δεν είναι οροφές τους,
και στη συνέχεια, υπάρχει μια άλλη γλώσσα για κάθε λειτουργία. Είναι ότι 254 σε αυτή τη λειτουργία, ή -;
Είναι >> γραμμή 254. Μοιάζει σε αυτό το αρχείο. S, έτσι ώστε να είναι κατά πάσα πιθανότητα κώδικα assembly.
>> Αλλά, υποθέτω ότι το πιο πιεστικό θέμα είναι, επειδή έχουμε πάρει ένα σφάλμα seg,
και αυτό μοιάζει να έρχεται από την strcmp λειτουργία,
σημαίνει αυτό, στη συνέχεια, ότι strcmp έχει σπάσει;
Δεν θα πρέπει, ελπίζω. Έτσι, μόνο και μόνο επειδή έχετε ένα σφάλμα καταμερισμού
σε μία από τις λειτουργίες του συστήματος, συνήθως αυτό σημαίνει ότι απλά δεν έχουν ονομάζεται σωστά.
Ο πιο γρήγορος πράγμα που πρέπει να κάνετε για να καταλάβουμε τι πραγματικά συμβαίνει
όταν βλέπεις κάτι σαν τρελό αυτό, κάθε φορά που θα δείτε ένα σφάλμα seg,
ειδικά αν έχετε ένα πρόγραμμα που χρησιμοποιεί είναι περισσότερο από ό, τι ακριβώς κύρια,
είναι να χρησιμοποιήσετε ένα backtrace.
I συντομεύσει backtrace γράφοντας bt, σε αντίθεση με την πλήρη λέξη backtrace.
Αλλά Charlotte, τι συμβαίνει όταν πληκτρολογείτε bt και πατήστε Enter;
[Charlotte] Δείχνει με δύο γραμμές, 0 γραμμής και της γραμμής 1.
Ναι >>. Έτσι η γραμμή 0 και της γραμμής 1.
Αυτές είναι οι πραγματικές πλαίσια στοίβα που είχαν σήμερα στο παιχνίδι, όταν συνετρίβη το πρόγραμμά σας.
Ξεκινώντας από το κορυφαίο καρέ, καρέ 0, και πηγαίνοντας προς τα κάτω, οι περισσότεροι, το οποίο είναι το πλαίσιο 1.
Κορυφαίο καρέ μας είναι η strcmp πλαίσιο.
Μπορείτε να σκεφτείτε αυτό ως παρόμοιο με εκείνο το πρόβλημα που μόλις είχαν κάνει στο κουίζ με τους δείκτες,
όπου είχαμε ανταλλάξει πλαίσιο στοίβα στην κορυφή του κύριου πλαισίου στοίβας,
και είχαμε τις μεταβλητές που χρησιμοποιούσε ανταλλαγής πάνω από τις μεταβλητές που κυρίως χρησιμοποιούσε.
Εδώ δυστύχημα συνέβη σε μας strcmp λειτουργία μας, η οποία κλήθηκε από την κύρια λειτουργία μας,
backtrace και μας δίνει όχι μόνο τις λειτουργίες στις οποίες απέτυχε πράγματα,
αλλά είναι, επίσης, μας λέει, όπου τα πάντα κλήθηκε από.
Έτσι, αν μετακινηθείτε πάνω λίγο περισσότερο προς τα δεξιά,
μπορούμε να δούμε ότι ναι, ήμασταν στην γραμμή 254 του παρόντος strcmp-sse4.s αρχείο.
Αλλά η κλήση έγινε σε buggy1.c, γραμμή 6.
Έτσι, αυτό σημαίνει ότι μπορούμε να κάνουμε - είναι ότι μπορεί απλά να ελέγξετε έξω και να δούμε τι συνέβαινε
σε buggy1.c, γραμμή 6.
Και πάλι, υπάρχουν δύο τρόποι για να γίνει αυτό. Η μία είναι να βγείτε έξω από GDB
ή έχουν κωδικό σας ανοίξει σε άλλο παράθυρο και αναφορά σταυρό.
Αυτό, από μόνο του, είναι αρκετά βολικό, επειδή τώρα, αν είστε σε ώρες γραφείου
και έχετε ένα σφάλμα seg και TF σας αναρωτιέστε πού είναι ό, τι ήταν το σπάσιμο,
μπορείτε απλώς να πω, "Ω, γραμμή 6. Δεν ξέρω τι συμβαίνει,
αλλά κάτι σχετικά με γραμμή 6 προκαλεί το πρόγραμμά μου να σπάσει. "
Ο άλλος τρόπος για να το κάνει είναι ότι μπορείτε να χρησιμοποιήσετε την εντολή αυτή ονομάζεται λίστα στην GDB.
Μπορείτε να συντομεύσει επίσης με l.
Έτσι, αν χτυπήσει l, τι έχουμε εδώ;
Παίρνουμε ένα σωρό περίεργα πράγματα.
Αυτός είναι ο πραγματικός κώδικας συναρμολόγησης
δηλαδή στην strcmp_sse4_2.
Αυτό φαίνεται από το είδος funky,
και ο λόγος που παίρνουμε αυτό οφείλεται στο γεγονός ότι αυτή τη στιγμή,
GDB μας έχει στο πλαίσιο 0.
>> Έτσι, ανά πάσα στιγμή εξετάζουμε τις μεταβλητές, κάθε φορά που θα δούμε τον πηγαίο κώδικα,
ψάχνουμε σε πηγαίο κώδικα που αφορά το πλαίσιο στοίβας είμαστε σήμερα μέσα
Έτσι, προκειμένου να πάρει τίποτα ουσιαστικό, θα πρέπει να
κινούνται σε ένα πλαίσιο στοίβα που έχει περισσότερο νόημα.
Σε αυτή την περίπτωση, το κύριο πλαίσιο στοίβας θα κάνει λίγο περισσότερο νόημα,
γιατί αυτό ήταν στην πραγματικότητα ο κώδικας που γράψαμε.
Δεν είναι η strcmp κώδικα.
Ο τρόπος που μπορείτε να μετακινηθείτε μεταξύ των πλαισίων, σε αυτή την περίπτωση, επειδή έχουμε δύο,
έχουμε 0 και 1,
να το κάνετε αυτό με το πάνω και κάτω εντολές.
Αν ανεβάσουμε ένα καρέ,
τώρα είμαι στο κεντρικό πλαίσιο στοίβας.
Μπορώ να μετακινηθείτε προς τα κάτω για να πάει πίσω όπου ήμουν,
ανεβαίνουν και πάλι, κατεβαίνουν και πάλι, και να ανεβαίνουν και πάλι.
Αν το κάνετε ποτέ το πρόγραμμά σας σε GDB, μπορείτε να πάρετε μια συντριβή, μπορείτε να πάρετε το backtrace,
και θα δείτε ότι είναι σε κάποιο αρχείο που δεν ξέρεις τι συμβαίνει.
Θα προσπαθήσουμε λίστα, ο κωδικός δεν φαίνεται γνωστό σε σας,
ρίξτε μια ματιά στο καρέ σας και να καταλάβω όπου και αν βρίσκεστε.
Είστε πιθανώς σε λάθος πλαίσιο στοίβας.
Ή τουλάχιστον να είστε σε ένα πλαίσιο στοίβας που δεν είναι αυτό που μπορείτε πραγματικά να διορθώσετε.
Τώρα που είμαστε στο κατάλληλο πλαίσιο στοίβας, είμαστε σε γενικές γραμμές,
Τώρα μπορούμε να χρησιμοποιήσουμε την εντολή λίστας για να καταλάβω τι ήταν η γραμμή.
Και μπορείτε να το δείτε? Αυτό το έντυπο για εμάς εδώ.
Αλλά μπορούμε να χτυπήσει λίστα όλοι το ίδιο, και η λίστα μας δίνει αυτό το ωραίο εκτύπωση
του πραγματικού κώδικα που συμβαίνει εδώ.
>> Πιο συγκεκριμένα, μπορούμε να εξετάσουμε στη γραμμή 6.
Μπορούμε να δούμε τι συμβαίνει εδώ.
Και φαίνεται σαν να κάνετε μια σύγκριση συμβολοσειράς
μεταξύ των χορδών "CS50 βράχους» και argv [1].
Κάτι σχετικά με αυτό συντρίβεται.
Έτσι, δεσποινίς, έχετε οποιεσδήποτε σκέψεις για το τι μπορεί να συμβαίνει εδώ;
[Missy] Δεν ξέρω γιατί αυτό είναι συντρίβεται. >> Δεν ξέρω γιατί αυτό είναι συντρίβεται;
Jimmy, οποιεσδήποτε σκέψεις;
[Jimmy] Δεν είμαι απόλυτα σίγουρος, αλλά η τελευταία φορά που χρησιμοποιήθηκε σύγκρισης συμβολοσειράς,
ή strcmp, όπως είχαμε τρεις διαφορετικές περιπτώσεις, κάτω από αυτό.
Δεν είχαμε μια ==, δεν νομίζω, το δικαίωμα στην εν λόγω πρώτη γραμμή.
Αντ 'αυτού, διαχωρίστηκε σε τρία, και ένας ήταν == 0,
ο ένας ήταν <0, νομίζω, και ο ένας ήταν> 0.
Έτσι, ίσως κάτι τέτοιο; Ναι >>. Έτσι, υπάρχει το θέμα αυτό
του κάνουμε τη σύγκριση σωστά;
Στέλλα; Οποιεσδήποτε σκέψεις;
[Στέλλα] Δεν είμαι σίγουρος. >> Δεν είστε σίγουροι. Daniel; Σκέψεις; Εντάξει.
Βγάζει ό, τι συμβαίνει εδώ είναι όταν τρέξαμε το πρόγραμμα
και πήραμε το seg σφάλμα, όταν έτρεξε το πρόγραμμα για πρώτη φορά, Δανιήλ,
δεν θα δώσει κανένα επιχείρημα γραμμή εντολών;
[Daniel] Όχι Όχι >> Σε αυτή την περίπτωση, ποια είναι η αξία του argv [1];
>> Δεν υπάρχει καμία αξία. Δικαίωμα >>.
Λοιπόν, δεν υπάρχει κατάλληλη τιμή συμβολοσειράς.
Αλλά υπάρχει κάποια αξία. Ποια είναι η τιμή που παίρνει αποθηκεύονται εκεί μέσα;
>> Μια τιμή σκουπίδια; >> Είναι είτε μια τιμή σκουπιδιών ή, στην περίπτωση αυτή,
το τέλος του πίνακα argv είναι πάντα τερματίζεται με null.
Έτσι, αυτό που πραγματικά έχεις αποθηκευμένα εκεί είναι μηδενική.
Ο άλλος τρόπος να λυθεί αυτό, αντί να σκεφτόμαστε ότι μέσω,
είναι να δοκιμάστε να εκτυπώσετε το έξω.
Αυτό είναι όπου έλεγα ότι η χρήση GDB είναι μεγάλη,
επειδή μπορείτε να εκτυπώσετε όλες τις μεταβλητές, όλες οι τιμές που θέλετε
χρησιμοποιώντας αυτό το πρακτικό-δανδής εντολή p.
Έτσι, αν πληκτρολογήσετε p και στη συνέχεια να πληκτρολογήσετε την τιμή μιας μεταβλητής ή το όνομα της μεταβλητής,
ας πούμε, argc, βλέπω ότι argc είναι 1.
Αν θέλετε να εκτυπώσετε argv [0], μπορώ να το κάνω έτσι ακριβώς όπως αυτό.
Και όπως είδαμε, argv [0] είναι πάντα το όνομα του προγράμματός σας,
πάντα το όνομα του εκτελέσιμου.
Εδώ μπορείτε να δείτε το έχεις το πλήρες όνομα διαδρομής.
Μπορώ επίσης να εκτυπώσετε argv [1] και να δούμε τι θα συμβεί.
>> Εδώ έχουμε αυτό το είδος της μυστικιστική αξία.
Πήραμε αυτό το 0x0.
Να θυμάστε στην αρχή του όρου, όταν μιλήσαμε για δεκαεξαδικούς αριθμούς;
Ή ότι η μικρή ερώτηση στο τέλος του PSET 0 για το πώς να αντιπροσωπεύουν το 50 στο δεκαεξαδικό;
Ο τρόπος που γράφουμε hex αριθμούς σε CS, ακριβώς για να μην συγχέουμε τον εαυτό μας
με δεκαδικούς αριθμούς, είναι ότι το πρόθεμα τα πάντα με 0x.
Έτσι, αυτό το πρόθεμα 0x πάντα ακριβώς σημαίνει ερμηνεύσει τον ακόλουθο αριθμό ως δεκαεξαδικός αριθμός,
όχι ως μια σειρά, όχι ως δεκαδικός αριθμός, όχι ως ένα δυαδικό αριθμό.
Δεδομένου ότι ο αριθμός 5-0 είναι ένα έγκυρο αριθμό σε δεκαεξαδική.
Και είναι ένας αριθμός στο δεκαδικό, 50.
Έτσι, αυτό είναι ακριβώς το πώς θα αποσαφηνίζουν.
Έτσι 0x0 σημαίνει δεκαεξαδικό 0, η οποία είναι επίσης δεκαδικό 0, δυαδικό 0.
Είναι ακριβώς η τιμή 0.
Αποδεικνύεται ότι αυτό είναι ό, τι είναι μηδενική, στην πραγματικότητα, στη μνήμη.
Null είναι μόνο 0.
Εδώ, το στοιχείο αποθηκεύεται στο argv [1] είναι μηδενική.
Έτσι, προσπαθούμε να συγκρίνουμε "CS50 βράχια" μας σειρά με μια κενή συμβολοσειρά.
Έτσι εύρεση τιμών null, προσπαθεί να αποκτήσει πρόσβαση σε πράγματα null,
αυτά είναι συνήθως πρόκειται να προκαλέσει κάποια βλάβη κατάτμησης ή άλλα κακά πράγματα να συμβούν.
Και αποδεικνύεται ότι strcmp δεν ελέγχει για να δείτε
αν δεν έχετε περάσει σε μια τιμή που είναι null.
Αντίθετα, πηγαίνει μόνο μπροστά, προσπαθεί να κάνει το πράγμα του,
και αν διαχωρίζονται από λάθη, διαχωρίζονται από λάθη, και αυτό είναι το πρόβλημά σας. Θα πρέπει να πάμε να το διορθώσουμε.
Πραγματικά γρήγορα, πώς θα μπορούσαμε να διορθώσετε αυτό το πρόβλημα; Charlotte;
[Charlotte] Μπορείτε να ελέγξετε αν χρησιμοποιείτε.
Έτσι, εάν argv [1] είναι μηδενική, == 0, τότε επιστρέφει 1, ή κάτι [ακατάληπτο].
Ναι >>. Έτσι, αυτός είναι ένας πολύ καλός τρόπος για να το κάνουμε, όπως μπορούμε να ελέγξουμε για να δούμε,
η αξία είμαστε έτοιμοι να περάσουν στην strcmp, argv [1], είναι το μηδέν;
Αν αυτό είναι μηδενική, τότε μπορούμε να πούμε εντάξει, ματαίωση.
>> Μια πιο κοινός τρόπος να γίνει αυτό είναι να χρησιμοποιήσετε το argc αξία.
Μπορείτε να δείτε εδώ κατά την έναρξη της κύριας,
που παρέλειψε την εν λόγω πρώτη δοκιμή που συνήθως κάνουμε όταν χρησιμοποιούν τα επιχειρήματα της γραμμής εντολών,
η οποία είναι να εξετάσει εάν ή όχι argc αξία μας είναι αυτό που περιμένουμε.
Σε αυτή την περίπτωση, εμείς περιμένουμε τουλάχιστον δύο επιχειρήματα,
το όνομα του προγράμματος συν μία άλλη.
Επειδή είμαστε έτοιμοι να χρησιμοποιήσετε το δεύτερο επιχείρημα εδώ.
Έτσι, έχοντας κάποια δοκιμή εκ των προτέρων, πριν από την κλήση μας strcmp
ότι οι δοκιμές ή όχι argv είναι τουλάχιστον 2, θα κάνει επίσης το ίδιο πράγμα.
Μπορούμε να δούμε αν αυτό λειτουργεί εκτελώντας το πρόγραμμα ξανά.
Μπορείτε να επανεκκινήσετε το πρόγραμμα σας πάντα μέσα GDB, η οποία είναι πολύ ωραία.
Μπορείτε να τρέξετε, και όταν περνούν τα επιχειρήματα για το πρόγραμμά σας,
μπορείτε να περάσετε σε κλήση, όταν τρέχει, όταν δεν μπότα επάνω GDB.
Με αυτόν τον τρόπο μπορείτε να κρατήσετε την επίκληση πρόγραμμα σας με διαφορετικά επιχειρήματα κάθε φορά.
Έτσι τρέχει, ή πάλι, μπορώ να Type R, και ας δούμε τι θα συμβεί αν πληκτρολογήσετε "γεια".
Θα σας ρωτήσω πάντα αν θέλετε να ξεκινήσετε από την αρχή ξανά.
Συνήθως, θέλετε να το ξεκινήσετε πάλι από την αρχή.
Και σε αυτό το σημείο, επανεκκίνηση ξανά, το εκτυπώνει
το πρόγραμμα που τρέχετε, buggy1, με το επιχείρημα γεια σου,
και τυπώνει αυτό το πρότυπο έξω? λέει, "Μπορείτε να πάρετε μια D,« λυπημένο πρόσωπο.
Αλλά δεν διαχωρίζονται από σφάλμα. Είπε ότι η διαδικασία βγήκε κανονικά.
Έτσι, αυτό φαίνεται αρκετά καλό.
Δεν υπάρχουν άλλα seg σφάλμα, κάναμε το παρελθόν,
έτσι ώστε να φαίνεται σαν αυτό ήταν πράγματι το seg bug σφάλμα που είχαμε πάρει.
Δυστυχώς, μας λέει ότι παίρνουμε μια Δ.
>> Μπορούμε να πάμε πίσω και να δούμε τον κώδικα και να δούμε τι συμβαίνει εκεί
να καταλάβω τι ήταν - γιατί μας έλεγε ότι έχουμε μια Δ.
Ας δούμε, εδώ ήταν αυτό printf λέγοντας ότι έχεις ένα D.
Αν πληκτρολογήσετε λίστα, όπως σας κρατήσει πληκτρολογώντας λίστα, κρατά επανάληψη κάτω από το πρόγραμμά σας,
γι 'αυτό θα σας δείξω τις πρώτες γραμμές του προγράμματός σας.
Στη συνέχεια θα σας δείξει τις επόμενες λίγες γραμμές, και το επόμενο κομμάτι και το επόμενο κομμάτι.
Και αυτό θα συνεχίσουμε να προσπαθούμε για να πάει κάτω.
Και τώρα θα φτάσουμε στο «γραμμή αριθμός 16 είναι εκτός εμβέλειας."
Επειδή έχει μόνο 15 γραμμές.
Αν φτάσετε σε αυτό το σημείο και σας αναρωτιέστε, "Τι μπορώ να κάνω;" μπορείτε να χρησιμοποιήσετε την εντολή help.
Χρησιμοποιήστε βοηθήσει και στη συνέχεια να του δώσει το όνομα μιας εντολής.
Και θα δείτε το GDB δίνει σε όλους μας αυτό το είδος του πράγματα.
Λέει, "Με κανένα επιχείρημα, απαριθμεί δέκα ακόμη γραμμές μετά ή γύρω από την προηγούμενη επιχείρηση.
Κατάλογος - απαριθμεί τις δέκα γραμμές πριν - "
Ας δοκιμάστε να χρησιμοποιήσετε μείον λίστα.
Και αυτό απαριθμεί τις 10 γραμμές προηγούμενο? Μπορείτε να παίξετε γύρω με λίστα λίγο.
Μπορείτε να κάνετε λίστα, λίστα -, μπορείτε ακόμη και να εγγράψει έναν αριθμό, όπως η λίστα 8,
και θα απαριθμεί τις 10 γραμμές γύρω από τη γραμμή 8.
Και μπορείτε να δείτε τι συμβαίνει εδώ είναι ότι έχετε μια απλή, αν άλλο.
Αν πληκτρολογήσετε CS50 βράχους, που εκτυπώνει "Μπορείτε να πάρετε μια Α."
Διαφορετικά, εκτυπώνει "Μπορείτε να πάρετε μια Δ."
Κρίμα πόλη. Εντάξει. Ναι;
>> [Daniel] Έτσι, όταν προσπάθησα να κάνει CS50 βράχια χωρίς τα εισαγωγικά,
λέει "Μπορείτε να πάρετε μια Δ."
Χρειαζόμουν τα εισαγωγικά για να πάμε στη δουλειά μας? Γιατί συμβαίνει αυτό;
Ναι >>. Αποδεικνύεται ότι όταν - αυτό είναι ένα άλλο διασκεδαστικό λίγο εκλεκτός μεζές -
όταν εκτελείτε το πρόγραμμα, αν θέλουμε να τρέξει και να πληκτρολογήσετε CS50 βράχους,
όπως έλεγε ο Daniel έκανε, και πατήσετε Enter,
λέει ακόμα να πάρετε μια Δ.
Και το ερώτημα είναι, γιατί συμβαίνει αυτό;
Και αποδεικνύεται ότι τόσο τερματικό και GDB μας αναλύσει αυτά ως δύο ξεχωριστά επιχειρήματα.
Διότι όταν υπάρχει ένας χώρος, που είναι σιωπηρή, όπως
το πρώτο επιχείρημα έληξε? το επόμενο επιχείρημα είναι έτοιμο να ξεκινήσει.
Ο τρόπος για να συνδυάσετε αυτές σε δύο, ή συγγνώμη, σε ένα επιχείρημα,
είναι να χρησιμοποιήσετε τα εισαγωγικά.
Έτσι τώρα, αν το βάλετε σε εισαγωγικά και να τρέξει και πάλι, έχουμε μια A.
Έτσι απλά για να ανακεφαλαιώσουμε, δεν εισαγωγικά, CS50 και βράχια αναλύεται ως δύο ξεχωριστά επιχειρήματα.
Με εισαγωγικά, είναι αναλύονται ως ένα επιχείρημα εντελώς.
>> Μπορούμε να δούμε αυτό με ένα breakpoint.
Μέχρι στιγμής έχουμε ήδη τρέχει το πρόγραμμά μας, και είναι ήδη τρέχει
μέχρι είτε να διαχωρίζονται από λάθη ή επιτυχίες σφάλμα
ή μέχρι να βγει και όλα ήταν μια χαρά.
Αυτό δεν είναι απαραίτητα το πιο χρήσιμο πράγμα, επειδή μερικές φορές
έχετε ένα σφάλμα στο πρόγραμμά σας, αλλά αυτό δεν είναι που προκαλεί ένα σφάλμα καταμερισμού.
Δεν είναι αυτό που προκαλεί το πρόγραμμά σας για να σταματήσει ή κάτι τέτοιο.
Ο τρόπος για να πάρετε GDB να σταματήσει το πρόγραμμά σας σε ένα συγκεκριμένο σημείο
είναι να ορίσετε ένα breakpoint.
Μπορείτε να το κάνετε αυτό είτε με τον καθορισμό ενός breakpoint στο όνομα της συνάρτησης
ή μπορείτε να ορίσετε ένα breakpoint σε μια συγκεκριμένη γραμμή κώδικα.
Μου αρέσει να ορίσετε σημεία διακοπής λειτουργίας σε ονόματα, γιατί - είναι εύκολο να θυμάστε,
και αν πραγματικά πάνε και να αλλάξετε τον πηγαίο κώδικα σας επάνω λίγο,
breakpoint τότε θα σας μείνει πραγματικά στην ίδια θέση στον κωδικό σας.
Ότι, αν χρησιμοποιείτε αριθμούς γραμμών, και οι αριθμοί αλλάζουν γραμμή
επειδή μπορείτε να προσθέσετε ή να διαγράψετε κάποιο κωδικό, τότε τα σημεία διακοπής σας όλα εντελώς μαντάρα.
Ένα από τα πιο κοινά πράγματα που κάνετε είναι να ορίσετε ένα breakpoint στην κύρια λειτουργία.
Συχνά Θα εκκίνηση GDB, θα πληκτρολογήσετε β κύρια, πατήστε Enter, και ότι θα ορίσετε ένα breakpoint
για την κύρια λειτουργία που απλά λέει, "Παύση του πρόγραμμα αμέσως μόλις αρχίσουν να προβάλλονται,"
και με αυτόν τον τρόπο, όταν τρέχω το πρόγραμμα μου με, ας πούμε, CS50 βράχους ως δύο επιχειρήματα
και πατήστε Enter, παίρνει την κύρια λειτουργία και να σταματήσει ακριβώς στην πρώτη γραμμή,
δικαίωμα πριν αξιολογεί την strcmp λειτουργία.
>> Επειδή είμαι παύση, τώρα μπορώ να ξεκινήσω mucking γύρω και να δει τι συμβαίνει
με όλες τις διάφορες μεταβλητές που έχουν περάσει στο πρόγραμμά μου.
Εδώ μπορώ να εκτυπώσετε argc και να δούμε τι συμβαίνει.
Δείτε ότι argc είναι 3, επειδή πήρε 3 διαφορετικές τιμές σε αυτό.
Είναι πήρε το όνομα του προγράμματος, το πήρε το πρώτο επιχείρημα και το δεύτερο επιχείρημα.
Μπορούμε να τυπώσουμε από εκείνους που αναζητούν στο argv [0], argv [1], και argv [2].
Έτσι τώρα μπορείτε επίσης να δείτε γιατί αυτή η κλήση strcmp πρόκειται να αποτύχει,
γιατί βλέπεις ότι δεν χωρίσουν τον CS50 και τους βράχους σε δύο διαφορετικά επιχειρήματα.
Σε αυτό το σημείο, από τη στιγμή που έχετε χτυπήσει ένα σημείο διακοπής, μπορείτε να συνεχίσετε να το βήμα μέσα από το πρόγραμμα σας
γραμμή προς γραμμή, σε αντίθεση με την έναρξη του προγράμματος σας και πάλι.
Έτσι, αν δεν θέλετε να ξεκινήσετε το πρόγραμμά σας και πάλι και μόλις συνεχίσει από εδώ,
μπορείτε να χρησιμοποιήσετε την εντολή continue και θα συνεχιστεί τρέξει το πρόγραμμα μέχρι το τέλος.
Ακριβώς όπως το έκανε εδώ.
Ωστόσο, αν επανεκκίνηση του προγράμματος, CS50 βράχια, χτυπά breakpoint μου και πάλι,
και αυτή τη φορά, αν δεν θέλω να φύγουμε σε όλη τη διαδρομή μέσα από το υπόλοιπο του προγράμματος,
Μπορώ να χρησιμοποιήσω την επόμενη εντολή, που θα συντομεύσει επίσης με n.
Και αυτό θα το βήμα από τη γραμμή του προγράμματος από την γραμμή.
Έτσι, μπορείτε να παρακολουθήσετε τα πράγματα ως εκτελέσει, όπως η αλλαγή μεταβλητών, όπως τα πράγματα λάβετε ενημέρωση.
Ποια είναι αρκετά ωραία.
Το άλλο δροσερό πράγμα είναι αντί να επαναλαμβάνει την ίδια εντολή ξανά και ξανά και ξανά,
αν απλά πατήστε Enter - έτσι εδώ που βλέπετε δεν έχω πληκτρολογήσει στο τίποτα -
αν εγώ απλά πατήστε Enter, θα επαναλάβει την προηγούμενη εντολή,
ή η προηγούμενη εντολή GDB ότι εγώ απλά βάλτε μέσα
Μπορώ να κρατήσει το χτύπημα Enter και θα κρατήσει την ενίσχυση μέσω της γραμμής κωδικό μου γραμμή.
Θα ήθελα να σας ενθαρρύνω τα παιδιά να πάνε ελέγξτε έξω τα άλλα προγράμματα, καθώς και με λάθη.
Δεν έχουμε χρόνο για να περάσει όλα αυτά σήμερα στο τμήμα.
Ο πηγαίος κώδικας είναι εκεί, ώστε να μπορείτε να δείτε το είδος του τι συμβαίνει
πίσω από τις σκηνές, αν έχετε κολλήσει πραγματικά,
αλλά τουλάχιστον, ακριβώς πρακτική εκκίνηση GDB,
την εκτέλεση του προγράμματος μέχρι να σπάσει σε σας,
να πάρει την backtrace, υπολογίζει τι λειτουργεί η συντριβή ήταν,
ποια γραμμή ήταν επάνω, εκτύπωση κάποιες τιμές των μεταβλητών,
ακριβώς έτσι μπορείτε να πάρετε μια ιδέα για αυτό, γιατί αυτό πραγματικά θα σας βοηθήσει να πάμε μπροστά.
Σε αυτό το σημείο, θα πάμε για να βγείτε από το GDB, το οποίο μπορείτε να κλείσετε τη χρήση ή απλά q.
Εάν το πρόγραμμά σας είναι στη μέση της λειτουργίας ακόμα, και δεν έχει εγκαταλειφθεί,
θα σας ζητήσει πάντα, "Είστε σίγουροι ότι θέλετε πραγματικά να σταματήσουν το κάπνισμα;"
Μπορείτε απλά πατήστε ναι.
>> Τώρα θα πάμε να δούμε το επόμενο πρόβλημα που έχουμε, το οποίο είναι το πρόγραμμα γάτα.
Αν παρακολουθήσουμε τη σύντομη για τον αναπροσανατολισμό και σωλήνες, θα δείτε ότι ο Tommy χρησιμοποιεί αυτό το πρόγραμμα
που τυπώνει ουσιαστικά όλη την παραγωγή ενός αρχείου στην οθόνη.
Έτσι, αν τρέχω γάτα, αυτό είναι στην πραγματικότητα ένα ενσωματωμένο πρόγραμμα στη συσκευή,
και αν έχετε υπολογιστές Mac, μπορείτε να το κάνετε αυτό στο Mac σας πάρα πολύ, αν ανοίξετε το τερματικό.
Και εμείς - γάτα, ας πούμε, cp.c, και πατήστε Enter.
Αυτό το έκανε, αν μετακινηθείτε προς τα επάνω λίγο και να δούμε πού τρέξαμε τη γραμμή,
ή όπου τρέξαμε την εντολή cat, κυριολεκτικά μόλις εκτυπωθούν τα περιεχόμενα του cp.c στην οθόνη μας.
Μπορούμε να το τρέξει και πάλι και μπορείτε να βάλετε σε πολλά αρχεία μαζί.
Έτσι, μπορείτε να κάνετε cp.c γάτα, και στη συνέχεια μπορούμε να ενώσετε επίσης την cat.c αρχείο,
το οποίο είναι το πρόγραμμα είμαστε έτοιμοι να γράψει,
και αυτό θα εκτυπώσει και τα δύο αρχεία πλάτη με πλάτη στην οθόνη μας.
Έτσι, αν μετακινηθείτε προς τα επάνω λίγο, βλέπουμε ότι όταν έτρεξε αυτή cp.c γάτα, cat.c,
Αρχικά εκτυπώνεται το αρχείο cp, και στη συνέχεια, κάτω από αυτό, εκτυπώνεται το αρχείο cat.c δικαίωμα εδώ κάτω.
Εμείς πάμε για να χρησιμοποιήσετε αυτό για να πάρει ακριβώς τα πόδια μας υγρό.
Παίξτε με απλή εκτύπωση με το τερματικό, δείτε πώς λειτουργεί.
Αν εσείς ανοίξει με το gedit cat.c, πατήστε Enter,
μπορείτε να δείτε το πρόγραμμα ότι είμαστε έτοιμοι να γράψουν.
Έχουμε συμπεριλάβει αυτό το ωραίο πλάκα λέβητα, έτσι ώστε να μην χρειάζεται να περνούν το χρόνο πληκτρολογώντας όλα αυτά τα έξω.
Μπορούμε επίσης να ελέγξετε τον αριθμό των arguments που περνιούνται μέσα
Εμείς εκτυπώσετε ένα ωραίο μήνυμα χρήση.
>> Αυτό είναι το είδος των πράγμα που, και πάλι, όπως έχουμε μιλήσει για,
Είναι σχεδόν σαν μνήμη των μυών.
Απλά θυμηθείτε να συνεχίσει να κάνει το ίδιο είδος της ουσίας
και πάντα την εκτύπωση από κάποιο είδος χρήσιμο μήνυμα
έτσι ώστε οι άνθρωποι ξέρουν πώς να τρέξετε το πρόγραμμά σας.
Με γάτα, είναι αρκετά απλή? Είμαστε ακριβώς πρόκειται να περάσουν από όλα τα διαφορετικά επιχειρήματα
που είχαν περάσει στο πρόγραμμά μας, και θα πάμε για να εκτυπώσετε
περιεχόμενό τους έξω στην οθόνη, ένα κάθε φορά.
Για να εκτυπώσετε αρχεία από την οθόνη, θα πάμε να κάνουμε κάτι πολύ παρόμοιο
για ό, τι κάναμε στο τέλος του κουίζ.
Στο τέλος του κουίζ, που προσλαμβάνουν πρόγραμμα, θα έπρεπε να ανοίξουμε ένα αρχείο,
και τότε θα έπρεπε να εκτυπώσουν σε αυτό.
Σε αυτή την περίπτωση, θα πάμε για να ανοίξει ένα αρχείο, και θα πάμε να διαβάσετε από αυτό αντ 'αυτού.
Στη συνέχεια θα πάμε να εκτυπώσετε, αντί σε ένα αρχείο, θα πάμε για να εκτυπώσετε στην οθόνη.
Έτσι, εκτύπωση στην οθόνη που έχετε κάνει πριν από όλα με printf.
Έτσι, αυτό δεν είναι πάρα πολύ τρελό.
Όμως, την ανάγνωση ενός αρχείου είναι το είδος της παράξενο.
Θα πάμε μέσα από αυτό ένα μικρό κομμάτι σε έναν χρόνο.
Αν εσείς πάτε πίσω σε εκείνη την τελευταία πρόβλημα με κουίζ σας, πρόβλημα 33,
η πρώτη γραμμή που θα πάμε να κάνουμε εδώ, το άνοιγμα του αρχείου, είναι πολύ παρόμοιο με αυτό που κάναμε εκεί.
Έτσι, Στέλλα, τι κάνει αυτό το βλέμμα σαν γραμμή, όταν ανοίγουμε ένα αρχείο;
[Στέλλα] * ΑΡΧΕΙΟ Capital, αρχείο - >> Εντάξει. >> - Είναι ίσο με fopen. Yup >>.
Που στην προκειμένη περίπτωση είναι; Είναι το σχόλιο.
>> Είναι το σχόλιο; argv [i] και r;
Ακριβώς >>. Δεξιά επάνω. Έτσι Στέλλα είναι εντελώς σωστό.
Αυτό είναι ό, τι η γραμμή μοιάζει.
Εμείς πάμε για να πάρει μια μεταβλητή ροή αρχείο, αποθηκεύστε το σε ένα αρχείο *, έτσι ώστε όλα τα καλύμματα,
FILE, *, και το όνομα αυτής της μεταβλητής θα είναι το αρχείο.
Θα μπορούσαμε να το ονομάσουμε ό, τι μας αρέσει. Θα μπορούσαμε να το ονομάσουμε first_file, ή file_i, ό, τι θα θέλαμε.
Και τότε το όνομα του αρχείου ψηφίστηκε στη γραμμή εντολών σε αυτό το πρόγραμμα.
Έτσι είναι αποθηκευμένο στο argv [i,] και στη συνέχεια θα πάμε για να ανοίξει αυτό το αρχείο σε κατάσταση ανάγνωσης.
Τώρα που έχουμε ανοίξει το αρχείο, αυτό είναι το πράγμα που πρέπει πάντα να θυμάστε να κάνετε
κάθε φορά που έχουμε ανοίξει ένα αρχείο; Κλείστε αυτό.
Έτσι, δεσποινίς, πώς μπορούμε να κλείσει ένα αρχείο;
[Missy] Αδυναμία εγγραφής αρχείου (αρχείο) >> Αδυναμία εγγραφής αρχείου (αρχείο). Ακριβώς.
Μεγάλη. Εντάξει. Αν κοιτάξουμε να κάνουμε αυτό το σχόλιο εδώ,
λέει, "Open argv [i] και να εκτυπώσετε το περιεχόμενό του στο stdout."
>> Πρότυπο έξω είναι ένα παράξενο όνομα. Stdout είναι ακριβώς ο τρόπος μας για να πούμε
θέλουμε να το εκτυπώσετε στο τερματικό? θέλουμε να το εκτυπώσετε με το πρότυπο ρεύμα εξόδου.
Μπορούμε πραγματικά να απαλλαγούμε από αυτό το σχόλιο εδώ.
Πάω να το αντιγράψετε και να επικολλήσετε αυτό δεδομένου ότι είναι ό, τι κάναμε.
Σε αυτό το σημείο, τώρα έχουμε να διαβάσει το αρχείο κομμάτι από το κομμάτι.
Έχουμε συζητήσει ένα ζευγάρι των τρόπων ανάγνωσης αρχείων.
Ποια είναι τα αγαπημένα σας μέχρι τώρα;
Ποια τρόπους έχετε δει ή να θυμάστε, να διαβάσετε τα αρχεία;
[Daniel] fread; >> Fread; Έτσι fread είναι ένα. Jimmy, ξέρετε κάποια άλλα;
[Jimmy] Όχι >> Εντάξει. Όχι. Charlotte; Αλέξανδρος; Τυχόν άλλοι; Εντάξει.
Έτσι, οι υπόλοιπες είναι fgetc, είναι αυτή που θα χρησιμοποιήσουμε πολλά.
Υπάρχει επίσης fscanf? Εσείς δείτε ένα μοτίβο εδώ;
Όλοι ξεκινούν με f. Ό, τι να κάνει με ένα αρχείο.
Υπάρχει fread, fgetc, fscanf. Αυτά είναι όλα τα λειτουργίες ανάγνωσης.
Για γραφή έχουμε fwrite, έχουμε fputc αντί του fgetc.
Έχουμε επίσης fprintf όπως είδαμε στο κουίζ.
Δεδομένου ότι αυτό είναι ένα πρόβλημα που περιλαμβάνει την ανάγνωση από ένα αρχείο,
θα πάμε να χρησιμοποιήσετε μία από αυτές τις τρεις λειτουργίες.
Εμείς δεν πρόκειται να χρησιμοποιήσετε τις λειτουργίες αυτές εδώ κάτω.
Αυτές οι λειτουργίες που βρίσκονται όλα στο πρότυπο I / O βιβλιοθήκη.
Έτσι, αν κοιτάξουμε την κορυφή αυτού του προγράμματος,
μπορείτε να δείτε ότι έχουμε ήδη συμπεριλάβει το αρχείο κεφαλίδα για το πρότυπο I / O βιβλιοθήκη.
Αν θέλουμε να καταλάβουμε ποια θέλουμε να χρησιμοποιήσουμε,
μπορούμε πάντα να ανοίξει τις σελίδες man.
Έτσι μπορούμε να πληκτρολογήσετε stdio άνθρωπος
και να διαβάσετε όλα τα σχετικά με την είσοδο και stdio λειτουργίες εξόδου στον Γ.
Και μπορούμε να δούμε ήδη oh, κοίτα. Είναι που παραπέμπουν fgetc, αυτό είναι που παραπέμπουν fputc.
Έτσι, μπορείτε να εμβαθύνετε λίγο και να δούμε, ας πούμε, fgetc
και να κοιτάξουμε σελίδα man της.
Μπορείτε να δείτε ότι πηγαίνει μαζί με ένα σωρό άλλες λειτουργίες:
fgetc, fgets, getc, getchar, παίρνει, ungetc, και η συμβολή του χαρακτήρες και έγχορδα.
Έτσι, αυτό είναι το πώς διαβάζουμε σε χαρακτήρες και έγχορδα από τα αρχεία από την κανονική είσοδο,
η οποία είναι κατ 'ουσίαν από το χρήστη.
Και αυτό είναι το πώς το κάνουμε στην πραγματική C.
Έτσι, αυτό που δεν χρησιμοποιούν το GetString getchar και λειτουργίες
ότι χρησιμοποιείται από τη βιβλιοθήκη CS50.
Εμείς πάμε για να κάνουμε αυτό το πρόβλημα σε μια-δυο τρόπους
έτσι ώστε να μπορείτε να δείτε δύο διαφορετικούς τρόπους για να γίνει αυτό.
Τόσο η λειτουργία fread ότι ο Δανιήλ αναφέρει και fgetc είναι καλοί τρόποι για να το κάνει.
Νομίζω fgetc είναι λίγο πιο εύκολο, γιατί έχει μόνο, όπως βλέπετε,
ένα όρισμα, το αρχείο * ότι προσπαθούμε να διαβάσετε το χαρακτήρα από,
και η τιμή επιστροφής της είναι ένα int.
Και αυτό είναι μια μικρή σύγχυση, έτσι δεν είναι;
>> Επειδή είμαστε να πάρει ένα χαρακτήρα, οπότε γιατί να μην επιστρέψει μια χαρα;
Εσείς έχετε κάποιες ιδέες σχετικά με το γιατί αυτό δεν θα μπορούσε να επιστρέψει μια χαρα;
[Απαντήσεις Missy, ακατάληπτο] >> Ναι. Έτσι, Missy είναι εντελώς σωστό.
Αν είναι ASCII, τότε αυτό θα μπορούσε να είναι ακέραιος αντιστοιχίζονται με μία πραγματική char.
Θα μπορούσε να είναι ένα ASCII χαρακτήρα, και αυτό είναι σωστό.
Αυτό είναι ακριβώς τι συμβαίνει.
Είμαστε χρησιμοποιώντας ένα int απλά επειδή έχει περισσότερα bit.
Είναι μεγαλύτερο από ένα char? Char μας έχει μόνο 8 bits, ότι 1 byte για 32-bit μηχανές μας.
Και μια int έχει αξία όλων των 4 bytes του χώρου.
Και αποδεικνύεται ότι ο τρόπος που λειτουργεί fgetc,
αν μετακινηθείτε προς τα κάτω στη σύνοψη μας σε αυτή τη σελίδα άνθρωπο λίγο,
μετακινηθείτε σε όλη τη διαδρομή προς τα κάτω. Αποδεικνύεται ότι χρησιμοποιούν αυτή την ιδιαίτερη αξία που ονομάζεται ΕΟΦ.
Είναι μια ειδική σταθερά ως τιμή επιστροφής της συνάρτησης fgetc
κάθε φορά που θα χτυπήσει το τέλος του αρχείου ή εάν παίρνετε ένα λάθος.
Και αποδεικνύεται ότι για να κάνουμε αυτές τις συγκρίσεις με τον ΕΟΦ σωστά,
θέλετε να έχετε αυτό το επιπλέον ποσό των πληροφοριών που έχετε σε μια int
σε αντίθεση με τη χρήση ενός απανθρακώματος μεταβλητή.
Ακόμα κι αν fgetc είναι να πάρει αποτελεσματικά ένα χαρακτήρα από ένα αρχείο,
θέλετε να θυμάστε ότι επιστρέφει κάτι που είναι του τύπου int σε εσάς.
Τούτου λεχθέντος, είναι αρκετά εύκολο στη χρήση.
Είναι πρόκειται να μας δώσει ένα χαρακτήρα? Έτσι το μόνο που έχουμε να κάνουμε είναι να κρατήσει ζητώντας από το αρχείο,
"Δώσε μου τον επόμενο χαρακτήρα, να μου δώσει τον επόμενο χαρακτήρα, να μου δώσει τον επόμενο χαρακτήρα»,
μέχρι να φτάσουμε στο τέλος του αρχείου.
Και ότι θα τραβήξει σε ένα χαρακτήρα τη φορά από το αρχείο μας,
και στη συνέχεια μπορούμε να κάνουμε ό, τι θέλουμε με αυτό.
Μπορούμε να το αποθηκεύσετε, μπορούμε να το προσθέσετε σε μια σειρά, μπορούμε να το εκτυπώσετε.
Προβείτε σε οποιαδήποτε από αυτό.
>> Ζουμ πίσω έξω και να πηγαίνει πίσω στο πρόγραμμα cat.c μας,
αν θα πάμε να χρησιμοποιήσετε fgetc,
πώς θα μπορούσαμε να προσεγγίσουμε αυτή την επόμενη γραμμή του κώδικα;
Εμείς πάμε για να χρησιμοποιήσει - fread θα κάνει κάτι λίγο διαφορετικό.
Και αυτή τη φορά, είμαστε ακριβώς πρόκειται να χρησιμοποιήσετε fgetc να πάρει ένα χαρακτήρα κάθε φορά.
Για να επεξεργαστείτε ένα ολόκληρο αρχείο, αυτό θα μπορούσε να πρέπει να κάνουμε;
Πόσοι χαρακτήρες υπάρχουν σε ένα αρχείο;
Υπάρχουν πολλά. Έτσι, ίσως θέλετε να πάρετε ένα
και στη συνέχεια να πάρετε ένα άλλο και να πάρει ένα άλλο και να πάρει ένα άλλο.
Τι είδος του αλγορίθμου νομίζετε ότι θα μπορούσαμε να χρησιμοποιήσουμε εδώ;
Τι είδους -; [Αλέξανδρος] Α για βρόχο; Ακριβώς >>.
Κάποιο είδος του βρόγχου.
Ένας βρόχος for είναι πραγματικά μεγάλη, σε αυτή την περίπτωση.
Και όπως είπατε, αυτό ακούγεται σαν θέλετε μια θηλιά πάνω από το σύνολο του φακέλου,
να πάρει ένα χαρακτήρα τη φορά.
Οποιεσδήποτε προτάσεις σχετικά με το τι που θα μπορούσε να μοιάζει;
[Αλέξανδρος, ακατάληπτο]
>> Εντάξει, απλά πες μου στα αγγλικά αυτό που προσπαθείτε να κάνετε; [Αλέξανδρος, ακατάληπτο]
Έτσι, στην περίπτωση αυτή, ακούγεται σαν να είμαστε απλώς προσπαθεί να βρόχο πάνω από το σύνολο του φακέλου.
[Αλέξανδρος] Έτσι, i <το μέγεθος του int; >> Το μέγεθος της -;
Υποθέτω ότι το μέγεθος του αρχείου, έτσι δεν είναι; Το μέγεθος - we'll απλά γράψτε το όπως αυτό.
Μέγεθος του αρχείου για την ώρα, i + +.
Έτσι, αποδεικνύεται ότι ο τρόπος που το κάνετε αυτό χρησιμοποιώντας fgetc, και αυτό είναι νέο,
είναι ότι δεν υπάρχει εύκολος τρόπος για να πάρετε ακριβώς το μέγεθος ενός αρχείου
με αυτό το "sizeof" τύπο κατασκευής που έχετε δει πριν.
Όταν χρησιμοποιείτε αυτή τη λειτουργία fgetc, είμαστε εισαγωγή κάποιου είδους
νέα, funky σύνταξη σε αυτό για βρόχο, όπου αντί να χρησιμοποιεί μόνο μια βασική αντίθεση
για να πάει χαρακτήρα προς χαρακτήρα, θα πάμε να τραβήξει ένα χαρακτήρα κάθε φορά,
ένα χαρακτήρα κάθε φορά, και ο τρόπος που ξέρουμε ότι είμαστε στο τέλος
όταν δεν έχουμε υπολογίζονται έναν ορισμένο αριθμό χαρακτήρων,
αλλά όταν ο χαρακτήρας μας βγάλει είναι ότι οι ειδικές τέλος του αρχείου χαρακτήρα.
Έτσι, μπορούμε να το κάνουμε αυτό με - Καλώ αυτό το ch, και θα πάμε να το αρχικοποιήσει
με την πρώτη κλήση μας για να πάρει τον πρώτο χαρακτήρα από το αρχείο.
Έτσι, αυτό το μέρος εδώ, αυτό πρόκειται να πάρει ένα χαρακτήρα από το αρχείο
και να αποθηκεύσει στη μεταβλητή ch.
Εμείς πάμε για να συνεχίσουμε να το κάνουμε αυτό μέχρι να φτάσουμε στο τέλος του αρχείου,
οποίο κάνουμε με τη δοκιμή για τον χαρακτήρα δεν είναι ίσο με το εν λόγω ειδικό χαρακτήρα ΕΟΦ.
Και τότε, αντί να κάνει ch + +, η οποία θα αυξήσει την αξία μόνο του,
οπότε αν διαβάσουμε ένα ένα από το αρχείο, ένα κεφαλαίο Α, ας πούμε,
ch + + θα μας δώσει β, και τότε θα έπαιρνα γ και δ στη συνέχεια.
Αυτό σαφώς δεν είναι αυτό που θέλουμε. Αυτό που θέλουμε εδώ
σε αυτό το τελευταίο κομμάτι που θέλουμε να πάρει τον επόμενο χαρακτήρα από το αρχείο.
>> Πώς, λοιπόν, μπορεί να έχουμε τον επόμενο χαρακτήρα από το αρχείο;
Πώς να πάρει τον πρώτο χαρακτήρα από το αρχείο;
[Φοιτητικό] fgetfile; >> Fgetc, ή, συγγνώμη, θα ήταν απόλυτα σωστή.
Μου ορθογραφικά λάθη εκεί. Οπότε ναι.
Εδώ, αντί να κάνει ch + +,
είμαστε ακριβώς πρόκειται να καλέσετε fgetc (αρχείο) και πάλι
και αποθηκεύουν το αποτέλεσμα στην ίδια μεταβλητή ch μας.
[Ερώτηση Φοιτητών, ακατάληπτο]
>> Αυτό είναι όπου αυτοί οι τύποι αρχείου * είναι ειδική.
Ο τρόπος που λειτουργεί είναι ότι - όταν για πρώτη φορά ανοιχτό - όταν κάνετε την πρώτη κλήση αυτή fopen,
το * FILE χρησιμεύει αποτελεσματικά ως ένα δείκτη στην αρχή του αρχείου.
Και στη συνέχεια, κάθε φορά που θα καλέσει fgetc, κινείται ένα χαρακτήρα μέσα από το αρχείο.
Έτσι, κάθε φορά που θα καλέσει αυτό, έχετε την αύξηση του δείκτη αρχείου με ένα χαρακτήρα.
Και όταν fgetc πάλι, είστε κινείται το άλλο χαρακτήρα
και ένα άλλο χαρακτήρα και ένα άλλο χαρακτήρα και ένα άλλο χαρακτήρα.
[Ερώτηση Φοιτητών, ακατάληπτο] >> Και that's - ναι.
Είναι το είδος της μαγείας κάτω από την κουκούλα.
Μπορείτε απλά να κρατήσει προσαύξηση μέσα.
Σε αυτό το σημείο, είστε σε θέση πραγματικά να συνεργαστεί με έναν χαρακτήρα.
Πώς, λοιπόν, θα μπορούσαμε να εκτυπώσετε αυτό έξω στην οθόνη, τώρα;
Μπορούμε να χρησιμοποιήσουμε το ίδιο πράγμα printf που χρησιμοποιήσαμε πριν.
Αυτό που έχουμε χρησιμοποιήσει όλα τα εξαμήνου.
Μπορούμε να καλέσετε printf,
και μπορούμε να περάσουμε στο χαρακτήρα έτσι απλά.
Ένας άλλος τρόπος για να το κάνουμε είναι αντί να χρησιμοποιούν printf και έχουν να κάνουν αυτή την συμβολοσειρά μορφής,
μπορούμε επίσης να χρησιμοποιήσουμε μία από τις άλλες λειτουργίες.
Μπορούμε να χρησιμοποιήσουμε fputc, η οποία εκτυπώνει ένα χαρακτήρα στην οθόνη,
εκτός αν κοιτάξουμε fputc - επιτρέψτε μου σμίκρυνση λίγο.
Βλέπουμε τι ωραίο είναι ότι παίρνει στο χαρακτήρα που διαβάζουμε με τη χρήση fgetc,
αλλά τότε θα πρέπει να του δώσετε ένα ρεύμα να εκτυπώσετε.
Μπορούμε επίσης να χρησιμοποιήσουμε τη λειτουργία putchar, το οποίο θα τεθεί άμεσα σε τυποποιημένες.
Έτσι, υπάρχουν ένα σωρό διαφορετικές επιλογές που μπορούμε να χρησιμοποιήσουμε για την εκτύπωση.
Είναι όλα στο πρότυπο I / O βιβλιοθήκη.
Κάθε φορά που θέλετε να εκτυπώσετε - έτσι printf, από προεπιλογή, θα εκτυπωθούν σε ειδικό πρότυπο από ρεύμα,
η οποία είναι ότι stdout.
Έτσι, μπορούμε απλά να αναφέρονται σε αυτήν ως είδος αυτού του μαγικού αξία, stdout εδώ.
Ωχ. Βάλτε το ερωτηματικό έξω.
>> Αυτή είναι μια πολύ νέα, funky πληροφορίες εδώ.
Πολλά από αυτά είναι πολύ ιδιότυπο, με την έννοια ότι αυτή είναι κώδικας
που είναι γραμμένο με αυτόν τον τρόπο μόνο και μόνο επειδή είναι καθαρή για να διαβάσετε, εύκολο να το διαβάσετε.
Υπάρχουν πολλοί διαφορετικοί τρόποι για να το κάνει, πολλές διαφορετικές λειτουργίες που μπορείτε να χρησιμοποιήσετε,
αλλά έχουμε την τάση να ακολουθούν ακριβώς τα ίδια μοτίβα ξανά και ξανά.
Έτσι, μην εκπλαγείτε αν δείτε τον κωδικό όπως αυτό έρχονται ξανά και ξανά.
Εντάξει. Σε αυτό το σημείο, πρέπει να σπάσει για την ημέρα.
Ευχαριστώ που ήρθες. Ευχαριστώ για την προσοχή αν είστε σε απευθείας σύνδεση. Και θα τα πούμε την επόμενη εβδομάδα.
[CS50.TV]