1 00:00:00,000 --> 00:00:02,520 [Powered by Google Translate] [Ενότητα 4 - Άνετα Περισσότερα] 2 00:00:02,520 --> 00:00:04,850 [Rob Bowden - Πανεπιστήμιο του Χάρβαρντ] 3 00:00:04,850 --> 00:00:07,370 [Αυτό είναι CS50. - CS50.TV] 4 00:00:08,920 --> 00:00:13,350 Έχουμε ένα κουίζ αύριο, σε περίπτωση που εσείς δεν το γνωρίζουν αυτό. 5 00:00:14,810 --> 00:00:20,970 Είναι βασικά για ό, τι θα μπορούσε να δει σε τάξη ή θα πρέπει να έχουν δει στην τάξη. 6 00:00:20,970 --> 00:00:26,360 Αυτό περιλαμβάνει δείκτες, ακόμη κι αν είναι ένα πολύ πρόσφατο θέμα. 7 00:00:26,360 --> 00:00:29,860 Θα πρέπει τουλάχιστον να καταλάβουν τα υψηλά επίπεδα τους. 8 00:00:29,860 --> 00:00:34,760 Οτιδήποτε που είχε φύγει πάνω στην τάξη θα πρέπει να καταλάβετε για το κουίζ. 9 00:00:34,760 --> 00:00:37,320 Έτσι, εάν έχετε ερωτήσεις σχετικά με αυτούς, μπορείτε να τους ρωτήσετε τώρα. 10 00:00:37,320 --> 00:00:43,280 Αλλά αυτό πρόκειται να είναι μια πολύ φοιτητής υπό την ηγεσία της συνόδου, όπου εσείς ερωτήσεις, 11 00:00:43,280 --> 00:00:45,060 έτσι ελπίζουμε ότι οι άνθρωποι έχουν ερωτήσεις. 12 00:00:45,060 --> 00:00:48,020 Υπάρχει κάποιος που έχει ερωτήσεις; 13 00:00:49,770 --> 00:00:52,090 Ναι. >> [Φοιτητής] Μπορείς να πάει πέρα ​​από δείκτες πάλι; 14 00:00:52,090 --> 00:00:54,350 Θα πάω πάνω από δείκτες. 15 00:00:54,350 --> 00:00:59,180 Όλες οι μεταβλητές σας κατ 'ανάγκην ζουν στη μνήμη, 16 00:00:59,180 --> 00:01:04,450 αλλά συνήθως δεν ανησυχούν γι 'αυτό και το μόνο που λένε x + 2 και y + 3 17 00:01:04,450 --> 00:01:07,080 και ο compiler θα καταλάβω όπου τα πράγματα είναι ζωντανά για εσάς. 18 00:01:07,080 --> 00:01:12,990 Όταν έχουμε να κάνουμε με δείκτες, τώρα που χρησιμοποιείτε ρητά αυτές τις διευθύνσεις μνήμης. 19 00:01:12,990 --> 00:01:19,800 Έτσι, μια μεταβλητή θα ζήσουν ποτέ σε μια μοναδική διεύθυνση σε κάθε δεδομένη στιγμή. 20 00:01:19,800 --> 00:01:24,040 Αν θέλουμε να δηλώνουμε έναν pointer, τι είναι ο τύπος πρόκειται να μοιάσει; 21 00:01:24,040 --> 00:01:26,210 >> Θέλω να κηρύξει σ δείκτη. Τι κάνει ο τύπος μοιάζει; 22 00:01:26,210 --> 00:01:33,530 [Φοιτητής] int * p. Ναι >>. Έτσι, int * p. 23 00:01:33,530 --> 00:01:38,030 Και πώς μπορώ να κάνω το σημείο στο x; >> [Φοιτητής] Ampersand. 24 00:01:40,540 --> 00:01:45,300 [Bowden] Έτσι, εμπορικό και κυριολεκτικά ονομάζεται η διεύθυνση του επιχειρηματία. 25 00:01:45,300 --> 00:01:50,460 Έτσι, όταν λέω & x είναι να πάρει τη διεύθυνση μνήμης της μεταβλητής x. 26 00:01:50,460 --> 00:01:56,790 Έτσι, τώρα έχω το δείκτη p, και οπουδήποτε στον κώδικά μου μπορώ να χρησιμοποιήσω * p 27 00:01:56,790 --> 00:02:02,960 ή θα μπορούσα να χρησιμοποιήσω x και θα είναι ακριβώς το ίδιο πράγμα. 28 00:02:02,960 --> 00:02:09,520 (* Ρ). Τι κάνει αυτό; Τι σημαίνει ότι το αστέρι; 29 00:02:09,520 --> 00:02:13,120 [Φοιτητής] Αυτό σημαίνει ότι μια τιμή σε αυτό το σημείο. Ναι >>. 30 00:02:13,120 --> 00:02:17,590 Έτσι, αν το δούμε, μπορεί να είναι πολύ χρήσιμο να σκιαγραφήσει τα διαγράμματα 31 00:02:17,590 --> 00:02:22,230 όπου αυτό είναι ένα μικρό κουτί μνήμης για χ, η οποία συμβαίνει να έχει την τιμή 4, 32 00:02:22,230 --> 00:02:25,980 τότε έχουμε ένα μικρό κουτί της μνήμης για το p, 33 00:02:25,980 --> 00:02:31,590 και έτσι να σ. σημεία x, έτσι ώστε να σχεδιάσετε ένα βέλος από το p στο x. 34 00:02:31,590 --> 00:02:40,270 Έτσι, όταν λέμε * σ. λέμε πάμε στο κουτί που είναι p. 35 00:02:40,270 --> 00:02:46,480 Αστέρια είναι να ακολουθήσετε το βέλος και στη συνέχεια, κάντε ό, τι θέλετε με αυτό το κουτί εκεί. 36 00:02:46,480 --> 00:03:01,090 Έτσι μπορώ να πω * p = 7? Και ότι θα πάει στο κουτί που είναι x και η αλλαγή που έως 7. 37 00:03:01,090 --> 00:03:13,540 Ή θα μπορούσα να πω int z = * p * 2? Αυτό είναι σύγχυση, επειδή αυτό είναι αστέρι, αστέρι. 38 00:03:13,540 --> 00:03:19,230 Το ένα άστρο εύρεση τιμών p, το άλλο αστέρι πολλαπλασιάζεται επί 2. 39 00:03:19,230 --> 00:03:26,780 Παρατηρήστε θα μπορούσε να έχει εξίσου καλά αντικατέστησε το p * με x. 40 00:03:26,780 --> 00:03:29,430 Μπορείτε να τα χρησιμοποιήσετε με τον ίδιο τρόπο. 41 00:03:29,430 --> 00:03:38,000 Και τότε αργότερα μπορώ να έχω σημείο p σε ένα εντελώς νέο πράγμα. 42 00:03:38,000 --> 00:03:42,190 Μπορώ μόνο να πω p = &z; 43 00:03:42,190 --> 00:03:44,940 Έτσι p τώρα δεν είναι πλέον σημεία για x? Αυτό δείχνει z. 44 00:03:44,940 --> 00:03:50,510 Και κάθε φορά που κάνω * p είναι το ίδιο όπως κάνει z. 45 00:03:50,510 --> 00:03:56,170 Έτσι, το χρήσιμο πράγμα για αυτό είναι όταν θα αρχίσουν να πάρει σε λειτουργίες. 46 00:03:56,170 --> 00:03:59,790 >> Είναι το είδος των άχρηστων να δηλώσει ένα δείκτη που δείχνει σε κάτι 47 00:03:59,790 --> 00:04:03,140 και τότε είστε απλά εύρεση τιμών 48 00:04:03,140 --> 00:04:06,060 όταν θα μπορούσε να χρησιμοποιήσει την αρχική μεταβλητή για να αρχίσει με. 49 00:04:06,060 --> 00:04:18,190 Αλλά όταν μπει σε λειτουργία - οπότε ας πούμε ότι έχουμε κάποια λειτουργία, int foo, 50 00:04:18,190 --> 00:04:32,810 που παίρνει ένα δείκτη και μόλις κάνει * p = 6? 51 00:04:32,810 --> 00:04:39,990 Όπως είδαμε πριν, με swap, δεν μπορείτε να κάνετε μια αποτελεσματική ανταλλαγή και μια ξεχωριστή λειτουργία 52 00:04:39,990 --> 00:04:45,180 με απλά περνώντας ακέραιοι, διότι τα πάντα σε C είναι πάντα περνώντας από αξία. 53 00:04:45,180 --> 00:04:48,360 Ακόμα και όταν είστε περνώντας δείκτες είστε περνώντας από την αξία. 54 00:04:48,360 --> 00:04:51,940 Συμβαίνει ότι αυτές οι αξίες είναι διευθύνσεις μνήμης. 55 00:04:51,940 --> 00:05:00,770 Έτσι, όταν λέω foo (ιστ)? Είμαι πέρασμα του δείκτη σε συνάρτηση foo 56 00:05:00,770 --> 00:05:03,910 και στη συνέχεια να κάνει foo * p = 6? 57 00:05:03,910 --> 00:05:08,600 Έτσι, μέσα από αυτή τη λειτουργία, * p εξακολουθεί να είναι ισοδύναμο προς το x, 58 00:05:08,600 --> 00:05:12,720 αλλά δεν μπορώ να χρησιμοποιήσω x στο εσωτερικό αυτής της λειτουργίας, επειδή δεν είναι scoped εντός της εν λόγω λειτουργία. 59 00:05:12,720 --> 00:05:19,510 Έτσι * p = 6 είναι ο μόνος τρόπος που μπορώ να αποκτήσετε πρόσβαση σε μια τοπική μεταβλητή από μια άλλη λειτουργία. 60 00:05:19,510 --> 00:05:23,600 Ή, επίσης, δείκτες είναι ο μόνος τρόπος που μπορώ να αποκτήσετε πρόσβαση σε μια τοπική μεταβλητή από μια άλλη λειτουργία. 61 00:05:23,600 --> 00:05:31,600 [Φοιτητής] Ας πούμε ότι έχετε ήθελε να επιστρέψει ένα δείκτη. Πώς ακριβώς το κάνεις αυτό; 62 00:05:31,600 --> 00:05:44,270 [Bowden] Επιστροφή έναν δείκτη όπως σε κάτι σαν int y = 3? Επιστροφή & y; >> [Φοιτητής] Ναι. 63 00:05:44,270 --> 00:05:48,480 [Bowden] Εντάξει. Ποτέ δεν θα πρέπει να το κάνετε αυτό. Αυτό είναι κακό. 64 00:05:48,480 --> 00:05:59,480 Νομίζω ότι είδα σε αυτές τις διαφάνειες διάλεξης που άρχισε να βλέπει όλο αυτό το διάγραμμα της μνήμης 65 00:05:59,480 --> 00:06:02,880 όπου εδώ έχετε τη διεύθυνση μνήμης 0 66 00:06:02,880 --> 00:06:09,550 και κάτω εδώ έχετε μνήμη διεύθυνση 4 συναυλίες ή 2 στο 32. 67 00:06:09,550 --> 00:06:15,120 Έτσι λοιπόν έχετε κάποια πράγματα και κάποια πράγματα και στη συνέχεια να έχετε στοίβα σας 68 00:06:15,120 --> 00:06:21,780 και έχετε σωρό σας, που μόλις άρχισε να μαθαίνει περίπου, που μεγαλώνει. 69 00:06:21,780 --> 00:06:24,390 [Φοιτητής] Δεν είναι ο σωρός πάνω από τη στοίβα; 70 00:06:24,390 --> 00:06:27,760 >> Ναι. Ο σωρός είναι στην κορυφή, έτσι δεν είναι; >> [Φοιτητής] Λοιπόν, έβαλε 0 στην κορυφή. 71 00:06:27,760 --> 00:06:30,320 [Φοιτητής] Ω, έβαλε 0 στην κορυφή. >> [Φοιτητής] Ω, εντάξει. 72 00:06:30,320 --> 00:06:36,060 Αποποίηση: Οπουδήποτε με CS50 θα πάμε να δούμε αυτό τον τρόπο. >> [Φοιτητής] Εντάξει. 73 00:06:36,060 --> 00:06:40,290 Είναι απλά ότι όταν δω τον πρώτο στοίβες, 74 00:06:40,290 --> 00:06:45,000 όπως όταν σκέφτεστε από μια στοίβα γνώμη σας για στοίβαγμα τα πράγματα το ένα πάνω στο άλλο. 75 00:06:45,000 --> 00:06:50,810 Έτσι, έχουμε την τάση να αναστρέψετε γύρω από αυτό, ώστε η στοίβα μεγαλώνει σαν μια στοίβα κανονικά 76 00:06:50,810 --> 00:06:55,940 αντί της στοίβας κρέμεται προς τα κάτω. >> [Φοιτητής] Μην σωρούς τεχνικά μεγαλώσει πάρα πολύ, όμως; 77 00:06:55,940 --> 00:07:01,100 Εξαρτάται από το τι εννοείτε με τον όρο μεγαλώνουν. 78 00:07:01,100 --> 00:07:04,010 Η στοίβα και σωρού πάντα μεγαλώνουν σε αντίθετες κατευθύνσεις. 79 00:07:04,010 --> 00:07:09,420 Μια στοίβα είναι πάντα μεγαλώνουν με την έννοια ότι είναι μεγαλώνουν 80 00:07:09,420 --> 00:07:12,940 προς υψηλότερες διευθύνσεις μνήμης, και ο σωρός αυξάνεται κάτω 81 00:07:12,940 --> 00:07:17,260 υπό την έννοια ότι μεγαλώνει προς χαμηλότερες διευθύνσεις μνήμης. 82 00:07:17,260 --> 00:07:20,250 Έτσι, η κορυφή είναι 0 και το κάτω μέρος είναι υψηλή διευθύνσεις μνήμης. 83 00:07:20,250 --> 00:07:26,390 Είναι και οι δύο αυξάνονται, μόνο σε αντίθετες κατευθύνσεις. 84 00:07:26,390 --> 00:07:29,230 [Φοιτητής] εννοούσα ακριβώς αυτό, επειδή είπατε βάζετε στοίβα στο κάτω μέρος 85 00:07:29,230 --> 00:07:33,640 επειδή φαίνεται πιο διαισθητική επειδή για τη στοίβα για να ξεκινήσει στην κορυφή ενός σωρού, 86 00:07:33,640 --> 00:07:37,520 σωρός είναι στην κορυφή του εαυτού πάρα πολύ, έτσι that's - >> Ναι. 87 00:07:37,520 --> 00:07:44,960 Μπορείτε επίσης να σκεφτείτε του σωρού, όπως μεγαλώνουν και μεγαλύτερα, αλλά η στοίβα περισσότερο. 88 00:07:44,960 --> 00:07:50,280 Έτσι, η στοίβα είναι αυτό που εμείς το είδος της θέλουν να δείξουν μεγαλώνουν. 89 00:07:50,280 --> 00:07:55,390 Αλλά παντού εσείς κοιτάζουν αλλιώς θα δείξει διεύθυνση 0 στην κορυφή 90 00:07:55,390 --> 00:07:59,590 και η υψηλότερη διεύθυνση μνήμης στο κάτω μέρος, έτσι αυτό είναι συνηθισμένο προβολή της μνήμης. 91 00:07:59,590 --> 00:08:02,100 >> Έχετε μια ερώτηση; 92 00:08:02,100 --> 00:08:04,270 [Φοιτητής] Μπορείτε να μας πείτε περισσότερα για το σωρό; 93 00:08:04,270 --> 00:08:06,180 Ναι. Θα φτάσουμε σε αυτό σε ένα δευτερόλεπτο. 94 00:08:06,180 --> 00:08:12,220 Κατ 'αρχάς, πρόκειται να επιστρέψει πίσω γιατί & y είναι ένα κακό πράγμα, 95 00:08:12,220 --> 00:08:18,470 στη στοίβα έχετε μια δέσμη των πλαισίων στοίβας που αντιπροσωπεύουν όλες τις λειτουργίες 96 00:08:18,470 --> 00:08:20,460 που έχουν κληθεί. 97 00:08:20,460 --> 00:08:27,990 Έτσι, αγνοώντας προηγούμενες πράγματα, η κορυφή της στοίβας σας είναι πάντα θα είναι η κύρια λειτουργία 98 00:08:27,990 --> 00:08:33,090 δεδομένου ότι είναι η πρώτη λειτουργία που είναι να ονομάζεται. 99 00:08:33,090 --> 00:08:37,130 Και στη συνέχεια, όταν σας καλούν άλλη λειτουργία, η στοίβα θα αυξηθεί προς τα κάτω. 100 00:08:37,130 --> 00:08:41,640 Έτσι, αν καλώ κάποια λειτουργία, foo, και παίρνει το δικό του πλαίσιο της στοίβας, 101 00:08:41,640 --> 00:08:47,280 μπορεί να καλέσει κάποια λειτουργία, μπαρ? παίρνει το δικό του πλαίσιο στοίβας του. 102 00:08:47,280 --> 00:08:49,840 Και γραμμή θα μπορούσε να είναι αναδρομική και θα μπορούσε να ζητήσει η ίδια, 103 00:08:49,840 --> 00:08:54,150 και έτσι ώστε δεύτερη κλήση στη γραμμή πρόκειται να πάρει το δικό του πλαίσιο στοίβας του. 104 00:08:54,150 --> 00:08:58,880 Και έτσι ό, τι συμβαίνει σε αυτά τα πλαίσια είναι στοίβα όλες τις τοπικές μεταβλητές 105 00:08:58,880 --> 00:09:03,450 και όλα τα ορίσματα της συνάρτησης ότι - 106 00:09:03,450 --> 00:09:08,730 Οποιαδήποτε πράγματα που είναι τοπικά scoped να πάει αυτή τη λειτουργία σε αυτά τα πλαίσια στοίβα. 107 00:09:08,730 --> 00:09:21,520 Έτσι, αυτό σημαίνει ότι όταν είπα κάτι σαν μπαρ είναι μια λειτουργία, 108 00:09:21,520 --> 00:09:29,270 Είμαι ακριβώς πρόκειται να δηλώσει έναν ακέραιο αριθμό και στη συνέχεια να επιστρέψει ένα δείκτη σε ακέραιο αυτό. 109 00:09:29,270 --> 00:09:33,790 Έτσι, όταν κάνει y ζει; 110 00:09:33,790 --> 00:09:36,900 [Φοιτητής] y ζει στο μπαρ. >> [Bowden] Ναι. 111 00:09:36,900 --> 00:09:45,010 Κάπου σε αυτή τη μικρή πλατεία της μνήμης είναι ένα τετράγωνο που έχει littler y σε αυτό. 112 00:09:45,010 --> 00:09:53,370 Όταν επιστρέψω & y, είμαι επιστροφή ενός δείκτη σε αυτό το μικρό μπλοκ της μνήμης. 113 00:09:53,370 --> 00:09:58,400 Στη συνέχεια, όμως, όταν επιστρέφει μια συνάρτηση, το πλαίσιο της στοίβας παίρνει έσκασε από τη στοίβα. 114 00:10:01,050 --> 00:10:03,530 Και αυτός είναι ο λόγος που ονομάζεται στοίβα. 115 00:10:03,530 --> 00:10:06,570 Είναι σαν τη δομή δεδομένων στοίβας, αν γνωρίζετε τι είναι αυτό. 116 00:10:06,570 --> 00:10:11,580 Ή ακόμα και σαν μια στοίβα των δίσκων είναι πάντα το παράδειγμα, 117 00:10:11,580 --> 00:10:16,060 κύριες πρόκειται να πάει στον πάτο, τότε η πρώτη λειτουργία που θα καλέσετε για να πάει στην κορυφή του ότι, 118 00:10:16,060 --> 00:10:20,400 και δεν μπορείτε να πάρετε πίσω στην κύρια μέχρι να επιστρέψει από όλες τις λειτουργίες που έχουν κληθεί 119 00:10:20,400 --> 00:10:22,340 που έχουν τοποθετηθεί πάνω του. 120 00:10:22,340 --> 00:10:28,650 >> [Φοιτητής] Έτσι, αν το κάνετε επιστρέψετε το & y, ότι η τιμή μπορεί να αλλάξουν χωρίς προειδοποίηση. 121 00:10:28,650 --> 00:10:31,290 Ναι, it's - >> [φοιτητής] Θα μπορούσε να αντικατασταθεί. Ναι >>. 122 00:10:31,290 --> 00:10:34,660 Είναι εντελώς - Αν προσπαθήσετε και - 123 00:10:34,660 --> 00:10:38,040 Αυτό θα ήταν επίσης ένα μπαρ int * γιατί είναι επιστρέφοντας ένα δείκτη, 124 00:10:38,040 --> 00:10:41,310 έτσι τον τύπο της επιστροφής είναι int *. 125 00:10:41,310 --> 00:10:46,500 Εάν προσπαθήσετε να χρησιμοποιήσετε την τιμή επιστροφής της συνάρτησης, είναι απροσδιόριστη συμπεριφορά 126 00:10:46,500 --> 00:10:51,770 επειδή ότι ο δείκτης δείχνει σε κακή μνήμη. >> [Φοιτητής] Εντάξει. 127 00:10:51,770 --> 00:11:01,250 Τι κι αν, για παράδειγμα, έχετε δηλώσει int * y = malloc (sizeof (int)); 128 00:11:01,250 --> 00:11:03,740 Αυτό είναι καλύτερο. Ναι. 129 00:11:03,740 --> 00:11:07,730 [Φοιτητής] Μιλήσαμε για το πώς όταν σύρετε τα πράγματα σε κάδο ανακύκλωσης μας 130 00:11:07,730 --> 00:11:11,750 δεν είστε πραγματικά διαγράφονται? χάνουμε μόνο τους δείκτες. 131 00:11:11,750 --> 00:11:15,550 Έτσι, σε αυτή την περίπτωση δεν θα διαγράψει πραγματικά την αξία ή είναι ακόμα εκεί στη μνήμη; 132 00:11:15,550 --> 00:11:19,130 Για το μεγαλύτερο μέρος, αυτό πρόκειται να είναι ακόμα εκεί. 133 00:11:19,130 --> 00:11:24,220 Αλλά ας πούμε ότι τυχαίνει να καλέσει κάποια άλλη λειτουργία, baz. 134 00:11:24,220 --> 00:11:28,990 Baz πρόκειται να πάρει το δικό του πλαίσιο στοίβας του εδώ. 135 00:11:28,990 --> 00:11:31,470 Είναι πρόκειται να αντικαταστήσετε όλα αυτά τα πράγματα, 136 00:11:31,470 --> 00:11:34,180 και στη συνέχεια, αν αργότερα δοκιμάσετε και να χρησιμοποιήσετε το δείκτη που πήρατε πριν, 137 00:11:34,180 --> 00:11:35,570 δεν πρόκειται να είναι η ίδια αξία. 138 00:11:35,570 --> 00:11:38,150 Είναι πρόκειται να έχουν αλλάξει μόνο και μόνο επειδή σας ονομάζεται baz λειτουργία. 139 00:11:38,150 --> 00:11:43,080 [Μαθητής] Αλλά δεν είχαμε, θα έχουμε ακόμα 3; 140 00:11:43,080 --> 00:11:44,990 [Bowden] Κατά πάσα πιθανότητα, θα κάνατε. 141 00:11:44,990 --> 00:11:49,670 Αλλά δεν μπορείτε να βασιστείτε σε αυτό. Γ λέει μόνο απροσδιόριστη συμπεριφορά. 142 00:11:49,670 --> 00:11:51,920 >> [Φοιτητής] Ω, ναι. Εντάξει. 143 00:11:51,920 --> 00:11:58,190 Έτσι, όταν θέλετε να επιστρέψετε ένα δείκτη, αυτό είναι όπου malloc έρχεται σε χρήση. 144 00:12:00,930 --> 00:12:15,960 Γράφω πραγματικά επιστρέψει μόλις malloc (3 * sizeof (int)). 145 00:12:17,360 --> 00:12:24,050 Θα πάμε πάνω από malloc περισσότερο σε ένα δεύτερο, αλλά η ιδέα της malloc είναι το σύνολο των τοπικών μεταβλητών σας 146 00:12:24,050 --> 00:12:26,760 πάντα να πάτε στη στοίβα. 147 00:12:26,760 --> 00:12:31,570 Οτιδήποτε είναι malloced πηγαίνει στο σωρό, και θα είναι για πάντα και πάντα να είναι στο σωρό 148 00:12:31,570 --> 00:12:34,490 μέχρι να ελευθερώσετε ρητά. 149 00:12:34,490 --> 00:12:42,130 Έτσι, αυτό σημαίνει ότι όταν malloc κάτι, πρόκειται να επιβιώσει μετά την επιστροφή της λειτουργίας. 150 00:12:42,130 --> 00:12:46,800 [Φοιτητής] Θα επιβιώσει μετά το πρόγραμμα σταματάει; Όχι >> 151 00:12:46,800 --> 00:12:53,180 Εντάξει, γι 'αυτό πρόκειται να είναι εκεί μέχρι το πρόγραμμα είναι όλος ο τρόπος λειτουργίας γίνεται. Ναι >>. 152 00:12:53,180 --> 00:12:57,510 Μπορούμε να πάμε για τις λεπτομέρειες του τι συμβαίνει όταν το πρόγραμμα σταματάει. 153 00:12:57,510 --> 00:13:02,150 Ίσως χρειαστεί να μου θυμίζουν, αλλά ότι είναι ένα ξεχωριστό πράγμα εντελώς. 154 00:13:02,150 --> 00:13:04,190 [Φοιτητής] Έτσι malloc δημιουργεί ένα δείκτη; Ναι >>. 155 00:13:04,190 --> 00:13:13,030 Malloc - >> [φοιτητής] Νομίζω malloc ορίζει ένα μπλοκ μνήμης που ένας δείκτης μπορεί να χρησιμοποιήσει. 156 00:13:15,400 --> 00:13:19,610 [Bowden] θέλω αυτό το διάγραμμα πάλι. >> [Φοιτητής] Έτσι, η λειτουργία αυτή δουλεύει, όμως; 157 00:13:19,610 --> 00:13:26,430 [Φοιτητής] Ναι, malloc ορίζει ένα μπλοκ μνήμης που μπορείτε να χρησιμοποιήσετε, 158 00:13:26,430 --> 00:13:30,470 και τότε επιστρέφει την διεύθυνση του πρώτου μπλοκ του εν λόγω μνήμης. 159 00:13:30,470 --> 00:13:36,750 >> [Bowden] Ναι. Έτσι, όταν malloc, είστε αρπάζοντας κάποια μπλοκ της μνήμης 160 00:13:36,750 --> 00:13:38,260 αυτό είναι σήμερα στο σωρό. 161 00:13:38,260 --> 00:13:43,040 Εάν ο σωρός είναι πολύ μικρή, τότε ο σωρός είναι ακριβώς πρόκειται να αναπτυχθούν, και αναπτύσσεται προς την κατεύθυνση αυτή. 162 00:13:43,040 --> 00:13:44,650 Ας πούμε ότι ο σωρός είναι πολύ μικρή. 163 00:13:44,650 --> 00:13:49,960 Στη συνέχεια, αυτό είναι για να αυξηθεί λίγο και να επιστρέψει ένα δείκτη σε αυτό το μπλοκ που μόλις μεγάλωσε. 164 00:13:49,960 --> 00:13:55,130 Όταν δωρεάν πράγματα, θέλετε να κάνετε περισσότερο χώρο στο σωρό, 165 00:13:55,130 --> 00:14:00,030 έτσι τότε καλέστε αργότερα να μπορούν να επαναχρησιμοποιηθούν malloc ότι η μνήμη που είχατε προηγουμένως απελευθέρωσε. 166 00:14:00,030 --> 00:14:09,950 Το σημαντικό πράγμα για malloc και δωρεάν είναι ότι σας δίνει τον πλήρη έλεγχο 167 00:14:09,950 --> 00:14:12,700 κατά τη διάρκεια αυτών των μπλοκ μνήμης. 168 00:14:12,700 --> 00:14:15,420 Οι καθολικές μεταβλητές είναι πάντα ζωντανός. 169 00:14:15,420 --> 00:14:18,500 Οι τοπικές μεταβλητές είναι ζωντανοί στο πεδίο εφαρμογής τους. 170 00:14:18,500 --> 00:14:22,140 Μόλις περάσετε ένα στήριγμα σγουρά, οι τοπικές μεταβλητές είναι νεκροί. 171 00:14:22,140 --> 00:14:28,890 Malloced μνήμη είναι ζωντανή, όταν θέλετε να είναι ζωντανός 172 00:14:28,890 --> 00:14:33,480 και στη συνέχεια απελευθερώνεται όταν το πείτε να κυκλοφορήσει. 173 00:14:33,480 --> 00:14:38,420 Αυτά είναι πραγματικά τα μόνα 3 τύπους μνήμης, πραγματικά. 174 00:14:38,420 --> 00:14:41,840 Υπάρχει αυτόματη διαχείριση μνήμης, η οποία είναι η στοίβα. 175 00:14:41,840 --> 00:14:43,840 Πράγματα συμβαίνουν για σας αυτόματα. 176 00:14:43,840 --> 00:14:46,910 Όταν λέτε int x, μνήμη για int x. 177 00:14:46,910 --> 00:14:51,630 Όταν x βγαίνει από το πεδίο εφαρμογής, τη μνήμη ανακτάται για x. 178 00:14:51,630 --> 00:14:54,790 Στη συνέχεια, υπάρχει δυναμική διαχείριση μνήμης, η οποία είναι ό, τι είναι malloc, 179 00:14:54,790 --> 00:14:56,740 η οποία είναι όταν έχετε τον έλεγχο. 180 00:14:56,740 --> 00:15:01,290 Μπορείτε δυναμικά μνήμη αποφασίσει πότε πρέπει και δεν θα πρέπει να διατεθούν. 181 00:15:01,290 --> 00:15:05,050 Και έπειτα υπάρχει στατική, πράγμα που σημαίνει απλώς ότι ζει για πάντα, 182 00:15:05,050 --> 00:15:06,610 η οποία είναι ό, τι είναι καθολικές μεταβλητές. 183 00:15:06,610 --> 00:15:10,240 Είναι απλά πάντα στη μνήμη. 184 00:15:10,960 --> 00:15:12,760 >> Ερωτήσεις; 185 00:15:14,490 --> 00:15:17,230 [Φοιτητής] Μπορείτε να ορίσετε ένα μπλοκ μόνο με τη χρήση άγκιστρα 186 00:15:17,230 --> 00:15:21,220 αλλά δεν χρειάζεται να έχει μια δήλωση ή αν μια δήλωση, ενώ ή κάτι τέτοιο; 187 00:15:21,220 --> 00:15:29,130 Μπορείτε να ορίσετε ένα μπλοκ, όπως σε μια λειτουργία, αλλά ότι έχει άγκιστρα πάρα πολύ. 188 00:15:29,130 --> 00:15:32,100 [Φοιτητής] Έτσι, μπορείτε όχι μόνο να έχει σαν ένα τυχαίο ζευγάρι αγκύλες στον κώδικά σας 189 00:15:32,100 --> 00:15:35,680 που έχουν τοπικές μεταβλητές; >> Ναι, μπορείτε. 190 00:15:35,680 --> 00:15:45,900 Μέσα από int bar θα μπορούσαμε να έχουμε {int y = 3?}. 191 00:15:45,900 --> 00:15:48,440 Έτσι θεωρείται ότι είναι ακριβώς εδώ. 192 00:15:48,440 --> 00:15:52,450 Αλλά αυτό καθορίζει πλήρως το πεδίο της int y. 193 00:15:52,450 --> 00:15:57,320 Μετά από αυτό το δεύτερο στήριγμα σγουρά, y δεν μπορεί να χρησιμοποιηθεί πλέον. 194 00:15:57,910 --> 00:16:00,630 Μπορείτε σχεδόν ποτέ δεν το κάνουμε αυτό, όμως. 195 00:16:02,940 --> 00:16:07,370 Να πάρει πίσω ό, τι συμβαίνει όταν ένα πρόγραμμα τελειώνει, 196 00:16:07,370 --> 00:16:18,760 υπάρχει το είδος της ένα ψέμα παρανόηση / half που δίνουμε για να κάνει τα πράγματα λίγο πιο εύκολη. 197 00:16:18,760 --> 00:16:24,410 Θα σας πω ότι όταν διαθέτουν μνήμη 198 00:16:24,410 --> 00:16:29,860 είστε κατανομή κάποιο κομμάτι της μνήμης RAM για τη συγκεκριμένη μεταβλητή. 199 00:16:29,860 --> 00:16:34,190 Αλλά δεν είστε πραγματικά αγγίζει άμεσα RAM ποτέ μέσα στα προγράμματά σας. 200 00:16:34,190 --> 00:16:37,490 Αν νομίζετε ότι από αυτό, πώς επέστησε - 201 00:16:37,490 --> 00:16:44,330 Και στην πραγματικότητα, αν περάσει στο GDB θα δείτε το ίδιο πράγμα. 202 00:16:51,120 --> 00:16:57,590 Ανεξάρτητα από το πόσες φορές θα τρέξει το πρόγραμμά σας ή τι πρόγραμμα τρέχετε, 203 00:16:57,590 --> 00:16:59,950 η στοίβα είναι πάντα πρόκειται να ξεκινήσει - 204 00:16:59,950 --> 00:17:06,510 είστε πάντα πρόκειται να δούμε τις μεταβλητές γύρω από κάτι oxbffff διεύθυνση. 205 00:17:06,510 --> 00:17:09,470 Είναι συνήθως κάπου στην περιοχή αυτή. 206 00:17:09,470 --> 00:17:18,760 Αλλά πώς μπορεί 2 προγράμματα έχουν ενδεχομένως δείκτες για την ίδια μνήμη; 207 00:17:20,640 --> 00:17:27,650 [Φοιτητής] Υπάρχει κάποια αυθαίρετη ονομασία oxbfff όπου υποτίθεται ότι είναι για τη μνήμη RAM 208 00:17:27,650 --> 00:17:31,320 που μπορεί πραγματικά να είναι σε διαφορετικές θέσεις ανάλογα με το πότε η συνάρτηση κλήθηκε. 209 00:17:31,320 --> 00:17:35,920 Ναι. Ο όρος είναι εικονική μνήμη. 210 00:17:35,920 --> 00:17:42,250 Η ιδέα είναι ότι κάθε διαδικασία, κάθε πρόγραμμα που εκτελείται στον υπολογιστή σας 211 00:17:42,250 --> 00:17:49,450 έχει τη δική του - ας υποθέσουμε 32 bit - εντελώς ανεξάρτητο χώρο διευθύνσεων. 212 00:17:49,450 --> 00:17:51,590 Αυτό είναι ο χώρος διευθύνσεων. 213 00:17:51,590 --> 00:17:56,220 Έχει τη δική του εντελώς ανεξάρτητη 4 gigabytes του να χρησιμοποιήσει. 214 00:17:56,220 --> 00:18:02,220 >> Έτσι, αν έχετε τρέξει 2 προγράμματα ταυτόχρονα, το πρόγραμμα αυτό βλέπει 4 gigabyte στον εαυτό του, 215 00:18:02,220 --> 00:18:04,870 αυτό το πρόγραμμα βλέπει 4 gigabyte στον εαυτό του, 216 00:18:04,870 --> 00:18:07,720 και είναι αδύνατο για αυτό το πρόγραμμα για να dereference ένας δείκτης 217 00:18:07,720 --> 00:18:10,920 και να καταλήξουμε με τη μνήμη από αυτό το πρόγραμμα. 218 00:18:10,920 --> 00:18:18,200 Και ποια είναι η εικονική μνήμη είναι μια χαρτογράφηση από ένα χώρο διευθύνσεων διαδικασίες 219 00:18:18,200 --> 00:18:20,470 με τις πραγματικές πράγματα για RAM. 220 00:18:20,470 --> 00:18:22,940 Έτσι είναι μέχρι και το λειτουργικό σας σύστημα για να γνωρίζουμε ότι, 221 00:18:22,940 --> 00:18:28,080 hey, όταν αυτός ο τύπος oxbfff δείκτη dereferences, που πραγματικά σημαίνει 222 00:18:28,080 --> 00:18:31,040 ότι θέλει RAM byte 1000, 223 00:18:31,040 --> 00:18:38,150 ενώ αν αυτό το πρόγραμμα dereferences oxbfff, θέλει πραγματικά RAM byte 10000. 224 00:18:38,150 --> 00:18:41,590 Μπορούν να είναι αυθαίρετα μακριά. 225 00:18:41,590 --> 00:18:48,730 Αυτό ισχύει ακόμη και από τα πράγματα μέσα σε ένα ενιαίο χώρο διευθύνσεων διαδικασίες. 226 00:18:48,730 --> 00:18:54,770 Έτσι όπως βλέπει και τα 4 gigabytes στον εαυτό του, αλλά ας πούμε - 227 00:18:54,770 --> 00:18:57,290 [Φοιτητής] Μήπως κάθε ενιαία διαδικασία - 228 00:18:57,290 --> 00:19:01,350 Ας πούμε ότι έχετε ένα υπολογιστή με μόνο 4 gigabytes μνήμης RAM. 229 00:19:01,350 --> 00:19:06,430 Μήπως κάθε διαδικασία δείτε το σύνολο των 4 gigabyte; Ναι >>. 230 00:19:06,430 --> 00:19:13,060 Αλλά τα 4 gigabytes που βλέπει είναι ένα ψέμα. 231 00:19:13,060 --> 00:19:20,460 Είναι ακριβώς νομίζει ότι έχει όλα αυτή τη μνήμη, επειδή δεν γνωρίζει οποιαδήποτε άλλη διαδικασία υπάρχει. 232 00:19:20,460 --> 00:19:28,140 Θα χρησιμοποιήσει μόνο όσο μνήμης που χρειάζεται πραγματικά. 233 00:19:28,140 --> 00:19:32,340 Το λειτουργικό σύστημα δεν πρόκειται να δώσει RAM σε αυτή τη διαδικασία 234 00:19:32,340 --> 00:19:35,750 αν είναι δεν χρησιμοποιούν καμία μνήμη σε όλη αυτή την περιοχή. 235 00:19:35,750 --> 00:19:39,300 Δεν πρόκειται να δώσει τη μνήμη για αυτή την περιοχή. 236 00:19:39,300 --> 00:19:54,780 Αλλά η ιδέα είναι ότι - προσπαθώ να σκεφτώ - δεν μπορώ να σκεφτώ μια αναλογία. 237 00:19:54,780 --> 00:19:56,780 Οι αναλογίες είναι δύσκολο. 238 00:19:57,740 --> 00:20:02,700 Ένα από τα θέματα της εικονικής μνήμης ή ένα από τα πράγματα που είναι επίλυση 239 00:20:02,700 --> 00:20:06,810 είναι ότι οι διαδικασίες θα πρέπει να είναι εντελώς απληροφόρητοι ένα από το άλλο. 240 00:20:06,810 --> 00:20:12,140 Και έτσι μπορείτε να γράψετε οποιοδήποτε πρόγραμμα που μόλις dereferences κάθε δείκτη, 241 00:20:12,140 --> 00:20:19,340 ακριβώς όπως γράψετε ένα πρόγραμμα που λέει * (ox1234), 242 00:20:19,340 --> 00:20:22,890 εύρεση τιμών διεύθυνση μνήμης και ότι το 1234. 243 00:20:22,890 --> 00:20:28,870 >> Αλλά είναι στο χέρι του λειτουργικού συστήματος για να μεταφράσει τότε τι σημαίνει 1234. 244 00:20:28,870 --> 00:20:33,960 Έτσι, αν συμβεί 1234 να είναι μια έγκυρη διεύθυνση μνήμης για τη διαδικασία αυτή, 245 00:20:33,960 --> 00:20:38,800 σαν να είναι στη στοίβα ή κάτι, τότε αυτό θα επιστρέψει την αξία του εν λόγω διεύθυνση μνήμης 246 00:20:38,800 --> 00:20:41,960 όσον αφορά τη διαδικασία γνωρίζει. 247 00:20:41,960 --> 00:20:47,520 Αλλά αν δεν είναι 1234 μια έγκυρη διεύθυνση, όπως συμβαίνει να προσγειωθεί 248 00:20:47,520 --> 00:20:52,910 σε κάποιο μικρό κομμάτι της μνήμης που είναι εδώ πέρα ​​από το σωρό και πέρα ​​από το σωρό 249 00:20:52,910 --> 00:20:57,200 και δεν έχετε πραγματικά ότι χρησιμοποιείται, στη συνέχεια, ότι όταν μπορείτε να πάρετε τα πράγματα όπως segfaults 250 00:20:57,200 --> 00:21:00,260 επειδή είστε αγγίζει μνήμη που δεν πρέπει να αγγίξει. 251 00:21:07,180 --> 00:21:09,340 Αυτό είναι επίσης αλήθεια - 252 00:21:09,340 --> 00:21:15,440 Ένα σύστημα 32-bit, 32 bit σημαίνει ότι έχετε 32 bit για να ορίσετε μια διεύθυνση μνήμης. 253 00:21:15,440 --> 00:21:22,970 Είναι γιατί δείκτες είναι 8 bytes, επειδή 32 bits είναι 8 bytes - ή 4 bytes. 254 00:21:22,970 --> 00:21:25,250 Οι δείκτες είναι 4 bytes. 255 00:21:25,250 --> 00:21:33,680 Έτσι, όταν βλέπετε ένα δείκτη, όπως oxbfffff, δηλαδή - 256 00:21:33,680 --> 00:21:40,080 Μέσα σε κάθε συγκεκριμένο πρόγραμμα μπορείτε να δημιουργήσετε ένα οποιοδήποτε αυθαίρετο δείκτη, 257 00:21:40,080 --> 00:21:46,330 οπουδήποτε από ox0 να βόδι 8 f's - ffffffff. 258 00:21:46,330 --> 00:21:49,180 [Φοιτητής] Μήπως δεν σας λένε ότι είναι 4 bytes; Ναι >>. 259 00:21:49,180 --> 00:21:52,730 [Φοιτητής] Στη συνέχεια, κάθε byte θα έχει - >> [Bowden] Δεκαεξαδικό. 260 00:21:52,730 --> 00:21:59,360 Δεκαεξαδικό - 5, 6, 7, 8. Έτσι δείκτες θα πάμε να δούμε πάντα σε δεκαεξαδικό. 261 00:21:59,360 --> 00:22:01,710 Είναι ακριβώς το πώς θα κατατάξει δείκτες. 262 00:22:01,710 --> 00:22:05,240 Κάθε 2 ψηφία του δεκαεξαδικού είναι 1 byte. 263 00:22:05,240 --> 00:22:09,600 Έτσι, υπάρχει μετάβαση να είναι 8 δεκαεξαδικά ψηφία για 4 bytes. 264 00:22:09,600 --> 00:22:14,190 Έτσι, κάθε δείκτη σε ένα σύστημα 32-bit θα είναι 4 bytes, 265 00:22:14,190 --> 00:22:18,550 πράγμα που σημαίνει ότι στη διαδικασία σας μπορείτε να δημιουργήσετε οποιαδήποτε αυθαίρετη 4 bytes 266 00:22:18,550 --> 00:22:20,550 και να κάνει ένα δείκτη έξω από αυτό, 267 00:22:20,550 --> 00:22:32,730 πράγμα που σημαίνει ότι όσο γνωρίζει, δεν μπορεί να αντιμετωπίσει μια ολόκληρη 2 στις 32 bytes μνήμης. 268 00:22:32,730 --> 00:22:34,760 Ακόμα κι αν δεν έχει πραγματικά πρόσβαση σε αυτό, 269 00:22:34,760 --> 00:22:40,190 ακόμη και αν ο υπολογιστής σας έχει μόνο 512 megabytes, νομίζει ότι έχει τόσο πολύ μνήμη. 270 00:22:40,190 --> 00:22:44,930 Και το λειτουργικό σύστημα είναι αρκετά έξυπνος ότι θα χορηγήσουν μόνο ό, τι πραγματικά χρειάζεται. 271 00:22:44,930 --> 00:22:49,630 Δεν πήγαινε, ω, μια νέα διαδικασία: 4 συναυλίες. 272 00:22:49,630 --> 00:22:51,930 >> Ναι. >> [Φοιτητής] Τι σημαίνει το βόδι; Γιατί να το γράψετε; 273 00:22:51,930 --> 00:22:54,980 Είναι ακριβώς το σύμβολο για δεκαεξαδική. 274 00:22:54,980 --> 00:22:59,590 Όταν δείτε ένα ξεκίνημα με αριθμό βόδι, οι διαδοχικές πράγματα είναι δεκαεξαδικό. 275 00:23:01,930 --> 00:23:05,760 [Φοιτητής] Ήσουν εξηγώντας για το τι συμβαίνει όταν ένα πρόγραμμα τελειώνει. Ναι >>. 276 00:23:05,760 --> 00:23:09,480 Τι συμβαίνει όταν ένα πρόγραμμα τελειώνει είναι το λειτουργικό σύστημα 277 00:23:09,480 --> 00:23:13,600 απλά διαγράφει τις αντιστοιχίσεις που έχει για αυτές τις διευθύνσεις, και αυτό είναι όλο. 278 00:23:13,600 --> 00:23:17,770 Το λειτουργικό σύστημα μπορεί να δώσει τώρα μόλις ότι η μνήμη σε ένα άλλο πρόγραμμα να χρησιμοποιήσει. 279 00:23:17,770 --> 00:23:19,490 [Φοιτητής] Εντάξει. 280 00:23:19,490 --> 00:23:24,800 Έτσι, όταν διαθέτουν κάτι για το σωρό ή στοίβα ή τις καθολικές μεταβλητές ή οτιδήποτε, 281 00:23:24,800 --> 00:23:27,010 όλοι απλά εξαφανίζονται μόλις τελειώσει το πρόγραμμα 282 00:23:27,010 --> 00:23:32,120 επειδή το λειτουργικό σύστημα είναι πλέον ελεύθερος να δοθούν σε αυτή την μνήμη σε οποιαδήποτε άλλη διαδικασία. 283 00:23:32,120 --> 00:23:35,150 [Φοιτητής] Ακόμα κι αν υπάρχουν πιθανώς ακόμα τιμές αναγράφονται σε; Ναι >>. 284 00:23:35,150 --> 00:23:37,740 Οι τιμές είναι πιθανό ακόμα εκεί. 285 00:23:37,740 --> 00:23:41,570 Είναι ακριβώς πρόκειται να είναι δύσκολο να πάρει σε αυτά. 286 00:23:41,570 --> 00:23:45,230 Είναι πολύ πιο δύσκολο να πάρει τους σε ό, τι είναι να πάρει σε ένα διαγραμμένο αρχείο 287 00:23:45,230 --> 00:23:51,450 επειδή η διαγραφή αρχείων από το είδος βρίσκεται εκεί για μεγάλο χρονικό διάστημα και ο σκληρός δίσκος είναι πολύ μεγαλύτερο. 288 00:23:51,450 --> 00:23:54,120 Έτσι πρόκειται να αντικαταστήσει διάφορα μέρη της μνήμης 289 00:23:54,120 --> 00:23:58,640 πριν αυτό συμβεί να αντικαταστήσετε το κομμάτι της μνήμης ότι ο φάκελος που χρησιμοποιείται για να είναι. 290 00:23:58,640 --> 00:24:04,520 Αλλά κύρια μνήμη, μνήμη RAM, θα τον κύκλο μέσα από μια πολύ πιο γρήγορα, 291 00:24:04,520 --> 00:24:08,040 έτσι πρόκειται να είναι πολύ γρήγορα να αντικατασταθούν. 292 00:24:10,300 --> 00:24:13,340 Ερωτήσεις για το θέμα αυτό ή κάτι άλλο; 293 00:24:13,340 --> 00:24:16,130 [Φοιτητής] Έχω ερωτήσεις σχετικά με ένα διαφορετικό θέμα. Εντάξει >>. 294 00:24:16,130 --> 00:24:19,060 Υπάρχει κάποιος που έχει ερωτήσεις σχετικά με αυτό; 295 00:24:20,170 --> 00:24:23,120 >> Εντάξει. Διαφορετικές θέμα. >> [Φοιτητής] Εντάξει. 296 00:24:23,120 --> 00:24:26,550 Πήγαινα σε μερικές από τις δοκιμές πρακτική, 297 00:24:26,550 --> 00:24:30,480 και σε ένα από αυτά ήταν μιλάμε για το sizeof 298 00:24:30,480 --> 00:24:35,630 και η τιμή που επιστρέφει ή διαφορετικούς τύπους μεταβλητών. Ναι >>. 299 00:24:35,630 --> 00:24:45,060 Και είπε ότι και οι δύο int και καιρό τόσο την επιστροφή 4, έτσι είναι και οι δύο μήκος 4 byte. 300 00:24:45,060 --> 00:24:48,070 Υπάρχει κάποια διαφορά μεταξύ int και ένα καιρό εκεί, ή είναι το ίδιο πράγμα; 301 00:24:48,070 --> 00:24:50,380 Ναι, υπάρχει μια διαφορά. 302 00:24:50,380 --> 00:24:52,960 Το πρότυπο C - 303 00:24:52,960 --> 00:24:54,950 Είμαι κατά πάσα πιθανότητα θα χαλάσουν. 304 00:24:54,950 --> 00:24:58,800 Το πρότυπο C είναι ακριβώς όπως αυτό είναι C, η επίσημη τεκμηρίωση του C. 305 00:24:58,800 --> 00:25:00,340 Αυτό είναι ό, τι λέει. 306 00:25:00,340 --> 00:25:08,650 Έτσι, η C πρότυπο λέει απλά ότι ένας char θα είναι για πάντα και πάντα να είναι 1 byte. 307 00:25:10,470 --> 00:25:19,040 Τα πάντα μετά από αυτό - μια σύντομη είναι πάντα ακριβώς ορίζεται ως μεγαλύτερη από ή ίση με ένα char. 308 00:25:19,040 --> 00:25:23,010 Αυτό μπορεί να είναι αυστηρά μεγαλύτερο από, αλλά όχι θετική. 309 00:25:23,010 --> 00:25:31,940 Μια int είναι ακριβώς ορίζεται ως μεγαλύτερη ή ίση με μια σύντομη. 310 00:25:31,940 --> 00:25:36,210 Και ένα μακρύ είναι ακριβώς ορίζεται ως μεγαλύτερη ή ίση με έναν int. 311 00:25:36,210 --> 00:25:41,600 Και ένα μακρύ χρονικό διάστημα είναι μεγαλύτερο από ή ίσο με ένα μακρύ. 312 00:25:41,600 --> 00:25:46,610 Έτσι, το μόνο πράγμα που η C είναι πρότυπο ορίζει η σχετική παραγγελία του τα πάντα. 313 00:25:46,610 --> 00:25:54,880 Το πραγματικό ποσό της μνήμης που καταλαμβάνουν τα πράγματα είναι γενικά μέχρι την υλοποίηση, 314 00:25:54,880 --> 00:25:57,640 αλλά είναι αρκετά καλά που ορίζονται σε αυτό το σημείο. >> [Φοιτητής] Εντάξει. 315 00:25:57,640 --> 00:26:02,490 Έτσι, σορτς είναι σχεδόν πάντα θα είναι 2 bytes. 316 00:26:04,920 --> 00:26:09,950 Ints είναι σχεδόν πάντα θα είναι 4 bytes. 317 00:26:12,070 --> 00:26:15,340 Long επιμήκη προϊόντα είναι σχεδόν πάντα θα είναι 8 bytes. 318 00:26:17,990 --> 00:26:23,160 Και longs, αυτό εξαρτάται από το αν είστε με τη χρήση 32-bit ή 64-bit σύστημα. 319 00:26:23,160 --> 00:26:27,450 Έτσι, ένα μακρύ πρόκειται να αντιστοιχεί με τον τύπο του συστήματος. 320 00:26:27,450 --> 00:26:31,920 Αν χρησιμοποιείτε ένα σύστημα 32-bit, όπως η συσκευή, πρόκειται να είναι 4 bytes. 321 00:26:34,530 --> 00:26:42,570 Εάν χρησιμοποιείτε μια έκδοση 64-bit σαν μια παρτίδα των πρόσφατων υπολογιστές, πρόκειται να είναι 8 bytes. 322 00:26:42,570 --> 00:26:45,230 >> Ints είναι σχεδόν πάντα 4 byte σε αυτό το σημείο. 323 00:26:45,230 --> 00:26:47,140 Long επιμήκη προϊόντα είναι σχεδόν πάντα 8 bytes. 324 00:26:47,140 --> 00:26:50,300 Στο παρελθόν, ints χρησιμοποιείται για να είναι μόνο 2 bytes. 325 00:26:50,300 --> 00:26:56,840 Αλλά παρατηρήσετε ότι αυτό ικανοποιεί πλήρως όλες αυτές τις σχέσεις και μεγαλύτερη από ό, τι ίσο με. 326 00:26:56,840 --> 00:27:01,280 Ενόσω είναι τέλεια επιτρέπεται να είναι το ίδιο μέγεθος με έναν ακέραιο αριθμό, 327 00:27:01,280 --> 00:27:04,030 και είναι επίσης επιτρέπεται να είναι το ίδιο μέγεθος με ένα μακρύ διάστημα. 328 00:27:04,030 --> 00:27:11,070 Και είναι ακριβώς έτσι συμβαίνει να είναι ότι το 99,999% των συστημάτων, που θα είναι ίσο με το 329 00:27:11,070 --> 00:27:15,800 είτε int ή πολύ μεγάλο χρονικό διάστημα. Εξαρτάται μόνο σε 32-bit ή 64-bit. >> [Φοιτητής] Εντάξει. 330 00:27:15,800 --> 00:27:24,600 Σε άρματα, πώς είναι το δεκαδικό σημείο που ορίζεται από την άποψη των bits; 331 00:27:24,600 --> 00:27:27,160 Όπως και το δυαδικό; Ναι >>. 332 00:27:27,160 --> 00:27:30,570 Δεν χρειάζεται να γνωρίζουν ότι για CS50. 333 00:27:30,570 --> 00:27:32,960 Δεν μαθαίνουν ότι ακόμα και σε 61. 334 00:27:32,960 --> 00:27:37,350 Δεν μαθαίνουν ότι πραγματικά σε κάθε μάθημα. 335 00:27:37,350 --> 00:27:42,740 Είναι απλά μια αναπαράσταση. 336 00:27:42,740 --> 00:27:45,440 Ξεχάσω τις ακριβείς διανομές λίγο. 337 00:27:45,440 --> 00:27:53,380 Η ιδέα της κινητής υποδιαστολής είναι ότι διαθέτουν ένα συγκεκριμένο αριθμό των bits να εκπροσωπεί - 338 00:27:53,380 --> 00:27:56,550 Βασικά, όλα είναι σε επιστημονική σημειογραφία. 339 00:27:56,550 --> 00:28:05,600 Έτσι, θα διαθέσει ένα συγκεκριμένο αριθμό των bits να εκπροσωπεί τον αριθμό τους, όπως το 1,2345. 340 00:28:05,600 --> 00:28:10,200 Ποτέ δεν μπορεί να αντιπροσωπεύει έναν αριθμό με περισσότερα ψηφία από 5. 341 00:28:12,200 --> 00:28:26,300 Στη συνέχεια, μπορείτε επίσης να διαθέτουν ένα συγκεκριμένο αριθμό bits έτσι ώστε να τείνει να είναι σαν 342 00:28:26,300 --> 00:28:32,810 μπορείτε να πάτε μόνο μέχρι ένα ορισμένο αριθμό, όπως αυτός είναι ο μεγαλύτερος εκθέτης που μπορείτε να έχετε, 343 00:28:32,810 --> 00:28:36,190 και μπορείτε να πάτε μόνο μέχρι ένα ορισμένο εκθέτη, 344 00:28:36,190 --> 00:28:38,770 όπως αυτό είναι το μικρότερο εκθέτη μπορείτε να έχετε. 345 00:28:38,770 --> 00:28:44,410 >> Δεν θυμάμαι τα ακριβή τρόπο bits ανατεθεί σε όλες αυτές τις αξίες, 346 00:28:44,410 --> 00:28:47,940 αλλά ένα ορισμένο αριθμό από bits είναι αφιερωμένο στην 1,2345, 347 00:28:47,940 --> 00:28:50,930 άλλο συγκεκριμένο αριθμό bits είναι αφιερωμένο στον εκθέτη, 348 00:28:50,930 --> 00:28:55,670 και αυτό είναι μόνο δυνατό να αποτελούν εκθέτης ενός ορισμένου μεγέθους. 349 00:28:55,670 --> 00:29:01,100 [Φοιτητής] Και ένα διπλό; Είναι αυτό σαν ένα πολύ μακρύ float; Ναι >>. 350 00:29:01,100 --> 00:29:07,940 Είναι το ίδιο πράγμα με ένα άρμα, εκτός από τώρα είστε με τη χρήση 8 byte αντί των 4 byte. 351 00:29:07,940 --> 00:29:11,960 Τώρα θα είστε σε θέση να χρησιμοποιήσει 9 ψηφία ή 10 ψηφία, 352 00:29:11,960 --> 00:29:16,630 και αυτό θα είναι σε θέση να πάει μέχρι και 300 αντί για 100. >> [Φοιτητής] Εντάξει. 353 00:29:16,630 --> 00:29:21,550 Και είναι επίσης επιπλέει 4 bytes. Ναι >>. 354 00:29:21,550 --> 00:29:27,520 Λοιπόν, και πάλι, αυτό εξαρτάται από τη συνολική πιθανώς για γενική εφαρμογή, 355 00:29:27,520 --> 00:29:30,610 επιπλέει αλλά είναι 4 bytes, δίκλινα είναι 8. 356 00:29:30,610 --> 00:29:33,440 Διπλό καλούνται διπλό επειδή είναι διπλάσιο από το μέγεθος των αρμάτων. 357 00:29:33,440 --> 00:29:38,380 [Φοιτητής] Εντάξει. Και υπάρχουν διπλασιάζει διπλό; >> Δεν υπάρχουν. 358 00:29:38,380 --> 00:29:43,660 Νομίζω - >> [φοιτητής] Σας αρέσει το μεγάλο επιμήκη προϊόντα; Ναι >>. Δε νομίζω. Ναι. 359 00:29:43,660 --> 00:29:45,950 [Φοιτητής] Στις δοκιμή του περασμένου έτους υπήρξε μια ερώτηση σχετικά με την κύρια λειτουργία 360 00:29:45,950 --> 00:29:49,490 χρειάζεται να είναι μέρος του προγράμματός σας. 361 00:29:49,490 --> 00:29:52,310 Η απάντηση ήταν ότι δεν πρέπει να είναι μέρος του προγράμματός σας. 362 00:29:52,310 --> 00:29:55,100 Σε τι κατάσταση; Αυτό είναι ό, τι είδα. 363 00:29:55,100 --> 00:29:59,090 [Bowden] Φαίνεται - >> [φοιτητής] Τι κατάσταση; 364 00:29:59,090 --> 00:30:02,880 Έχετε το πρόβλημα; >> [Φοιτητής] Ναι, μπορώ να τραβήξει σίγουρα επάνω. 365 00:30:02,880 --> 00:30:07,910 Δεν πρέπει να είναι, από τεχνική άποψη, αλλά βασικά πρόκειται να είναι. 366 00:30:07,910 --> 00:30:10,030 [Φοιτητής] είδα ένα σε διαφορετικό έτος. 367 00:30:10,030 --> 00:30:16,220 Ήταν σαν Σωστό ή Λάθος: Ένα έγκυρο - >> Ω, ένα αρχείο c.; 368 00:30:16,220 --> 00:30:18,790 . [Φοιτητής] Κάθε αρχείο πρέπει να έχει γ - [και οι δύο μιλούν ταυτόχρονα - ακατάληπτο] 369 00:30:18,790 --> 00:30:21,120 Εντάξει. Έτσι, αυτό είναι ξεχωριστό. 370 00:30:21,120 --> 00:30:26,800 >> Ένα αρχείο. Γ πρέπει απλά να περιέχει λειτουργίες. 371 00:30:26,800 --> 00:30:32,400 Μπορείτε να μεταγλωττίσετε ένα αρχείο σε κώδικα μηχανής, δυαδική, οτιδήποτε, 372 00:30:32,400 --> 00:30:36,620 χωρίς να είναι εκτελέσιμο ακόμα. 373 00:30:36,620 --> 00:30:39,420 Ένα έγκυρο εκτελέσιμο αρχείο πρέπει να έχει μια κύρια λειτουργία. 374 00:30:39,420 --> 00:30:45,460 Μπορείτε να γράψετε το 100 λειτουργεί σε 1 αρχείο, αλλά δεν κύριο 375 00:30:45,460 --> 00:30:48,800 και στη συνέχεια να μεταγλωττίσετε ότι κάτω στο δυαδικό, 376 00:30:48,800 --> 00:30:54,460 τότε μπορείτε να γράψετε ένα άλλο αρχείο που έχει μόνο κύριο, αλλά απαιτεί ένα σωρό από αυτές τις λειτουργίες 377 00:30:54,460 --> 00:30:56,720 σε αυτό το δυαδικό αρχείο εδώ. 378 00:30:56,720 --> 00:31:01,240 Και έτσι, όταν κάνεις το εκτελέσιμο, αυτό είναι που κάνει ο σύνδεσμος 379 00:31:01,240 --> 00:31:05,960 είναι αυτό που συνδυάζει αυτά τα 2 δυαδικά αρχεία σε ένα εκτελέσιμο αρχείο. 380 00:31:05,960 --> 00:31:11,400 Έτσι, ένα αρχείο. Γ. δεν πρέπει να έχουν μια βασική λειτουργία σε όλα. 381 00:31:11,400 --> 00:31:19,220 Και σε μεγάλες βάσεις κώδικα θα δείτε χιλιάδες αρχεία. Γ και 1 κύριο αρχείο. 382 00:31:23,960 --> 00:31:26,110 Περισσότερες ερωτήσεις; 383 00:31:29,310 --> 00:31:31,940 [Φοιτητής] Υπήρχε ένα άλλο ζήτημα. 384 00:31:31,940 --> 00:31:36,710 Είπε να είναι ένα μεταγλωττιστή. Σωστό ή Λάθος; 385 00:31:36,710 --> 00:31:42,030 Και η απάντηση ήταν ψευδείς, και κατάλαβα γιατί δεν είναι σαν Clang. 386 00:31:42,030 --> 00:31:44,770 Αλλά τι να λέμε, αν δεν είναι; 387 00:31:44,770 --> 00:31:49,990 Κάνετε είναι βασικά ακριβώς - Μπορώ να δω ακριβώς τι ζητά. 388 00:31:49,990 --> 00:31:52,410 Αλλά λειτουργεί μόνο εντολές. 389 00:31:53,650 --> 00:31:55,650 Κάνετε. 390 00:31:58,240 --> 00:32:00,870 Μπορώ να τραβήξει αυτό επάνω. Ναι. 391 00:32:10,110 --> 00:32:13,180 Ω, ναι. Βεβαιωθείτε επίσης ότι κάνει. 392 00:32:13,180 --> 00:32:17,170 Αυτό λέει ο σκοπός της χρησιμότητας κάνουν είναι να προσδιορίσει αυτόματα 393 00:32:17,170 --> 00:32:19,610 ποια κομμάτια ενός μεγάλου προγράμματος θα πρέπει να αναθεωρείται 394 00:32:19,610 --> 00:32:22,350 και εκδίδει τις εντολές για να μεταγλωττίσετε τους. 395 00:32:22,350 --> 00:32:27,690 Μπορείτε να κάνετε τα αρχεία που είναι απολύτως τεράστια. 396 00:32:27,690 --> 00:32:33,210 Κάντε εξετάζει τις σφραγίδες του χρόνου και των αρχείων, όπως είπαμε πριν, 397 00:32:33,210 --> 00:32:36,930 μπορείτε να συντάξετε μεμονωμένα αρχεία κάτω, και δεν είναι μέχρι να φτάσετε στο συνδετήρα 398 00:32:36,930 --> 00:32:39,270 ότι από όπου και αν βάλει μαζί σε ένα εκτελέσιμο αρχείο. 399 00:32:39,270 --> 00:32:43,810 Έτσι, αν έχετε 10 διαφορετικά αρχεία και να κάνετε μια αλλαγή σε 1 από αυτά, 400 00:32:43,810 --> 00:32:47,870 τότε τι μάρκα πρόκειται να κάνει είναι απλά recompile ότι 1 αρχείο 401 00:32:47,870 --> 00:32:50,640 και επανασύνδεση τότε τα πάντα μαζί. 402 00:32:50,640 --> 00:32:53,020 Αλλά είναι πολύ dumber από αυτό. 403 00:32:53,020 --> 00:32:55,690 Είναι στο χέρι σας να καθορίσει πλήρως ότι αυτό είναι ό, τι θα έπρεπε να κάνει. 404 00:32:55,690 --> 00:32:59,560 Είναι εξ ορισμού έχει την ικανότητα να αναγνωρίζουν αυτά τα πράγματα σφραγίδα του χρόνου, 405 00:32:59,560 --> 00:33:03,220 αλλά μπορείτε να γράψετε ένα αρχείο μάρκα να κάνει τίποτα. 406 00:33:03,220 --> 00:33:09,150 Μπορείτε να γράψετε ένα αρχείο κάνουν έτσι ώστε όταν πληκτρολογείτε κάνει μόνο cd σε άλλο κατάλογο. 407 00:33:09,150 --> 00:33:15,560 Είχα πάρει απογοητευμένοι γιατί πάντα καρφί στο εσωτερικό της συσκευής μου 408 00:33:15,560 --> 00:33:21,740 και τότε θα δείτε το PDF από το Mac. 409 00:33:21,740 --> 00:33:30,720 >> Γι 'αυτό πηγαίνετε στο Finder και μπορώ να κάνω Go, Σύνδεση στο διακομιστή, 410 00:33:30,720 --> 00:33:36,950 και ο server θα συνδεθεί με συσκευή μου είναι, και στη συνέχεια θα ανοίξει το PDF 411 00:33:36,950 --> 00:33:40,190 που παίρνει συγκεντρώθηκαν από LaTeX. 412 00:33:40,190 --> 00:33:49,320 Αλλά είχα πάρει απογοητευμένοι γιατί κάθε φορά που χρειάζεται για να ανανεώσετε το PDF, 413 00:33:49,320 --> 00:33:53,900 Έπρεπε να το αντιγράψετε σε ένα συγκεκριμένο κατάλογο που θα μπορούσαν να έχουν πρόσβαση 414 00:33:53,900 --> 00:33:57,710 και είχε πάρει ενοχλητικό. 415 00:33:57,710 --> 00:34:02,650 Έτσι, αντί έγραψα ένα αρχείο μάρκα, τα οποία θα πρέπει να ορίσετε τον τρόπο αυτό καθιστά τα πράγματα. 416 00:34:02,650 --> 00:34:06,130 Πώς να κάνετε σε αυτό είναι PDF LaTeX. 417 00:34:06,130 --> 00:34:10,090 Ακριβώς όπως και κάθε άλλο αρχείο make - ή υποθέτω ότι δεν έχετε δει τα αρχεία μάρκα, 418 00:34:10,090 --> 00:34:13,510 αλλά έχουμε στη συσκευή ένα παγκόσμιο αρχείο μάρκα που απλά λέει, 419 00:34:13,510 --> 00:34:16,679 αν τη συγκρότηση του φακέλου C, χρησιμοποιήστε Clang. 420 00:34:16,679 --> 00:34:20,960 Και έτσι εδώ σε αρχείο μάρκα μου ότι κάνω λέω, 421 00:34:20,960 --> 00:34:25,020 αυτό το αρχείο που πρόκειται να θέλουν να συγκεντρώσει με PDF LaTeX. 422 00:34:25,020 --> 00:34:27,889 Και γι 'αυτό είναι PDF LaTeX που κάνει το compiling. 423 00:34:27,889 --> 00:34:31,880 Κάντε την κατάρτιση δεν είναι. Είναι τρέχει μόνο αυτές τις εντολές με τη σειρά που αναφέρονται. 424 00:34:31,880 --> 00:34:36,110 Γι 'αυτό τρέχει PDF LaTeX, το αντιγράφει στον κατάλογο θέλω να αντιγραφεί, 425 00:34:36,110 --> 00:34:38,270 το cd του στον κατάλογο και να κάνει άλλα πράγματα, 426 00:34:38,270 --> 00:34:42,380 αλλά το μόνο που κάνει είναι να αναγνωρίσουν πότε ένα αρχείο αλλάζει, 427 00:34:42,380 --> 00:34:45,489 και αν αλλάζει, τότε θα εκτελέσετε τις εντολές που είναι υποτίθεται για να τρέξει 428 00:34:45,489 --> 00:34:48,760 όταν οι αλλαγές στο αρχείο. >> [Φοιτητής] Εντάξει. 429 00:34:50,510 --> 00:34:54,420 Δεν ξέρω όπου τα παγκόσμια αρχεία μάρκα είναι για μένα για να το ελέγξουμε. 430 00:34:57,210 --> 00:35:04,290 Άλλες ερωτήσεις; Τίποτα από το παρελθόν κουίζ; Οποιαδήποτε πράγματα δείκτη; 431 00:35:06,200 --> 00:35:08,730 Υπάρχουν λεπτές πράγματα με δείκτες όπως - 432 00:35:08,730 --> 00:35:10,220 Είμαι δεν πρόκειται να είναι σε θέση να βρείτε ένα κουίζ ερώτηση σχετικά με αυτό - 433 00:35:10,220 --> 00:35:16,250 αλλά ακριβώς όπως αυτό το είδος του πράγματος. 434 00:35:19,680 --> 00:35:24,060 Βεβαιωθείτε ότι έχετε κατανοήσει ότι όταν λέω int * x * y - 435 00:35:24,890 --> 00:35:28,130 Αυτό δεν είναι ακριβώς κάτι εδώ, υποθέτω. 436 00:35:28,130 --> 00:35:32,140 Αλλά όπως * x * y, αυτά είναι 2 μεταβλητές που βρίσκονται στη στοίβα. 437 00:35:32,140 --> 00:35:37,220 Όταν λέω x = malloc (sizeof (int)), x εξακολουθεί να είναι μια μεταβλητή στη στοίβα, 438 00:35:37,220 --> 00:35:41,180 malloc είναι μερικά μπλοκ πάνω στο σωρό, και είμαστε με το σημείο x στο σωρό. 439 00:35:41,180 --> 00:35:43,900 >> Έτσι, κάτι σχετικά με τα σημεία στοίβα στο σωρό. 440 00:35:43,900 --> 00:35:48,100 Όποτε malloc τίποτα, είστε αποθήκευση αναπόφευκτα μέσα από ένα δείκτη. 441 00:35:48,100 --> 00:35:55,940 Έτσι ώστε το δείκτη βρίσκεται στη στοίβα, η malloced μπλοκ είναι στο σωρό. 442 00:35:55,940 --> 00:36:01,240 Πολλοί άνθρωποι μπερδεύονται και να πω int * x = malloc? X είναι στο σωρό. 443 00:36:01,240 --> 00:36:04,100 Όχι. Τι δείχνει x είναι στο σωρό. 444 00:36:04,100 --> 00:36:08,540 x είναι η ίδια στη στοίβα, εκτός αν για οποιοδήποτε λόγο έχετε x είναι μια καθολική μεταβλητή, 445 00:36:08,540 --> 00:36:11,960 στην οποία περίπτωση συμβαίνει να είναι σε μια άλλη περιοχή της μνήμης. 446 00:36:13,450 --> 00:36:20,820 Έτσι, την παρακολούθηση, αυτά τα διαγράμματα κουτί και το βέλος είναι αρκετά κοινό για το κουίζ. 447 00:36:20,820 --> 00:36:25,740 Ή αν δεν είναι σε κουίζ 0, θα είναι σε κουίζ 1. 448 00:36:27,570 --> 00:36:31,940 Θα πρέπει να γνωρίζετε όλα αυτά, τα βήματα στην κατάρτιση 449 00:36:31,940 --> 00:36:35,740 δεδομένου ότι θα έπρεπε να απαντήσει σε ερωτήσεις σχετικά με αυτούς. Ναι. 450 00:36:35,740 --> 00:36:38,940 [Φοιτητής] Θα μπορούσαμε να πάμε πάνω σε αυτές τις ενέργειες - Σίγουρα >>. 451 00:36:48,340 --> 00:36:58,640 Πριν από την κατάρτιση και τα βήματα που έχουμε προεπεξεργασία, 452 00:36:58,640 --> 00:37:16,750 την κατάρτιση, τη συναρμολόγηση, και τη σύνδεση. 453 00:37:16,750 --> 00:37:21,480 Προεπεξεργασία. Τι σημαίνει ότι κάνω; 454 00:37:29,720 --> 00:37:32,290 Είναι το πιο εύκολο βήμα - καλά, όχι όπως - 455 00:37:32,290 --> 00:37:35,770 αυτό δεν σημαίνει ότι θα πρέπει να είναι προφανές, αλλά είναι το πιο εύκολο βήμα. 456 00:37:35,770 --> 00:37:38,410 Εσείς θα μπορούσαν να εφαρμόσουν οι ίδιοι. Ναι. 457 00:37:38,410 --> 00:37:43,410 [Φοιτητής] Πάρτε ό, τι έχετε σε σας όπως αυτό περιλαμβάνει και το αντιγράφει και στη συνέχεια, επίσης, καθορίζει. 458 00:37:43,410 --> 00:37:49,250 Φαίνεται ότι για τα πράγματα όπως # include και # define, 459 00:37:49,250 --> 00:37:53,800 και απλά αντίγραφα και πάστες τι πραγματικά σημαίνουν αυτά. 460 00:37:53,800 --> 00:37:59,240 Έτσι, όταν λέτε # include cs50.h, ο Preprocessor είναι αντιγραφή και επικόλληση cs50.h 461 00:37:59,240 --> 00:38:01,030 σε αυτή τη γραμμή. 462 00:38:01,030 --> 00:38:06,640 Όταν λέτε # define x να είναι 4, ο προεπεξεργαστής περνά μέσα από το σύνολο του προγράμματος 463 00:38:06,640 --> 00:38:10,400 και αντικαθιστά όλες τις εμφανίσεις του x με 4. 464 00:38:10,400 --> 00:38:17,530 Έτσι, ο προεπεξεργαστής παίρνει ένα έγκυρο αρχείο C και εξάγει ένα έγκυρο αρχείο C 465 00:38:17,530 --> 00:38:20,300 όπου τα πράγματα έχουν αντιγραφεί και επικολληθεί. 466 00:38:20,300 --> 00:38:24,230 Έτσι τώρα κατάρτιση. Τι σημαίνει ότι κάνω; 467 00:38:25,940 --> 00:38:28,210 [Φοιτητής] Πηγαίνει από C σε δυαδικό. 468 00:38:28,210 --> 00:38:30,970 >> [Bowden] Δεν πάνε όλα το δρόμο σε δυαδικό. 469 00:38:30,970 --> 00:38:34,220 [Φοιτητής] Να κώδικα μηχανής τότε; >> Δεν είναι κώδικα μηχανής. 470 00:38:34,220 --> 00:38:35,700 [Φοιτητής] Συνέλευση; >> Συνέλευση. 471 00:38:35,700 --> 00:38:38,890 Πηγαίνει στην Συνέλευση προτού να πάει σε όλη τη διαδρομή στον κώδικα C, 472 00:38:38,890 --> 00:38:45,010 και περισσότερες γλώσσες κάνουν κάτι τέτοιο. 473 00:38:47,740 --> 00:38:50,590 Διαλέξτε οποιαδήποτε γλώσσα υψηλού επιπέδου, και αν πρόκειται να το υπολογίσουν, 474 00:38:50,590 --> 00:38:52,390 είναι πιθανό να συγκεντρώσει σε βήματα. 475 00:38:52,390 --> 00:38:58,140 Πρώτον, πρόκειται να μεταγλωττίσετε την Python στο C, τότε πρόκειται για την κατάρτιση C έως Συνέλευση, 476 00:38:58,140 --> 00:39:01,600 Συνέλευση και στη συνέχεια πρόκειται να πάρει μεταφραστεί σε δυαδική. 477 00:39:01,600 --> 00:39:07,800 Έτσι, την κατάρτιση πρόκειται να το φέρει από C έως Συνέλευση. 478 00:39:07,800 --> 00:39:12,130 Η λέξη σημαίνει συνήθως την κατάρτιση φέρνοντας το από ένα υψηλότερο επίπεδο 479 00:39:12,130 --> 00:39:14,340 σε χαμηλότερο γλώσσα προγραμματισμού υψηλού επιπέδου. 480 00:39:14,340 --> 00:39:19,190 Έτσι, αυτό είναι το μόνο βήμα για την συλλογή όπου μπορείτε να ξεκινήσετε με μια υψηλού επιπέδου γλώσσα 481 00:39:19,190 --> 00:39:23,270 και να καταλήξουμε σε μια χαμηλού επιπέδου γλώσσα, και γι 'αυτό το βήμα ονομάζεται κατάρτιση. 482 00:39:25,280 --> 00:39:33,370 [Φοιτητής] Κατά τη διάρκεια της κατάρτισης, ας πούμε ότι έχετε κάνει # include cs50.h. 483 00:39:33,370 --> 00:39:42,190 Θα το μεταγλωττιστή recompile το cs50.h, όπως και τις λειτουργίες που είναι εκεί, 484 00:39:42,190 --> 00:39:45,280 και τη μεταφράζουν σε κώδικα Συνέλευση, καθώς και, 485 00:39:45,280 --> 00:39:50,830 ή θα το αντιγράψετε και να επικολλήσετε κάτι που είναι ήδη προ-Συνέλευση; 486 00:39:50,830 --> 00:39:56,910 cs50.h θα λίγο πολύ ποτέ δεν καταλήγουν σε Συνέλευσης. 487 00:39:59,740 --> 00:40:03,680 Πράγματα όπως πρωτότυπα λειτουργία και τα πράγματα είναι απλά για σας να είστε προσεκτικοί. 488 00:40:03,680 --> 00:40:09,270 Εγγυάται ότι ο compiler μπορεί να ελέγξει τα πράγματα όπως είστε καλώντας λειτουργίες 489 00:40:09,270 --> 00:40:12,910 με τους τύπους δικαίωμα επιστροφής και τα σωστά επιχειρήματα και πράγματα. 490 00:40:12,910 --> 00:40:18,350 >> Έτσι cs50.h θα προεπεξεργασία στο αρχείο, και στη συνέχεια, όταν αυτό είναι σύνταξη 491 00:40:18,350 --> 00:40:22,310 Είναι βασικά πετιούνται μετά κάνει σίγουρος ότι όλα καλείται σωστά. 492 00:40:22,310 --> 00:40:29,410 Αλλά οι συναρτήσεις που ορίζονται στη βιβλιοθήκη CS50, που είναι ξεχωριστό από cs50.h, 493 00:40:29,410 --> 00:40:33,610 αυτά δεν θα καταρτίζονται χωριστά. 494 00:40:33,610 --> 00:40:37,270 Αυτό στην πραγματικότητα θα κατέβει στο στάδιο διασύνδεσης, έτσι θα φτάσουμε σε αυτό σε ένα δευτερόλεπτο. 495 00:40:37,270 --> 00:40:40,100 Αλλά πρώτα, τι είναι συναρμολόγηση; 496 00:40:41,850 --> 00:40:44,500 [Φοιτητής] Συνέλευση σε δυαδικό; Ναι >>. 497 00:40:46,300 --> 00:40:48,190 Συναρμολόγηση. 498 00:40:48,190 --> 00:40:54,710 Εμείς δεν αποκαλούμε την κατάρτιση Συνέλευση επειδή είναι λίγο πολύ μια καθαρή μετάφραση του δυαδικού. 499 00:40:54,710 --> 00:41:00,230 Υπάρχει πολύ λίγη λογική για να μεταβούν από συνέλευση σε δυαδικό. 500 00:41:00,230 --> 00:41:03,180 Είναι ακριβώς όπως την αναζήτηση σε έναν πίνακα, oh, έχουμε αυτή την εντολή? 501 00:41:03,180 --> 00:41:06,290 που αντιστοιχεί σε δυαδικό 01110. 502 00:41:10,200 --> 00:41:15,230 Και έτσι τα αρχεία που συναρμολόγηση γενικά έξοδοι. O αρχεία. 503 00:41:15,230 --> 00:41:19,020 Και τα αρχεία. O είναι αυτό που λέγαμε πριν, 504 00:41:19,020 --> 00:41:21,570 πώς ένα αρχείο δεν χρειάζεται να έχει μια κύρια λειτουργία. 505 00:41:21,570 --> 00:41:27,640 Κάθε αρχείο μπορεί να συγκεντρωθεί σε ένα αρχείο. O εφ 'όσον αυτό είναι ένα έγκυρο αρχείο C. 506 00:41:27,640 --> 00:41:30,300 Μπορεί να συγκεντρωθεί σε. O. 507 00:41:30,300 --> 00:41:43,030 Τώρα, η σύνδεση είναι αυτό που φέρνει πραγματικά ένα μάτσο. O αρχεία και τους φέρνει σε ένα εκτελέσιμο αρχείο. 508 00:41:43,030 --> 00:41:51,110 Και έτσι τι κάνει διασύνδεση είναι ότι μπορείτε να σκεφτείτε το CS50 βιβλιοθήκη ως ένα αρχείο. O. 509 00:41:51,110 --> 00:41:56,980 Πρόκειται για ένα ήδη καταρτίζονται δυαδικό αρχείο. 510 00:41:56,980 --> 00:42:03,530 Και έτσι κατά τη μεταγλώττιση του αρχείου σας, hello.c σας, η οποία καλεί GetString, 511 00:42:03,530 --> 00:42:06,360 hello.c παίρνει συγκεντρώνονται σε hello.o, 512 00:42:06,360 --> 00:42:08,910 hello.o είναι τώρα σε δυαδικό. 513 00:42:08,910 --> 00:42:12,830 Χρησιμοποιεί GetString, γι 'αυτό πρέπει να πάει πάνω σε cs50.o, 514 00:42:12,830 --> 00:42:16,390 και ο σύνδεσμος τους smooshes μαζί και αντιγράφει GetString σε αυτό το αρχείο 515 00:42:16,390 --> 00:42:20,640 και βγαίνει με ένα εκτελέσιμο αρχείο που έχει όλες τις λειτουργίες που χρειάζεται. 516 00:42:20,640 --> 00:42:32,620 Έτσι cs50.o δεν είναι στην πραγματικότητα ένα O αρχείο, αλλά είναι αρκετά κοντά ότι δεν υπάρχει θεμελιώδης διαφορά. 517 00:42:32,620 --> 00:42:36,880 Έτσι, συνδέοντας απλά φέρνει μια δέσμη των αρχείων μαζί 518 00:42:36,880 --> 00:42:41,390 που περιέχουν χωριστά όλες τις λειτουργίες που πρέπει να χρησιμοποιήσετε 519 00:42:41,390 --> 00:42:46,120 και δημιουργεί το εκτελέσιμο αρχείο που θα λειτουργεί πραγματικά. 520 00:42:48,420 --> 00:42:50,780 >> Και έτσι αυτό είναι επίσης αυτό που λέγαμε πριν 521 00:42:50,780 --> 00:42:55,970 όπου μπορείτε να έχετε 1000. γ. αρχεία, που συγκεντρώνει όλα αυτά να. o αρχεία, 522 00:42:55,970 --> 00:43:00,040 η οποία θα λάβει κατά πάσα πιθανότητα λίγο, στη συνέχεια, αλλάζετε 1. γ. αρχείο. 523 00:43:00,040 --> 00:43:05,480 Το μόνο που χρειάζεται να μεταγλωττίσετε ότι 1. Αρχείο c και στη συνέχεια όλα τα άλλα επανασύνδεση, 524 00:43:05,480 --> 00:43:07,690 συνδέσει τα πάντα πίσω μαζί. 525 00:43:09,580 --> 00:43:11,430 [Φοιτητής] Όταν είμαστε σύνδεση γράφουμε lcs50; 526 00:43:11,430 --> 00:43:20,510 Ναι, έτσι-lcs50. Που σηματοδοτεί τη σημαία με τον συνδετήρα που θα πρέπει να συνδέει σε αυτήν τη βιβλιοθήκη. 527 00:43:26,680 --> 00:43:28,910 Ερωτήσεις; 528 00:43:41,310 --> 00:43:46,860 Έχουμε περάσει πάνω από δυαδικό, εκτός από το ότι 5 δευτερόλεπτα στην πρώτη διάλεξη; 529 00:43:50,130 --> 00:43:53,010 Δε νομίζω. 530 00:43:55,530 --> 00:43:58,820 Θα πρέπει να γνωρίζετε όλα τα μεγάλα Os ότι έχουμε περάσει πάνω, 531 00:43:58,820 --> 00:44:02,670 και θα πρέπει να είναι σε θέση, αν σας δώσαμε μια λειτουργία, 532 00:44:02,670 --> 00:44:09,410 θα πρέπει να είναι σε θέση να πω ότι είναι μεγάλη O, περίπου. Ή επίσης, μεγάλη O είναι τραχύ. 533 00:44:09,410 --> 00:44:15,300 Έτσι, αν δείτε φωλιασμένα for για looping πάνω από τον ίδιο αριθμό των πραγμάτων, 534 00:44:15,300 --> 00:44:22,260 όπως int i, i > [φοιτητής] n τετράγωνο. >> Τείνει να είναι n τετράγωνο. 535 00:44:22,260 --> 00:44:25,280 Αν έχετε τριπλή ένθετο, τείνει να είναι n κύβους. 536 00:44:25,280 --> 00:44:29,330 Έτσι, αυτό το είδος των πράγμα που πρέπει να είναι σε θέση να επισημάνει αμέσως. 537 00:44:29,330 --> 00:44:33,890 Θα πρέπει να γνωρίζετε το είδος εισαγωγής και το είδος φούσκα και να συγχωνεύσει το είδος και όλα αυτά. 538 00:44:33,890 --> 00:44:41,420 Είναι πιο εύκολο να καταλάβουμε γιατί είναι αυτές n τετράγωνο και n log n και όλα αυτά 539 00:44:41,420 --> 00:44:47,810 γιατί νομίζω ότι υπήρχε ένα κουίζ για ένα έτος, όταν σας δώσαμε βασικά 540 00:44:47,810 --> 00:44:55,050 η εφαρμογή του bubble sort και είπε, "Ποιος είναι ο χρόνος εκτέλεσης αυτής της λειτουργίας;" 541 00:44:55,050 --> 00:45:01,020 Έτσι, αν το αναγνωρίσει ως είδος φούσκα, τότε μπορείτε να πείτε αμέσως n τετράγωνο. 542 00:45:01,020 --> 00:45:05,470 Αλλά αν εξετάσουμε μόνο αυτό, δεν χρειάζεται καν να συνειδητοποιήσουμε είδος αυτό είναι φούσκα? 543 00:45:05,470 --> 00:45:08,990 μπορείτε απλά να το πω αυτό το κάνει αυτό και αυτό. Αυτό είναι ν τετράγωνο. 544 00:45:12,350 --> 00:45:14,710 [Φοιτητής] Υπάρχουν παραδείγματα σκληρή μπορείτε να έρθετε επάνω με εκεί, 545 00:45:14,710 --> 00:45:20,370 σαν μια παρόμοια ιδέα για την εξεύρεση; 546 00:45:20,370 --> 00:45:24,450 >> Δεν νομίζω ότι θα σας δώσω κάποια παραδείγματα σκληρή. 547 00:45:24,450 --> 00:45:30,180 Το πράγμα bubble sort είναι περίπου τόσο σκληρά όσο θα πάμε, 548 00:45:30,180 --> 00:45:36,280 και ακόμη ότι, εφ 'όσον μπορείτε να καταλάβετε ότι είστε πάνω από την επανάληψη του πίνακα 549 00:45:36,280 --> 00:45:41,670 για κάθε στοιχείο του πίνακα, ο οποίος πρόκειται να είναι κάτι που ν τετράγωνο. 550 00:45:45,370 --> 00:45:49,940 Υπάρχουν γενικές ερωτήσεις, όπως το δικαίωμα που έχουμε εδώ - Αχ. 551 00:45:55,290 --> 00:45:58,530 Ακριβώς η άλλη ημέρα, Doug ισχυρίστηκε, «έχω εφεύρει έναν αλγόριθμο που να ταξινομήσετε μια σειρά 552 00:45:58,530 --> 00:46:01,780 "N των αριθμών σε O (log n) χρόνο!" 553 00:46:01,780 --> 00:46:04,900 Λοιπόν, πώς ξέρουμε ότι είναι αδύνατο; 554 00:46:04,900 --> 00:46:08,850 [Ακούγεται ανταπόκριση των φοιτητών] >> Ναι. 555 00:46:08,850 --> 00:46:13,710 Τουλάχιστον, θα πρέπει να αγγίζουν το ένα στοιχείο του πίνακα, 556 00:46:13,710 --> 00:46:16,210 έτσι είναι αδύνατο να ταξινομήσετε μια σειρά από - 557 00:46:16,210 --> 00:46:20,850 Αν όλα είναι σε τάξη αδιαχώριστα, τότε θα πάμε να αγγίξετε τα πάντα στον πίνακα, 558 00:46:20,850 --> 00:46:25,320 έτσι είναι αδύνατο να το κάνει σε λιγότερο από O από n. 559 00:46:27,430 --> 00:46:30,340 [Φοιτητής] Θα μας έδειξε το παράδειγμα του να είναι σε θέση να το κάνουμε σε n O της 560 00:46:30,340 --> 00:46:33,920 αν χρησιμοποιείτε μια πολύ μνήμη. Ναι >>. 561 00:46:33,920 --> 00:46:37,970 Και that's - ξεχάσω τι that's - Είναι είδος καταμέτρηση; 562 00:46:47,360 --> 00:46:51,330 Χμμ. Αυτό είναι ένας ακέραιος αλγόριθμος ταξινόμησης. 563 00:46:59,850 --> 00:47:05,100 Έψαχνα για το ειδικό όνομα για αυτό που δεν μπορούσε να θυμηθεί την περασμένη εβδομάδα. 564 00:47:05,100 --> 00:47:13,000 Ναι. Αυτά είναι τα είδη των ειδών που μπορεί να επιτύχει τα πράγματα σε μεγάλο Ο του n. 565 00:47:13,000 --> 00:47:18,430 Αλλά υπάρχουν περιορισμοί, όπως μπορείτε να χρησιμοποιήσετε μόνο ακέραιοι μέχρι ένα ορισμένο αριθμό. 566 00:47:20,870 --> 00:47:24,560 Πλέον, αν προσπαθείτε να ταξινομήσετε that's κάτι - 567 00:47:24,560 --> 00:47:30,750 Αν σας είναι σειρά 012, -12, 151, 4 εκατ. ευρώ, 568 00:47:30,750 --> 00:47:35,120 τότε μόνο στοιχείο που πρόκειται να καταστρέψει εντελώς το σύνολο της διαλογής. 569 00:47:42,060 --> 00:47:44,030 >> Ερωτήσεις; 570 00:47:49,480 --> 00:47:58,870 [Φοιτητής] Αν έχετε μια αναδρομική συνάρτηση και κάνει ακριβώς τις αναδρομικές κλήσεις 571 00:47:58,870 --> 00:48:02,230 μέσα σε μια δήλωση επιστροφής, αυτό είναι ουρά αναδρομικό 572 00:48:02,230 --> 00:48:07,360 και έτσι δεν θα χρησιμοποιούν περισσότερη μνήμη ότι κατά τη διάρκεια της εκτέλεσης 573 00:48:07,360 --> 00:48:12,550 ή θα ήταν τουλάχιστον συγκρίσιμη χρήση μνήμης ως μια επαναληπτική λύση; 574 00:48:12,550 --> 00:48:14,530 [Bowden] Ναι. 575 00:48:14,530 --> 00:48:19,840 Θα ήταν πιθανό να είναι κάπως πιο αργή, αλλά δεν είναι πραγματικά. 576 00:48:19,840 --> 00:48:23,290 Ουρά αναδρομική είναι πολύ καλή. 577 00:48:23,290 --> 00:48:32,640 Κοιτάζοντας ξανά σε στοίβα πλαίσια, ας πούμε ότι έχουν την κύρια 578 00:48:32,640 --> 00:48:42,920 και έχουμε int bar (int x) ή κάτι τέτοιο. 579 00:48:42,920 --> 00:48:52,310 Αυτό δεν είναι ένα τέλειο αναδρομική συνάρτηση, αλλά μπαρ επιστροφή (x - 1). 580 00:48:52,310 --> 00:48:57,620 Έτσι, προφανώς, αυτή είναι εσφαλμένη. Χρειάζεται περιπτώσεις βάση και την ουσία. 581 00:48:57,620 --> 00:49:00,360 Αλλά η ιδέα εδώ είναι ότι αυτή είναι η ουρά αναδρομικό 582 00:49:00,360 --> 00:49:06,020 πράγμα που σημαίνει όταν κεντρικό μπαρ κλήσεις πρόκειται να πάρει πλαίσιο της στοίβας. 583 00:49:09,550 --> 00:49:12,440 Σε αυτό το πλαίσιο στοίβας υπάρχει πρόκειται να είναι ένα μικρό κομμάτι της μνήμης 584 00:49:12,440 --> 00:49:17,490 που αντιστοιχεί στο όρισμα x του. 585 00:49:17,490 --> 00:49:25,840 Και ας πούμε ότι έτσι συμβαίνει κυρίως να καλέσετε μπαρ (100)? 586 00:49:25,840 --> 00:49:30,050 Έτσι x πρόκειται να αρχίσει από το 100. 587 00:49:30,050 --> 00:49:35,660 Εάν ο μεταγλωττιστής αναγνωρίζει ότι αυτό αποτελεί μια ουρά αναδρομική συνάρτηση, 588 00:49:35,660 --> 00:49:38,540 στη συνέχεια, όταν bar κάνει αναδρομική κλήση της να απαγορεύσει, 589 00:49:38,540 --> 00:49:45,490 αντί να κάνει ένα νέο πλαίσιο στοίβας, η οποία είναι όπου η στοίβα αρχίζει να αυξάνεται σε μεγάλο βαθμό, 590 00:49:45,490 --> 00:49:48,220 τελικά θα τρέξει στο σωρό και στη συνέχεια μπορείτε να πάρετε segfaults 591 00:49:48,220 --> 00:49:51,590 επειδή η μνήμη αρχίζει να συγκρούονται. 592 00:49:51,590 --> 00:49:54,830 >> Έτσι, αντί να κάνει το δικό του πλαίσιο στοίβας, μπορεί να συνειδητοποιήσουμε, 593 00:49:54,830 --> 00:49:59,080 hey, εγώ ποτέ δεν πρέπει να επανέλθουμε σε αυτό το πλαίσιο στοίβας, 594 00:49:59,080 --> 00:50:08,040 έτσι αντί εγώ θα αντικαταστήσει ακριβώς αυτό το επιχείρημα με το 99 και στη συνέχεια, ξεκινήστε μπαρ πάνω από όλα. 595 00:50:08,040 --> 00:50:11,810 Και τότε θα το κάνουμε και πάλι και θα φτάσουν μπαρ επιστροφής (x - 1), 596 00:50:11,810 --> 00:50:17,320 και αντί να κάνει ένα νέο πλαίσιο στοίβας, θα αντικαταστήσει μόνο σημερινό επιχείρημα του με 98 597 00:50:17,320 --> 00:50:20,740 και στη συνέχεια άλμα πίσω στην αρχή του μπαρ. 598 00:50:23,860 --> 00:50:30,430 Οι πράξεις αυτές, αντικαθιστώντας, το 1 τιμή στη στοίβα και το άλμα πίσω στην αρχή, 599 00:50:30,430 --> 00:50:32,430 είναι αρκετά αποτελεσματική. 600 00:50:32,430 --> 00:50:41,500 Έτσι, δεν είναι μόνο αυτό το ίδιο χρήση μνήμης ως μια ξεχωριστή λειτουργία, η οποία είναι επαναληπτική 601 00:50:41,500 --> 00:50:45,390 επειδή είστε χρησιμοποιώντας μόνο 1 πλαίσιο στοίβα, αλλά δεν είστε που πάσχουν μειονεκτήματα της 602 00:50:45,390 --> 00:50:47,240 του χρειάζεται να καλέσετε λειτουργίες. 603 00:50:47,240 --> 00:50:50,240 Κλήση λειτουργίες μπορεί να είναι κάπως ακριβά, διότι έχει να κάνει όλες αυτές τις ρυθμίσεις 604 00:50:50,240 --> 00:50:52,470 και λύσιμο και όλα αυτά τα πράγματα. 605 00:50:52,470 --> 00:50:58,160 Έτσι, αυτή η αναδρομή ουράς είναι καλό. 606 00:50:58,160 --> 00:51:01,170 [Φοιτητής] Γιατί δεν δημιουργεί νέα μέτρα; 607 00:51:01,170 --> 00:51:02,980 Επειδή συνειδητοποιεί ότι δεν χρειάζεται να. 608 00:51:02,980 --> 00:51:07,800 Η κλήση στη γραμμή επιστρέφει μόλις την αναδρομική κλήση. 609 00:51:07,800 --> 00:51:12,220 Γι 'αυτό δεν χρειάζεται να κάνει τίποτα με την τιμή επιστροφής. 610 00:51:12,220 --> 00:51:15,120 Είναι ακριβώς πρόκειται να επιστρέψει αμέσως. 611 00:51:15,120 --> 00:51:20,530 Γι 'αυτό ακριβώς πρόκειται να αντικαταστήσουν το δικό του επιχείρημα και ξεκινήστε από την αρχή. 612 00:51:20,530 --> 00:51:25,780 Και επίσης, αν δεν έχετε την ουρά αναδρομική έκδοση, 613 00:51:25,780 --> 00:51:31,460 τότε μπορείτε να πάρετε όλα αυτά τα μπαρ, όπου όταν η γραμμή επιστρέφει 614 00:51:31,460 --> 00:51:36,010 πρέπει να επιστρέψει την αξία του σε αυτό, στη συνέχεια, ότι η γραμμή επιστρέφει αμέσως 615 00:51:36,010 --> 00:51:39,620 και επιστρέφει την αξία του σε αυτό το σημείο, τότε αυτό είναι ακριβώς πρόκειται να επιστρέψει αμέσως 616 00:51:39,620 --> 00:51:41,350 και να επιστρέψει την αξία του σε αυτό. 617 00:51:41,350 --> 00:51:45,350 Έτσι, είστε εξοικονόμηση αυτή βρεθώ όλα αυτά τα πράγματα από την στοίβα 618 00:51:45,350 --> 00:51:48,730 δεδομένου ότι η τιμή επιστροφής είναι ακριβώς πρόκειται να περάσει όλος ο τρόπος πίσω έτσι κι αλλιώς. 619 00:51:48,730 --> 00:51:55,400 Γιατί λοιπόν να μην αντικαταστήσει μόνο το επιχείρημά μας με το επικαιροποιημένο επιχείρημα και ξεκινήστε από την αρχή; 620 00:51:57,460 --> 00:52:01,150 Εάν η λειτουργία δεν είναι αναδρομική ουρά, αν κάνετε κάτι τέτοιο - 621 00:52:01,150 --> 00:52:07,530 [Φοιτητής] αν bar (x + 1). Ναι >>. 622 00:52:07,530 --> 00:52:11,770 >> Έτσι, αν το βάλετε σε κατάσταση, τότε κάνετε κάτι με την τιμή επιστροφής. 623 00:52:11,770 --> 00:52:16,260 Ή ακόμα και αν το κάνετε μόνο την επιστροφή 2 * bar (x - 1). 624 00:52:16,260 --> 00:52:23,560 Έτσι τώρα bar (x - 1) θα πρέπει να επιστρέψουν, προκειμένου να υπολογίσει 2 φορές ότι η αξία, 625 00:52:23,560 --> 00:52:26,140 έτσι τώρα χρειάζεται το δικό της ξεχωριστό πλαίσιο της στοίβας, 626 00:52:26,140 --> 00:52:31,180 και τώρα, δεν έχει σημασία πόσο σκληρά την προσπάθειά σας, εσείς πρόκειται να πρέπει να - 627 00:52:31,180 --> 00:52:34,410 Αυτό δεν είναι αναδρομική ουρά. 628 00:52:34,410 --> 00:52:37,590 [Φοιτητής] Θα προσπαθήσω να φέρω μια αναδρομή στο στόχο για μια αναδρομή ουρά - 629 00:52:37,590 --> 00:52:41,450 [Bowden] Σε έναν ιδανικό κόσμο, αλλά σε CS50 δεν έχετε να. 630 00:52:43,780 --> 00:52:49,280 Για να πάρετε αναδρομή ουρά, γενικά, θα δημιουργήσει ένα πρόσθετο επιχείρημα 631 00:52:49,280 --> 00:52:53,550 όπου θα λάβει μπαρ int x σε y 632 00:52:53,550 --> 00:52:56,990 και y αντιστοιχεί στον τελικό πράγμα που θέλετε να επιστρέψετε. 633 00:52:56,990 --> 00:53:03,650 Έτσι, τότε αυτό θα πάμε να επιστρέψει bar (x - 1), 2 * y. 634 00:53:03,650 --> 00:53:09,810 Έτσι, αυτό είναι απλώς μια υψηλού επιπέδου πώς θα μετατρέψει τα πράγματα να είναι αναδρομική ουρά. 635 00:53:09,810 --> 00:53:13,790 Αλλά το επιπλέον επιχείρημα - 636 00:53:13,790 --> 00:53:17,410 Και στη συνέχεια, στο τέλος, όταν φτάσετε βασικό σενάριο σας, μπορείτε να επιστρέψετε ακριβώς y 637 00:53:17,410 --> 00:53:22,740 επειδή έχετε συσσώρευση ολόκληρο το χρόνο η τιμή επιστροφής που θέλετε. 638 00:53:22,740 --> 00:53:27,280 Μπορείτε είδος του έχουν κάνει επαναληπτικά αλλά χρησιμοποιώντας αναδρομικές κλήσεις. 639 00:53:32,510 --> 00:53:34,900 Ερωτήσεις; 640 00:53:34,900 --> 00:53:39,890 [Φοιτητής] Ίσως για αριθμητική δείκτη, όπως όταν χρησιμοποιεί χορδές. Σίγουρα >>. 641 00:53:39,890 --> 00:53:43,610 Αριθμητική δείκτη. 642 00:53:43,610 --> 00:53:48,440 Όταν χρησιμοποιείτε χορδές είναι εύκολο, επειδή οι χορδές είναι char αστέρια, 643 00:53:48,440 --> 00:53:51,860 χαρακτήρες είναι για πάντα και πάντα ένα μόνο byte, 644 00:53:51,860 --> 00:53:57,540 και έτσι αριθμητική δείκτη είναι ισοδύναμη με κανονική αριθμητική όταν έχεις να κάνεις με χορδές. 645 00:53:57,540 --> 00:54:08,790 Ας πούμε char * s = "γεια". 646 00:54:08,790 --> 00:54:11,430 Έτσι έχουμε ένα μπλοκ στη μνήμη. 647 00:54:19,490 --> 00:54:22,380 Χρειάζεται 6 bytes, επειδή θα πρέπει να έχετε πάντα τη μηδενική τερματισμού. 648 00:54:22,380 --> 00:54:28,620 Και char * s πρόκειται να επισημάνω στην αρχή αυτού του πίνακα. 649 00:54:28,620 --> 00:54:32,830 Έτσι, s επισημαίνει εκεί. 650 00:54:32,830 --> 00:54:36,710 Τώρα, αυτό είναι βασικά το πώς λειτουργεί κάθε σειρά, 651 00:54:36,710 --> 00:54:40,780 ανεξάρτητα από το αν ήταν μια επιστροφή με malloc ή αν είναι στη στοίβα. 652 00:54:40,780 --> 00:54:47,110 Κάθε συστοιχία είναι βασικά ένας δείκτης προς την έναρξη της συστοιχίας, 653 00:54:47,110 --> 00:54:53,640 και στη συνέχεια, κάθε πράξη πίνακα, κάθε ευρετηρίασης, πρόκειται ακριβώς σε αυτή την σειρά ένα συγκεκριμένο offset. 654 00:54:53,640 --> 00:55:05,360 >> Έτσι, όταν λέω κάτι σαν s [3]? Αυτό πρόκειται να s και μετρώντας 3 χαρακτήρες μέσα 655 00:55:05,360 --> 00:55:12,490 Έτσι, s [3], έχουμε 0, 1, 2, 3, έτσι s [3] πρόκειται να αναφερθώ σε αυτό το l. 656 00:55:12,490 --> 00:55:20,460 [Φοιτητής] Και θα μπορούσαμε να φτάσει την ίδια αξία με τον τρόπο s + 3 και στη συνέχεια παρενθέσεις αστέρι; 657 00:55:20,460 --> 00:55:22,570 Ναι. 658 00:55:22,570 --> 00:55:26,010 Αυτό είναι ισοδύναμο με * (s + 3)? 659 00:55:26,010 --> 00:55:31,240 και ότι είναι για πάντα και πάντα ισοδύναμο δεν έχει σημασία τι θα κάνεις. 660 00:55:31,240 --> 00:55:34,070 Ποτέ δεν πρέπει να χρησιμοποιήσετε τη σύνταξη βραχίονα. 661 00:55:34,070 --> 00:55:37,770 Μπορείτε να χρησιμοποιείτε πάντα την * (s + 3) σύνταξη. 662 00:55:37,770 --> 00:55:40,180 Οι άνθρωποι έχουν την τάση να τους αρέσει η σύνταξη βραχίονα, όμως. 663 00:55:40,180 --> 00:55:43,860 [Φοιτητής] Έτσι, όλες οι σειρές είναι στην πραγματικότητα μόνο δείκτες. 664 00:55:43,860 --> 00:55:53,630 Υπάρχει μια μικρή διαφορά όταν λέω int x [4]? >> [Φοιτητής] Έχει δημιουργήσει αυτή τη μνήμη; 665 00:55:53,630 --> 00:56:03,320 [Bowden] Αυτό θα δημιουργήσει 4 ints στη στοίβα, έτσι συνολικά 16 bytes. 666 00:56:03,320 --> 00:56:05,700 Είναι πρόκειται να δημιουργήσει 16 byte στη στοίβα. 667 00:56:05,700 --> 00:56:09,190 x δεν αποθηκεύονται πουθενά. 668 00:56:09,190 --> 00:56:13,420 Είναι απλά ένα σύμβολο που αναφέρεται στην έναρξη του πράγματος. 669 00:56:13,420 --> 00:56:17,680 Επειδή έχετε δηλώσει τη σειρά μέσα από αυτή τη λειτουργία, 670 00:56:17,680 --> 00:56:22,340 τι ο compiler πρόκειται να κάνουμε είναι να αντικαταστήσει ακριβώς όλες τις εμφανίσεις της μεταβλητής x 671 00:56:22,340 --> 00:56:26,400 με όπου συνέβη να επιλέξουν να εφαρμόσουν αυτές τις 16 bytes. 672 00:56:26,400 --> 00:56:30,040 Δεν μπορεί να το κάνει αυτό με char * s, επειδή s είναι ένα πραγματικό δείκτη. 673 00:56:30,040 --> 00:56:32,380 Είναι ελεύθερος να επισημάνω στη συνέχεια σε άλλα πράγματα. 674 00:56:32,380 --> 00:56:36,140 χ είναι μια σταθερά. Δεν μπορείς να έχεις το σημείο σε μια διαφορετική σειρά. >> [Φοιτητής] Εντάξει. 675 00:56:36,140 --> 00:56:43,420 Αλλά αυτή η ιδέα, αυτή η ευρετηρίαση, είναι η ίδια, ανεξάρτητα από το αν πρόκειται για μια παραδοσιακή σειρά 676 00:56:43,420 --> 00:56:48,230 ή αν είναι ένας δείκτης για κάτι ή αν είναι ένας δείκτης σε μια σειρά malloced. 677 00:56:48,230 --> 00:56:59,770 Και στην πραγματικότητα, είναι τόσο ισοδύναμη ότι είναι επίσης το ίδιο πράγμα. 678 00:56:59,770 --> 00:57:05,440 Είναι πραγματικά ακριβώς μεταφράζεται αυτό που είναι μέσα από τα στηρίγματα και ό, τι έχει απομείνει από τα στηρίγματα, 679 00:57:05,440 --> 00:57:07,970 προσθέτει τους μαζί, και dereferences. 680 00:57:07,970 --> 00:57:14,710 Έτσι, αυτό είναι ακριβώς το ίδιο έγκυρη όπως * (s + 3) ή s [3]. 681 00:57:16,210 --> 00:57:22,090 [Φοιτητής] Μπορεί να έχετε δείκτες που δείχνουν σε 2-διαστάσεων πίνακες; 682 00:57:22,090 --> 00:57:27,380 >> Είναι πιο δύσκολο. Παραδοσιακά, ηο. 683 00:57:27,380 --> 00:57:34,720 Μια 2-διαστάσεων πίνακας είναι απλά ένα 1-διάστατο πίνακα με κάποιο βολικό σύνταξη 684 00:57:34,720 --> 00:57:54,110 γιατί όταν λέω int x [3] [3], αυτό είναι πραγματικά μόνο 1 πίνακα με 9 τιμές. 685 00:57:55,500 --> 00:58:03,000 Και έτσι όταν δείκτη, ο compiler ξέρει τι εννοώ. 686 00:58:03,000 --> 00:58:13,090 Αν πω x [1] [2], το ξέρει Θέλω να πάω στη δεύτερη σειρά, έτσι πρόκειται να παραλείψετε το πρώτο 3, 687 00:58:13,090 --> 00:58:17,460 και στη συνέχεια, θέλει το δεύτερο πράγμα που, γι 'αυτό πρόκειται να πάρει αυτό το ένα. 688 00:58:17,460 --> 00:58:20,480 Αλλά αυτό είναι ακόμα ένα απλό μονοδιάστατο πίνακα. 689 00:58:20,480 --> 00:58:23,660 Και έτσι, αν ήθελα να ορίσετε ένα δείκτη για την ποικιλία, 690 00:58:23,660 --> 00:58:29,770 Θα έλεγα int * p = x? 691 00:58:29,770 --> 00:58:33,220 Ο τύπος του x είναι ακριβώς - 692 00:58:33,220 --> 00:58:38,280 Είναι τραχύ τύπο λέγοντας του x δεδομένου ότι είναι απλώς ένα σύμβολο και δεν είναι μια πραγματική μεταβλητή, 693 00:58:38,280 --> 00:58:40,140 αλλά αυτό είναι μόνο ένα int *. 694 00:58:40,140 --> 00:58:44,840 χ είναι απλά ένας δείκτης για την έναρξη αυτής. >> [Φοιτητής] Εντάξει. 695 00:58:44,840 --> 00:58:52,560 Και γι 'αυτό δεν θα είναι σε θέση να έχουν πρόσβαση [1] [2]. 696 00:58:52,560 --> 00:58:58,370 Νομίζω ότι υπάρχει ειδική σύνταξη για την κήρυξη ενός δείκτη, 697 00:58:58,370 --> 00:59:12,480 κάτι γελοίο, όπως int (* p [-. κάτι εντελώς γελοίο που δεν γνωρίζουν καν. 698 00:59:12,480 --> 00:59:17,090 Αλλά υπάρχει ένα συντακτικό για τη δήλωση δείκτες, όπως με παρενθέσεις και δραστηριότητες. 699 00:59:17,090 --> 00:59:22,960 Δεν μπορεί ακόμη και να σας αφήσει να το κάνουμε αυτό. 700 00:59:22,960 --> 00:59:26,640 Θα μπορούσα να κοιτάξουμε πίσω σε κάτι που θα μπορούσε να μου πει την αλήθεια. 701 00:59:26,640 --> 00:59:34,160 Θα δούμε για αργότερα, αν υπάρχει ένα σημείο για σύνταξη. Αλλά ποτέ δεν θα το δείτε. 702 00:59:34,160 --> 00:59:39,670 Και ακόμα και η σύνταξη είναι τόσο αρχαϊκό ότι αν το χρησιμοποιείτε, οι άνθρωποι θα πρέπει να αμηχανία. 703 00:59:39,670 --> 00:59:43,540 Πολυδιάστατοι πίνακες είναι αρκετά σπάνιο, δεδομένου ότι είναι. 704 00:59:43,540 --> 00:59:44,630 Μπορείτε λίγο πολύ - 705 00:59:44,630 --> 00:59:48,490 Λοιπόν, αν κάνεις τα πράγματα μήτρα δεν πρόκειται να είναι σπάνια, 706 00:59:48,490 --> 00:59:56,730 αλλά σε C είστε σπάνια πρόκειται να χρησιμοποιείτε πολυδιάστατους πίνακες. 707 00:59:57,630 --> 01:00:00,470 Ναι. >> [Φοιτητής] Ας πούμε ότι έχετε ένα πραγματικά μεγάλο πίνακα. 708 01:00:00,470 --> 01:00:03,900 >> Έτσι, στην εικονική μνήμη φαίνεται να είναι όλα τα διαδοχικά, 709 01:00:03,900 --> 01:00:05,640 όπως και τα στοιχεία που το ένα δίπλα στο άλλο, 710 01:00:05,640 --> 01:00:08,770 αλλά στη φυσική μνήμη, θα ήταν δυνατό γι 'αυτό που πρόκειται να χωρίσουν; Ναι >>. 711 01:00:08,770 --> 01:00:16,860 Πώς λειτουργεί εικονική μνήμη είναι το χωρίζει μόνο - 712 01:00:19,220 --> 01:00:24,860 Η μονάδα της κατανομής είναι μια σελίδα, η οποία τείνει να είναι 4 kilobyte, 713 01:00:24,860 --> 01:00:29,680 και έτσι όταν μια διαδικασία λέει, hey, θέλω να χρησιμοποιήσω αυτή τη μνήμη, 714 01:00:29,680 --> 01:00:35,970 το λειτουργικό σύστημα πρόκειται να διαθέσει το 4 kilobyte για αυτό το μικρό μπλοκ μνήμης. 715 01:00:35,970 --> 01:00:39,100 Ακόμα και αν χρησιμοποιείτε μόνο μια μικρή byte σε ολόκληρο το μπλοκ της μνήμης, 716 01:00:39,100 --> 01:00:42,850 το λειτουργικό σύστημα πρόκειται να δώσει τα πλήρη 4 kilobyte. 717 01:00:42,850 --> 01:00:49,410 Έτσι τι αυτό σημαίνει είναι ότι θα μπορούσε να έχει - ας πούμε ότι αυτό είναι το stack μου. 718 01:00:49,410 --> 01:00:53,180 Αυτή η στοίβα μπορεί να διαχωριστεί. Stack μου θα μπορούσε να είναι megabytes και megabytes. 719 01:00:53,180 --> 01:00:55,020 Stack μου θα μπορούσε να είναι τεράστια. 720 01:00:55,020 --> 01:01:00,220 Αλλά η ίδια η στοίβα θα πρέπει να χωριστεί σε μεμονωμένες σελίδες, 721 01:01:00,220 --> 01:01:09,010 η οποία, αν κοιτάξουμε πάνω από εδώ ας πούμε αυτό είναι η μνήμη RAM μας, 722 01:01:09,010 --> 01:01:16,600 αν έχω 2 gigabytes μνήμης RAM, αυτό είναι πραγματική διεύθυνση 0, όπως η μηδενική byte της μνήμης RAM μου, 723 01:01:16,600 --> 01:01:22,210 και αυτό είναι 2 gigabytes σε όλη τη διαδρομή εδώ. 724 01:01:22,210 --> 01:01:27,230 Έτσι, αυτή η σελίδα θα μπορούσε να αντιστοιχεί σε αυτό το μπλοκ εδώ. 725 01:01:27,230 --> 01:01:29,400 Αυτή η σελίδα θα μπορούσε να αντιστοιχεί σε αυτό το μπλοκ εδώ. 726 01:01:29,400 --> 01:01:31,560 Αυτό και μόνο θα μπορούσε να αντιστοιχεί σε αυτό το σημείο εδώ. 727 01:01:31,560 --> 01:01:35,540 Έτσι, το λειτουργικό σύστημα είναι ελεύθερος να εκχωρήσει φυσική μνήμη 728 01:01:35,540 --> 01:01:39,320 σε κάθε σελίδα ξεχωριστά αυθαίρετα. 729 01:01:39,320 --> 01:01:46,180 Και αυτό σημαίνει ότι αν αυτό συμβαίνει στα σύνορα να μην συμπίπτει με μια σειρά, 730 01:01:46,180 --> 01:01:50,070 μια σειρά συμβαίνει να μείνει από αυτό και το δικαίωμα της παρούσας διάταξης μιας σελίδας, 731 01:01:50,070 --> 01:01:54,460 τότε η συστοιχία πρόκειται να χωριστεί σε φυσική μνήμη. 732 01:01:54,460 --> 01:01:59,280 Και στη συνέχεια, όταν κλείνετε το πρόγραμμα, όταν η διαδικασία τελειώνει, 733 01:01:59,280 --> 01:02:05,690 αυτές οι αντιστοιχίσεις να διαγραφούν και τότε είναι ελεύθερη να χρησιμοποιήσει αυτά τα μικρά τετράγωνα για άλλα πράγματα. 734 01:02:14,730 --> 01:02:17,410 Περισσότερες ερωτήσεις; 735 01:02:17,410 --> 01:02:19,960 [Φοιτητής] Η αριθμητική δείκτη. Ω ναι >>. 736 01:02:19,960 --> 01:02:28,410 Χορδές ήταν πιο εύκολο, αλλά κοιτάζοντας κάτι σαν ints, 737 01:02:28,410 --> 01:02:35,000 έτσι πίσω στο int x [4]? 738 01:02:35,000 --> 01:02:41,810 Είτε αυτό είναι ένας πίνακας ή αν είναι ένας δείκτης σε μια σειρά malloced από 4 ακέραιους αριθμούς, 739 01:02:41,810 --> 01:02:47,060 πρόκειται να αντιμετωπίζονται με τον ίδιο τρόπο. 740 01:02:50,590 --> 01:02:53,340 [Φοιτητής] Έτσι συστοιχίες είναι στο σωρό; 741 01:03:01,400 --> 01:03:05,270 [Bowden] Οι πίνακες δεν είναι στο σωρό. >> [Φοιτητής] Αχ. 742 01:03:05,270 --> 01:03:08,320 >> [Bowden] Αυτό το είδος της συστοιχίας τείνει να είναι στη στοίβα 743 01:03:08,320 --> 01:03:12,220 αν δεν δηλωθεί κατά - αγνοώντας καθολικές μεταβλητές. Μην χρησιμοποιείτε καθολικές μεταβλητές. 744 01:03:12,220 --> 01:03:16,280 Μέσα από μια συνάρτηση λέω int x [4]? 745 01:03:16,280 --> 01:03:22,520 Είναι πρόκειται να δημιουργήσει ένα 4-μπλοκ ακέραιο στη στοίβα για αυτή τη διάταξη. 746 01:03:22,520 --> 01:03:26,960 Αλλά αυτή η malloc (4 * sizeof (int))? Πρόκειται να πάει στο σωρό. 747 01:03:26,960 --> 01:03:31,870 Αλλά μετά από αυτό το σημείο μπορώ να χρησιμοποιήσω x και p σε λίγο πολύ τους ίδιους τρόπους, 748 01:03:31,870 --> 01:03:36,140 εκτός από τις εξαιρέσεις που είπα πριν για να μπορείτε να εκχωρήσετε εκ νέου σ.. 749 01:03:36,140 --> 01:03:40,960 Τεχνικά, τα μεγέθη τους είναι κάπως διαφορετικά, αλλά αυτό είναι τελείως άσχετο. 750 01:03:40,960 --> 01:03:43,310 Ποτέ δεν χρησιμοποιούν πραγματικά μεγέθη τους. 751 01:03:48,020 --> 01:03:56,810 Το p θα μπορούσα να πω σ. [3] = 2? Ή x [3] = 2? 752 01:03:56,810 --> 01:03:59,680 Μπορείτε να τα χρησιμοποιήσετε με τον ίδιο ακριβώς τρόπο. 753 01:03:59,680 --> 01:04:01,570 Έτσι αριθμητική δείκτη τώρα - Ναι. 754 01:04:01,570 --> 01:04:07,390 [Φοιτητής] Μην έχετε να κάνετε p * εάν έχετε τα στηρίγματα; 755 01:04:07,390 --> 01:04:11,720 Οι παρενθέσεις είναι μια σιωπηρή dereference. Εντάξει >>. 756 01:04:11,720 --> 01:04:20,200 Στην πραγματικότητα, επίσης, τι λέτε με το μπορείτε να πάρετε πολυδιάστατους πίνακες 757 01:04:20,200 --> 01:05:02,650 με δείκτες, τι μπορείτε να κάνετε είναι κάτι σαν, ας πούμε, int ** pp = malloc (sizeof (int *) * 5)? 758 01:05:02,650 --> 01:05:06,900 Εγώ απλώς θα γράψω όλα έξω πρώτα. 759 01:05:37,880 --> 01:05:41,020 Δεν ήθελα εκείνο το ένα. 760 01:05:41,020 --> 01:05:42,550 Εντάξει. 761 01:05:42,550 --> 01:05:48,910 Αυτό που έκανα είναι εδώ - Αυτό θα πρέπει να είναι σελ. [i]. 762 01:05:48,910 --> 01:05:53,680 Έτσι, pp είναι ένας δείκτης σε ένα δείκτη. 763 01:05:53,680 --> 01:06:02,420 Είσαι mallocing σελ. να επισημάνει μια σειρά από 5 αστέρια int. 764 01:06:02,420 --> 01:06:10,950 Έτσι, στη μνήμη έχετε στην σελ. στοίβα 765 01:06:10,950 --> 01:06:20,150 Είναι πρόκειται να επισημάνω για μια σειρά από 5 τετράγωνα τα οποία είναι όλα τους δείκτες. 766 01:06:20,150 --> 01:06:28,210 Και στη συνέχεια, όταν malloc εδώ κάτω, εγώ malloc ότι κάθε μία από αυτές τις μεμονωμένες δείκτες 767 01:06:28,210 --> 01:06:32,080 Πρέπει να επισημάνω ένα ξεχωριστό μπλοκ των 4 byte για το σωρό. 768 01:06:32,080 --> 01:06:35,870 Έτσι, αυτά τα σημεία σε 4 bytes. 769 01:06:37,940 --> 01:06:40,660 Και αυτό δείχνει ένα διαφορετικό 4 bytes. 770 01:06:40,660 --> 01:06:43,200 >> Και όλα αυτά στη δική τους 4 bytes. 771 01:06:43,200 --> 01:06:49,080 Αυτό μου δίνει ένα τρόπο για να γίνει πολυδιάστατη πράγματα. 772 01:06:49,080 --> 01:06:58,030 Θα μπορούσα να πω σελ. [3] [4], αλλά τώρα αυτό δεν είναι το ίδιο πράγμα με το πολυδιάστατο συστοιχίες 773 01:06:58,030 --> 01:07:05,390 επειδή πολυδιάστατων συστοιχίες που μεταφράζεται [3] [4] σε ένα ενιαίο αντιστάθμιση στη συστοιχία x. 774 01:07:05,390 --> 01:07:14,790 Αυτό σ. dereferences, πρόσβαση στο τρίτο δείκτη, τότε dereferences ότι 775 01:07:14,790 --> 01:07:20,790 και προσβάσεις - 4 θα είναι άκυρο - ο δεύτερος δείκτης. 776 01:07:24,770 --> 01:07:31,430 Ότι, όταν είχαμε το int x [3] [4], όπως πριν από ένα πολυδιάστατο πίνακα 777 01:07:31,430 --> 01:07:35,740 και όταν κάνετε διπλό βραχίονα είναι πραγματικά μόνο ένα dereference, 778 01:07:35,740 --> 01:07:40,490 είστε μετά από ένα μόνο δείκτη και στη συνέχεια ένα offset, 779 01:07:40,490 --> 01:07:42,850 αυτό είναι πραγματικά 2D αναφορές. 780 01:07:42,850 --> 01:07:45,840 Θα ακολουθήσουν 2 ξεχωριστά δείκτες. 781 01:07:45,840 --> 01:07:50,420 Έτσι, αυτό επίσης τεχνικά σας επιτρέπει να έχετε πολυδιάστατους πίνακες 782 01:07:50,420 --> 01:07:53,550 όπου κάθε επιμέρους array είναι διαφορετικά μεγέθη. 783 01:07:53,550 --> 01:07:58,000 Πιστεύω λοιπόν ότι ακανόνιστα πολυδιάστατους πίνακες είναι ό, τι λέγεται 784 01:07:58,000 --> 01:08:01,870 αφού πραγματικά το πρώτο πράγμα που θα μπορούσε να δείξει κάτι που έχει 10 στοιχεία, 785 01:08:01,870 --> 01:08:05,540 το δεύτερο πράγμα που θα μπορούσε να δείξει κάτι που έχει 100 στοιχεία. 786 01:08:05,540 --> 01:08:10,790 [Φοιτητής] Υπάρχει κάποιο όριο στον αριθμό των δεικτών μπορείτε να έχετε εκεί 787 01:08:10,790 --> 01:08:14,290 επισημαίνοντας άλλα δείκτες; Όχι >> 788 01:08:14,290 --> 01:08:17,010 Μπορείτε να έχετε int p *****. 789 01:08:18,050 --> 01:08:23,760 Επιστροφή στην αριθμητική δείκτη - >> [φοιτητής] Αχ. Ναι >>. 790 01:08:23,760 --> 01:08:35,649 [Φοιτητής] Αν έχω int *** p και στη συνέχεια να κάνω μια αποαναφοράς και λέω p * είναι ίση με την τιμή αυτή, 791 01:08:35,649 --> 01:08:39,560 είναι μόνο πρόκειται να κάνετε 1 επίπεδο εύρεση τιμών; Ναι >>. 792 01:08:39,560 --> 01:08:43,340 Έτσι, αν θέλετε να αποκτήσετε πρόσβαση το πράγμα ότι η τελευταία δείκτης δείχνει σε - 793 01:08:43,340 --> 01:08:46,210 Στη συνέχεια, κάνετε σ ***. Εντάξει >>. 794 01:08:46,210 --> 01:08:54,080 Έτσι, αυτό είναι τα σημεία p στο 1 μπλοκ, σημεία σε ένα άλλο μπλοκ, σημεία σε ένα άλλο μπλοκ. 795 01:08:54,080 --> 01:09:02,010 Στη συνέχεια, αν κάνετε * p = κάτι άλλο, τότε αλλάζουν αυτό 796 01:09:02,010 --> 01:09:13,640 τώρα το σημείο σε ένα άλλο μπλοκ. Εντάξει >>. 797 01:09:13,640 --> 01:09:17,649 >> [Bowden] Και αν αυτά malloced, τότε θα έχουν διαρρεύσει τώρα μνήμη 798 01:09:17,649 --> 01:09:20,430 εκτός και αν τυχαίνει να έχουν διαφορετικές αναφορές από αυτά 799 01:09:20,430 --> 01:09:25,270 δεδομένου ότι δεν μπορείτε να πάρετε πίσω σε εκείνες αυτά που μόλις πέταξε μακριά. 800 01:09:25,270 --> 01:09:29,550 Αριθμητική δείκτη. 801 01:09:29,550 --> 01:09:36,310 int x [4]? πρόκειται να διαθέσει μια σειρά από 4 ακέραιους αριθμούς 802 01:09:36,310 --> 01:09:40,670 όπου το χ πρόκειται να δείχνουν την αρχή της συστοιχίας. 803 01:09:40,670 --> 01:09:50,420 Έτσι, όταν λέω κάτι σαν x [1]? Θέλω να πάω να σημαίνει το δεύτερο ακέραιο στον πίνακα, 804 01:09:50,420 --> 01:09:53,319 το οποίο θα είναι αυτό. 805 01:09:53,319 --> 01:10:04,190 Αλλά πραγματικά, αυτό είναι 4 byte στη σειρά δεδομένου ότι αυτό ακέραιος καταλαμβάνει 4 bytes. 806 01:10:04,190 --> 01:10:08,470 Έτσι, μια μετατόπιση από 1 σημαίνει πραγματικά μια μετατόπιση από 1 807 01:10:08,470 --> 01:10:12,030 φορές το μέγεθος του ό, τι ο τύπος της συστοιχίας είναι. 808 01:10:12,030 --> 01:10:17,170 Πρόκειται για μια σειρά από ακέραιους αριθμούς, έτσι ώστε να ξέρει να κάνει 1 φορές το μέγεθος του int όταν θέλει να αντισταθμίσει. 809 01:10:17,170 --> 01:10:25,260 Η άλλη σύνταξη. Θυμηθείτε ότι αυτό είναι ισοδύναμο με * (χ + 1)? 810 01:10:25,260 --> 01:10:35,250 Όταν λέω δείκτη + 1, τι οι αποδόσεις είναι η διεύθυνση ότι ο δείκτης αποθηκεύει 811 01:10:35,250 --> 01:10:40,360 συν 1 φορές το μέγεθος του τύπου του δείκτη. 812 01:10:40,360 --> 01:10:59,510 Έτσι, εάν x = ox100, τότε x + 1 = ox104. 813 01:10:59,510 --> 01:11:19,750 Και μπορείτε να καταχραστούν αυτό και να πω κάτι σαν char * c = (char *) x? 814 01:11:19,750 --> 01:11:23,050 και γ τώρα πρόκειται να είναι η ίδια διεύθυνση με το x. 815 01:11:23,050 --> 01:11:26,040 γ πρόκειται να είναι ίση προς ox100, 816 01:11:26,040 --> 01:11:31,490 αλλά γ + 1 πρόκειται να είναι ίση προς ox101 817 01:11:31,490 --> 01:11:38,030 από αριθμητική δείκτη εξαρτάται από τον τύπο του δείκτη που προσθέτετε στο. 818 01:11:38,030 --> 01:11:45,390 Έτσι, γ + 1, φαίνεται στο γ, είναι ένας pointer σε char, έτσι πρόκειται να προσθέσετε 1 φορές το μέγεθος του char, 819 01:11:45,390 --> 01:11:48,110 η οποία είναι πάντα θα είναι 1, έτσι μπορείτε να πάρετε 101, 820 01:11:48,110 --> 01:11:54,890 ενώ αν το κάνω x, το οποίο είναι επίσης ακόμα 100, x + 1 θα είναι 104. 821 01:11:56,660 --> 01:12:06,340 [Φοιτητής] Μπορείτε να χρησιμοποιήσετε C + +, προκειμένου να προωθήσει το δείκτη του ποντικιού κατά 1; 822 01:12:06,340 --> 01:12:09,810 Ναι, μπορείτε. 823 01:12:09,810 --> 01:12:16,180 Δεν μπορείτε να το κάνετε αυτό, επειδή με x το x είναι απλώς ένα σύμβολο, είναι μια διαρκής? Δεν μπορείτε να αλλάξετε x. 824 01:12:16,180 --> 01:12:22,610 >> Αλλά γ συμβαίνει ακριβώς να είναι ένας δείκτης, έτσι c + + είναι απόλυτα έγκυρες και θα αυξηθεί κατά 1. 825 01:12:22,610 --> 01:12:32,440 Αν γ ήταν απλά μια int *, τότε το c + + θα είναι 104. 826 01:12:32,440 --> 01:12:41,250 + + Κάνει αριθμητική δείκτη ακριβώς όπως γ + 1 θα έχουν γίνει αριθμητική δείκτη. 827 01:12:43,000 --> 01:12:48,870 Αυτό είναι στην πραγματικότητα το πώς πολλά πράγματα όπως το είδος συγχώνευσης - 828 01:12:49,670 --> 01:12:55,710 Αντί για τη δημιουργία αντιγράφων των πραγμάτων, μπορείτε να περάσετε αντί - 829 01:12:55,710 --> 01:13:02,400 Όπως και αν ήθελα να περάσει αυτό το μισό του πίνακα - Ας σβήσει μερικά από αυτό. 830 01:13:04,770 --> 01:13:10,520 Ας πούμε ότι ήθελε να περάσει αυτή την πλευρά του πίνακα σε μια λειτουργία. 831 01:13:10,520 --> 01:13:12,700 Τι θα περάσει στη λειτουργία που εξασφαλίζει; 832 01:13:12,700 --> 01:13:17,050 Αν περάσει x, είμαι περνώντας αυτή τη διεύθυνση. 833 01:13:17,050 --> 01:13:23,780 Αλλά θέλω να περάσει αυτή τη συγκεκριμένη διεύθυνση. Λοιπόν, τι θα πρέπει να περάσει; 834 01:13:23,780 --> 01:13:26,590 [Φοιτητής] Pointer + 2; 835 01:13:26,590 --> 01:13:29,350 [Bowden] Έτσι, x + 2. Ναι. 836 01:13:29,350 --> 01:13:31,620 Αυτό πρόκειται να είναι η διεύθυνση. 837 01:13:31,620 --> 01:13:42,810 Θα πρέπει επίσης πολύ συχνά το βλέπουμε ως x [2] και στη συνέχεια, η διεύθυνση αυτού. 838 01:13:42,810 --> 01:13:47,850 Έτσι, θα πρέπει να πάρετε τη διεύθυνση του γιατί ο βραχίονας είναι μια έμμεση dereference. 839 01:13:47,850 --> 01:13:53,250 x [2] αναφέρεται στην αξία που είναι σε αυτό το πλαίσιο, και στη συνέχεια, θέλετε τη διεύθυνση του εν λόγω πλαισίου, 840 01:13:53,250 --> 01:13:56,850 έτσι λέτε & x [2]. 841 01:13:56,850 --> 01:14:02,880 Έτσι, αυτό είναι το πώς κάτι σε είδος συγχώνευσης που θέλετε να περάσει τη μισή λίστα για κάτι 842 01:14:02,880 --> 01:14:08,790 πραγματικά απλά να περάσει & x [2], και τώρα, όσον αφορά την αναδρομική κλήση εκφράζει την ανησυχία της, 843 01:14:08,790 --> 01:14:12,510 νέα σειρά μου αρχίζει εκεί. 844 01:14:12,510 --> 01:14:15,130 Τελευταία ερωτήσεις λεπτό. 845 01:14:15,130 --> 01:14:20,050 [Φοιτητής] Αν δεν τεθεί ένα εμπορικό ή - τι είναι αυτό που ονομάζεται; >> Star; 846 01:14:20,050 --> 01:14:23,200 [Φοιτητής] Star. >> Τεχνικά, χειριστής dereference, αλλά - >> [φοιτητής] Αποαναφορά. 847 01:14:23,200 --> 01:14:29,310 >> Αν δεν βάλετε ένα αστέρι ή ένα εμπορικό, τι θα συμβεί αν πω απλά y = x και x είναι ένας δείκτης; 848 01:14:29,310 --> 01:14:34,620 Ποιος είναι ο τύπος του y; >> [Φοιτητής] Θα πω μόνο ότι ο δείκτης του 2. 849 01:14:34,620 --> 01:14:38,270 Έτσι, αν απλώς να πω y = x, τώρα x και y το σημείο για το ίδιο πράγμα. >> [Φοιτητής] Σημείο για το ίδιο πράγμα. 850 01:14:38,270 --> 01:14:45,180 Και αν το x είναι ένα int pointer; >> Θα διαμαρτύρονται επειδή δεν μπορείτε να εκχωρήσετε δείκτες. 851 01:14:45,180 --> 01:14:46,540 [Φοιτητής] Εντάξει. 852 01:14:46,540 --> 01:14:51,860 Να θυμάστε ότι οι δείκτες, έστω και αν εμείς τους επιστήσει ως βέλη, 853 01:14:51,860 --> 01:15:02,010 πραγματικά όλα αυτά κατάστημα - int * x - x πραγματικά όλα είναι αποθήκευση είναι κάτι σαν ox100, 854 01:15:02,010 --> 01:15:06,490 που τυχαίνει να εκπροσωπεί ως δείχνοντας στο μπλοκ αποθηκεύονται σε 100. 855 01:15:06,490 --> 01:15:19,660 Έτσι, όταν λέω int * y = x? Είμαι απλά αντιγραφή ox100 σε y, 856 01:15:19,660 --> 01:15:24,630 που είμαστε ακριβώς πρόκειται να αντιπροσωπεύουν το y, επίσης δείχνει να ox100. 857 01:15:24,630 --> 01:15:39,810 Και αν πω int i = (int) x? Τότε εγώ πρόκειται να αποθηκεύσετε ό, τι η αξία του είναι ox100 858 01:15:39,810 --> 01:15:45,100 μέσα από αυτό, αλλά τώρα πρόκειται να ερμηνευθεί ως ακέραιο αντί ενός δείκτη. 859 01:15:45,100 --> 01:15:49,310 Αλλά θα πρέπει να έχετε το cast ή αλλιώς θα διαμαρτύρονται. 860 01:15:49,310 --> 01:15:53,300 [Φοιτητής] Έτσι εννοείτε να ρίξει - 861 01:15:53,300 --> 01:16:00,290 Είναι πρόκειται να χύτευση του int x int ή χύτευση του y; 862 01:16:00,290 --> 01:16:03,700 [Bowden] Τι; 863 01:16:03,700 --> 01:16:07,690 [Φοιτητής] Εντάξει. Μετά από αυτές τις παρενθέσεις είναι εκεί πρόκειται να είναι μια χ ή ay εκεί; 864 01:16:07,690 --> 01:16:11,500 >> [Bowden] Είτε. x και y είναι ισοδύναμες. >> [Φοιτητής] Εντάξει. 865 01:16:11,500 --> 01:16:14,390 Επειδή είστε και οι δύο δείκτες. Ναι >>. 866 01:16:14,390 --> 01:16:21,050 [Φοιτητής] Έτσι θα αποθηκεύσει το δεκαεξαδικό 100 σε ακέραια μορφή; >> [Bowden] Ναι. 867 01:16:21,050 --> 01:16:23,620 Αλλά δεν είναι η αξία του ό, τι αυτό δείχνει. 868 01:16:23,620 --> 01:16:29,940 [Bowden] Ναι. >> [Φοιτητής] Έτσι απλά τη διεύθυνση στο ακέραιο μορφή. Εντάξει. 869 01:16:29,940 --> 01:16:34,720 [Bowden] Αν ήθελε να για κάποιο περίεργο λόγο, 870 01:16:34,720 --> 01:16:38,900 θα μπορούσε να ασχοληθεί αποκλειστικά με δείκτες και ποτέ ασχοληθεί με ακέραιους αριθμούς 871 01:16:38,900 --> 01:16:49,240 και απλά να είναι σαν int * x = 0. 872 01:16:49,240 --> 01:16:53,000 Στη συνέχεια θα πάμε για να πάρει πραγματικά μια φορά σύγχυση αριθμητική δείκτη ξεκινά συμβαίνει. 873 01:16:53,000 --> 01:16:56,570 Έτσι, οι αριθμοί που αποθηκεύετε είναι χωρίς νόημα. 874 01:16:56,570 --> 01:16:58,940 Είναι ακριβώς το πώς θα καταλήξετε την ερμηνεία τους. 875 01:16:58,940 --> 01:17:02,920 Έτσι, είμαι ελεύθερος να αντιγράψετε ox100 από έναν int * int σε μια, 876 01:17:02,920 --> 01:17:07,790 και είμαι ελεύθερος να αναθέσει - Μπορείτε πλέον κατά πάσα πιθανότητα πρόκειται να πάρει φώναξε σε casting για μη - 877 01:17:07,790 --> 01:17:18,160 Είμαι ελεύθερος να εκχωρήσετε κάτι σαν (int *) ox1234 σε αυτό το αυθαίρετο * int. 878 01:17:18,160 --> 01:17:25,480 Έτσι ox123 είναι εξίσου έγκυρη μια διεύθυνση μνήμης είναι όπως και y. 879 01:17:25,480 --> 01:17:32,060 & Y συμβαίνει να επιστρέψει κάτι που είναι λίγο πολύ ox123. 880 01:17:32,060 --> 01:17:35,430 [Φοιτητής] Θα ότι είναι ένα πραγματικά δροσερό τρόπο για να πάει από δεκαεξαδικό σε δεκαδική μορφή, 881 01:17:35,430 --> 01:17:39,230 όπως και αν έχετε ένα δείκτη και να το ρίχνει σαν int; 882 01:17:39,230 --> 01:17:44,860 [Bowden] Μπορείτε να εκτυπώσετε πραγματικά ακριβώς όπως τη χρήση printf. 883 01:17:44,860 --> 01:17:50,300 Ας πούμε ότι έχω int y = 100. 884 01:17:50,300 --> 01:18:02,700 Έτσι printf (% d \ n - όπως θα πρέπει ήδη να ξέρετε - ότι εκτυπώσετε ως ένας ακέραιος, χ%. 885 01:18:02,700 --> 01:18:05,190 Θα εκτυπώσετε μόνο ως δεκαεξαδικό. 886 01:18:05,190 --> 01:18:10,760 Έτσι, ένας δείκτης δεν αποθηκεύεται ως δεκαεξαδικό, 887 01:18:10,760 --> 01:18:12,960 και ένας ακέραιος δεν αποθηκεύεται ως δεκαδικά. 888 01:18:12,960 --> 01:18:14,700 Τα πάντα είναι αποθηκευμένα ως δυαδικό. 889 01:18:14,700 --> 01:18:17,950 Είναι απλά ότι έχουμε την τάση να εμφανίζουν δείκτες ως δεκαεξαδικό 890 01:18:17,950 --> 01:18:23,260 γιατί σκεφτόμαστε τα πράγματα σε αυτές τις 4-byte μπλοκ, 891 01:18:23,260 --> 01:18:25,390 και διευθύνσεις μνήμης τείνουν να είναι εξοικειωμένοι. 892 01:18:25,390 --> 01:18:28,890 Είμαστε σαν, αν ξεκινά με bf, τότε συμβαίνει να είναι στη στοίβα. 893 01:18:28,890 --> 01:18:35,560 Έτσι είναι μόνο δική μας ερμηνεία των δεικτών ως δεκαεξαδικό. 894 01:18:35,560 --> 01:18:39,200 Εντάξει. Οι τελευταίες ερωτήσεις; 895 01:18:39,200 --> 01:18:41,700 >> Θα είμαι εδώ για λίγο μετά, αν έχετε κάτι άλλο. 896 01:18:41,700 --> 01:18:46,070 Και αυτό είναι το τέλος αυτού. 897 01:18:46,070 --> 01:18:48,360 >> [Φοιτητής] Yay! [Χειροκροτήματα] 898 01:18:51,440 --> 01:18:53,000 >> [CS50.TV]