1 00:00:00,000 --> 00:00:03,000 [Powered by Google Translate] [Semaine 4] 2 00:00:03,000 --> 00:00:05,000 [David J. Malan] [Université de Harvard] 3 00:00:05,000 --> 00:00:08,000 [C'est CS50.] [CS50.TV] 4 00:00:08,000 --> 00:00:12,000 >> D'accord, ce n'est CS50, et c'est le début de la semaine 4, 5 00:00:12,000 --> 00:00:16,000 et c'est l'un des algorithmes de tri plus lente possible. 6 00:00:16,000 --> 00:00:19,000 Lequel est-ce que nous venons de regarder là-bas? 7 00:00:19,000 --> 00:00:24,000 C'était en quelque sorte de bulle, dans le grand ordre O (n ^ 2) + somme, 8 00:00:24,000 --> 00:00:28,000 et en effet nous ne sommes pas les seuls dans ce monde à l'air de savoir 9 00:00:28,000 --> 00:00:30,000 ce tri à bulles est ou sa durée. 10 00:00:30,000 --> 00:00:33,000 En effet, il s'agissait d'une interview d'Eric Schmidt de Google 11 00:00:33,000 --> 00:00:45,000 et l'ancien sénateur Barack Obama seulement il ya quelques années. 12 00:00:45,000 --> 00:00:48,000 >> Maintenant, sénateur, vous êtes ici chez Google, 13 00:00:48,000 --> 00:00:54,000 et j'aime à penser de la présidence comme un entretien d'embauche. 14 00:00:54,000 --> 00:00:58,000 Maintenant, il est difficile d'obtenir un emploi en tant que président, et vous allez à travers les rigueurs maintenant. 15 00:00:58,000 --> 00:01:00,000 Il est également difficile d'obtenir un emploi chez Google. 16 00:01:00,000 --> 00:01:05,000 Nous avons des questions, et nous demandons à nos questions aux candidats, 17 00:01:05,000 --> 00:01:10,000 et celui-ci est de Larry Schwimmer. 18 00:01:10,000 --> 00:01:14,000 Les gars, vous pensez que je plaisante? C'est juste ici. 19 00:01:14,000 --> 00:01:18,000 Quel est le moyen le plus efficace de trier un million entiers 32 bits? 20 00:01:18,000 --> 00:01:21,000 [Rires] 21 00:01:21,000 --> 00:01:24,000 Bien- 22 00:01:24,000 --> 00:01:26,000 Je suis désolé. >> Non, non, non, non. 23 00:01:26,000 --> 00:01:34,000 Je pense que le tri à bulles serait la bonne façon de faire. 24 00:01:34,000 --> 00:01:39,000 >> Allez, qui lui a dit cela? 25 00:01:39,000 --> 00:01:43,000 La semaine dernière, rappelons nous avons pris une pause de code, au moins pour une journée, 26 00:01:43,000 --> 00:01:46,000 et a commencé à se concentrer sur quelques idées de plus haut niveau et de résolution de problèmes plus généralement 27 00:01:46,000 --> 00:01:49,000 dans le contexte de la recherche et de tri, 28 00:01:49,000 --> 00:01:53,000 et nous avons introduit quelque chose que nous n'avons pas frapper ce nom la semaine dernière, 29 00:01:53,000 --> 00:01:56,000 mais la notation asymptotique, le Big O, l'Oméga Big, 30 00:01:56,000 --> 00:02:00,000 et parfois la notation Big Theta, et ceux-ci étaient simplement des moyens 31 00:02:00,000 --> 00:02:02,000 de décrire le temps d'exécution des algorithmes, 32 00:02:02,000 --> 00:02:05,000 combien de temps cela prend pour un algorithme afin de fonctionner. 33 00:02:05,000 --> 00:02:08,000 >> Et vous vous souviendrez que vous avez parlé du temps de fonctionnement en fonction de la taille 34 00:02:08,000 --> 00:02:11,000 de l'entrée, que nous appelons généralement n, quel que soit le problème peut être, 35 00:02:11,000 --> 00:02:13,000 où n est le nombre de personnes dans la pièce, 36 00:02:13,000 --> 00:02:17,000 le nombre de pages d'un livre de téléphone, et nous avons commencé à écrire des choses sur 37 00:02:17,000 --> 00:02:21,000 comme O (n ^ 2) ou O (n) ou O (n log n), 38 00:02:21,000 --> 00:02:24,000 et même si le calcul n'a pas tout à fait si parfaitement 39 00:02:24,000 --> 00:02:28,000 et il était n ² - n / 2 ou quelque chose comme ça 40 00:02:28,000 --> 00:02:31,000 nous aurions plutôt que simplement jeter quelques-uns des termes d'ordre inférieur, 41 00:02:31,000 --> 00:02:34,000 et la motivation n'y est que nous voulons vraiment une 42 00:02:34,000 --> 00:02:37,000 sorte de manière objective d'évaluer 43 00:02:37,000 --> 00:02:39,000 l'exécution des programmes ou de la performance des algorithmes 44 00:02:39,000 --> 00:02:42,000 que, à la fin de la journée n'a rien à voir, par exemple, 45 00:02:42,000 --> 00:02:45,000 avec la vitesse de votre ordinateur aujourd'hui. 46 00:02:45,000 --> 00:02:47,000 >> Par exemple, si vous implémentez tri à bulles, 47 00:02:47,000 --> 00:02:50,000 ou vous mettre en œuvre le tri par fusion tri ou de sélection sur l'ordinateur d'aujourd'hui, 48 00:02:50,000 --> 00:02:53,000 un ordinateur de 2 GHz, et que vous l'exécutez, 49 00:02:53,000 --> 00:02:56,000 et il faut un certain nombre de secondes, l'année prochaine il ya un 3 GHz 50 00:02:56,000 --> 00:02:59,000 ou un ordinateur 4 GHz, et vous pourriez alors prétendre que "Wow, mon algorithme 51 00:02:59,000 --> 00:03:03,000 est maintenant deux fois plus vite », alors qu'en réalité, ce n'est évidemment pas le cas. 52 00:03:03,000 --> 00:03:06,000 C'est juste que le matériel a obtenu plus rapidement, mais votre ordinateur 53 00:03:06,000 --> 00:03:10,000 n'a pas, et si nous voulons vraiment jeter des choses comme 54 00:03:10,000 --> 00:03:13,000 multiples de 2 ou un multiple de 3 quand il s'agit de décrire les 55 00:03:13,000 --> 00:03:17,000 la rapidité ou la lenteur est un algorithme et vraiment se concentrer uniquement 56 00:03:17,000 --> 00:03:20,000 sur n ou un facteur de celui-ci, 57 00:03:20,000 --> 00:03:24,000 un certain pouvoir de celui-ci comme dans le cas des sortes de la semaine dernière. 58 00:03:24,000 --> 00:03:27,000 Et rappelons que, avec l'aide du tri par fusion 59 00:03:27,000 --> 00:03:31,000 nous avons pu faire beaucoup mieux que tri à bulles et tri par sélection 60 00:03:31,000 --> 00:03:33,000 et même le tri par insertion. 61 00:03:33,000 --> 00:03:36,000 >> Nous sommes descendus à n log n, et encore une fois, 62 00:03:36,000 --> 00:03:39,000 Rappelons que log n désigne généralement quelque chose qui grandit 63 00:03:39,000 --> 00:03:43,000 plus lentement alors n, alors n log n jusqu'ici était bon 64 00:03:43,000 --> 00:03:45,000 car il était inférieur à n ². 65 00:03:45,000 --> 00:03:47,000 Mais pour parvenir à n log n avec tri par fusion 66 00:03:47,000 --> 00:03:51,000 ce qui était le germe d'une idée de base que nous avons eu à effet de levier 67 00:03:51,000 --> 00:03:54,000 que nous avons également mobilisé de retour à la semaine 0? 68 00:03:54,000 --> 00:03:58,000 Comment avons-nous aborder le problème du tri habilement avec tri par fusion? 69 00:03:58,000 --> 00:04:04,000 Quelle a été la clé de vision, peut-être? 70 00:04:04,000 --> 00:04:07,000 N'importe qui. 71 00:04:07,000 --> 00:04:09,000 Bon, prenons un peu de recul. 72 00:04:09,000 --> 00:04:11,000 Décrivez le tri par fusion dans vos propres mots. 73 00:04:11,000 --> 00:04:15,000 Comment at-elle fonctionné? 74 00:04:15,000 --> 00:04:17,000 Bon, nous allons ramer à 0 par semaine. 75 00:04:17,000 --> 00:04:19,000 Ok, ouais. 76 00:04:19,000 --> 00:04:22,000 [Inaudible étudiant] 77 00:04:22,000 --> 00:04:26,000 Bon, bon, si nous avons divisé le tableau de nombres en 2 pièces. 78 00:04:26,000 --> 00:04:29,000 Nous avons classé chacun de ces morceaux, et on les fusionne, 79 00:04:29,000 --> 00:04:33,000 et nous avons vu cette idée avant de prendre un problème qui est ce grand 80 00:04:33,000 --> 00:04:36,000 et hacher dans un problème qui est ce gros ou grand comme ça. 81 00:04:36,000 --> 00:04:38,000 >> Rappelons l'exemple du livre de téléphone. 82 00:04:38,000 --> 00:04:42,000 Rappelons l'algorithme d'auto-comptage des semaines, 83 00:04:42,000 --> 00:04:45,000 tri afin de fusionner a été résumée par cette pseudo ici. 84 00:04:45,000 --> 00:04:48,000 Lorsque vous avez donné n éléments, d'abord c'était test de cohérence. 85 00:04:48,000 --> 00:04:51,000 Si n <2, alors ne rien faire du tout 86 00:04:51,000 --> 00:04:55,000 parce que, si n <2, alors n est égal à 0 ou 1 évidemment, 87 00:04:55,000 --> 00:04:57,000 et donc si c'est 0 ou 1 il n'y a rien à trier. 88 00:04:57,000 --> 00:04:59,000 Vous avez terminé. 89 00:04:59,000 --> 00:05:01,000 Votre liste est déjà triée trivialement. 90 00:05:01,000 --> 00:05:04,000 Mais sinon, si vous avez 2 ou plusieurs éléments aller de l'avant et de les diviser 91 00:05:04,000 --> 00:05:06,000 en 2 moitiés, gauche et droite. 92 00:05:06,000 --> 00:05:09,000 Trier chacune de ces moitiés, puis de fusionner les deux moitiés triés. 93 00:05:09,000 --> 00:05:13,000 Mais le problème ici est que, à première vue, cela se sent comme si nous étions en barque. 94 00:05:13,000 --> 00:05:17,000 Il s'agit d'une définition circulaire que si je vous ai demandé de trier ces n éléments 95 00:05:17,000 --> 00:05:22,000 et vous me dites "Bon, d'accord, nous allons trier les éléments n / 2 et ceux n / 2," 96 00:05:22,000 --> 00:05:27,000 alors ma prochaine question va être «Très bien, comment voulez-vous trier les n / 2 éléments?" 97 00:05:27,000 --> 00:05:30,000 >> Mais en raison de la structure de ce programme, 98 00:05:30,000 --> 00:05:33,000 parce qu'il ya ce scénario de base, pour ainsi dire, 99 00:05:33,000 --> 00:05:39,000 ce cas particulier, qui dit que si n est 00:05:42,000 Ne répondez pas à cette réponse même circulaire. 101 00:05:42,000 --> 00:05:46,000 Ce processus, cette cyclicité finiront. 102 00:05:46,000 --> 00:05:50,000 Si je vous demande "Trier ces n éléments», et vous dites: «Bon, trier ces n / 2," 103 00:05:50,000 --> 00:05:53,000 Ensuite, vous dites: «Bon, trier ces n / 4, n / 8, N/16," 104 00:05:53,000 --> 00:05:56,000 vous finirez par diviser par un nombre assez grand 105 00:05:56,000 --> 00:05:59,000 que vous aurez à seulement 1 élément à gauche, à quel point on peut dire, 106 00:05:59,000 --> 00:06:02,000 «Ici, c'est ici un élément triés unique." 107 00:06:02,000 --> 00:06:06,000 Ensuite, l'éclat de cet algorithme est en place ici pour découlent du fait 108 00:06:06,000 --> 00:06:09,000 qu'une fois que vous avez toutes ces listes triées individuellement, 109 00:06:09,000 --> 00:06:12,000 qui sont tous de taille 1, qui semble être inutile, 110 00:06:12,000 --> 00:06:15,000 une fois que vous commencez à les fusionner et de les fusionner 111 00:06:15,000 --> 00:06:19,000 vous construisez enfin que Rob a fait dans la vidéo une liste triée enfin. 112 00:06:19,000 --> 00:06:22,000 >> Mais cette idée se prolonge bien au-delà de tri. 113 00:06:22,000 --> 00:06:26,000 Il ya cette idée intégré dans ce programme connu sous le nom de récurrence, 114 00:06:26,000 --> 00:06:29,000 l'idée selon laquelle vous êtes un programme, 115 00:06:29,000 --> 00:06:32,000 et de résoudre un problème vous appelez-vous, 116 00:06:32,000 --> 00:06:36,000 ou replacer dans le contexte des langages de programmation que vous êtes une fonction, 117 00:06:36,000 --> 00:06:39,000 et dans le but de résoudre un problème, vous vous appelez la fonction 118 00:06:39,000 --> 00:06:42,000 encore et encore et encore, mais vous la fonction 119 00:06:42,000 --> 00:06:44,000 ne peut pas appeler vous-même un nombre infini de fois. 120 00:06:44,000 --> 00:06:47,000 Finalement, vous devez toucher le fond, pour ainsi dire, 121 00:06:47,000 --> 00:06:49,000 et avoir une certaine condition de base codée en dur qui dit 122 00:06:49,000 --> 00:06:53,000 à ce stade, arrêtez de vous appeler afin que l'ensemble du processus 123 00:06:53,000 --> 00:06:56,000 enfin, en fait, ne s'arrêter. 124 00:06:56,000 --> 00:06:58,000 Qu'est-ce que cela signifie vraiment, à recurse? 125 00:06:58,000 --> 00:07:01,000 >> Voyons voir si nous pouvons faire un exemple simple et trivial avec, par exemple, 126 00:07:01,000 --> 00:07:03,000 3 personnes avec moi jusqu'à ici sur scène, si quelqu'un est à l'aise. 127 00:07:03,000 --> 00:07:06,000 1, viennent sur place, 2 et 3. 128 00:07:06,000 --> 00:07:09,000 Si vous 3 voulez venir ici. 129 00:07:09,000 --> 00:07:12,000 Si vous voulez vous démarquer juste à côté de moi ici en ligne, supposons que le problème à la main 130 00:07:12,000 --> 00:07:15,000 est très trivialement compter le nombre de gens qui sont ici. 131 00:07:15,000 --> 00:07:18,000 Mais franchement, je suis fatigué de tous ces exemples de comptage. 132 00:07:18,000 --> 00:07:21,000 Cela va prendre un certain temps, 1, 2, et le point, point, point. 133 00:07:21,000 --> 00:07:23,000 Ça va prendre une éternité. 134 00:07:23,000 --> 00:07:25,000 Je préfère juste punt ce problème tout à fait avec l'aide de-Quel est votre nom? 135 00:07:25,000 --> 00:07:27,000 Sara. >> Sara, tout droit. 136 00:07:27,000 --> 00:07:29,000 Kelly. >> Kelly et? 137 00:07:29,000 --> 00:07:31,000 >> Willy. >> Willy, Sara, Kelly et Willy. 138 00:07:31,000 --> 00:07:34,000 En ce moment, j'ai posé la question par quelqu'un d' 139 00:07:34,000 --> 00:07:37,000 combien de personnes sont en place sur cette scène, et je n'ai aucune idée. 140 00:07:37,000 --> 00:07:40,000 Il s'agit d'une très longue liste, et ainsi de la place, je vais faire ce truc. 141 00:07:40,000 --> 00:07:43,000 Je vais demander à la personne à côté de moi pour faire la plupart du travail, 142 00:07:43,000 --> 00:07:46,000 et une fois qu'elle se fait faire le gros du travail 143 00:07:46,000 --> 00:07:49,000 Je vais faire le moins de travail possible et juste ajouter 1 144 00:07:49,000 --> 00:07:51,000 à ce que sa réponse est, alors allons-y. 145 00:07:51,000 --> 00:07:54,000 On m'a demandé combien de personnes sont sur scène. 146 00:07:54,000 --> 00:07:57,000 Combien de personnes sont sur scène à gauche de vous? 147 00:07:57,000 --> 00:08:00,000 La gauche de moi? >> D'accord, mais ne triche pas. 148 00:08:00,000 --> 00:08:04,000 C'est bon, c'est bon, mais si nous voulons continuer dans cette logique 149 00:08:04,000 --> 00:08:08,000 supposons que vous voulez même au pays de Pount ce problème à la gauche de vous, 150 00:08:08,000 --> 00:08:11,000 alors plutôt que de répondre directement aller de l'avant et juste renvoyer la balle. 151 00:08:11,000 --> 00:08:14,000 Oh, combien de personnes se trouvent à gauche de moi? 152 00:08:14,000 --> 00:08:16,000 Combien de personnes sont à gauche? 153 00:08:16,000 --> 00:08:18,000 1. 154 00:08:18,000 --> 00:08:27,000 [Rires] 155 00:08:27,000 --> 00:08:30,000 Ok, donc 0, de sorte que maintenant Willy a fait 156 00:08:30,000 --> 00:08:33,000 est que vous avez retourné votre réponse ce sens en disant 0. 157 00:08:33,000 --> 00:08:36,000 Maintenant, que devez-vous faire? >> 1. 158 00:08:36,000 --> 00:08:39,000 Bon, vous êtes le 1, si vous dites: «Bon, je vais ajouter 1 159 00:08:39,000 --> 00:08:41,000 à tout ce qui compte Willy était: «si 1 + 0. 160 00:08:41,000 --> 00:08:43,000 Vous êtes maintenant 1 pour votre réponse à la droite est désormais 161 00:08:43,000 --> 00:08:45,000 1. >> Et le mien serait de 2. 162 00:08:45,000 --> 00:08:48,000 Bon, si vous prenez la réponse précédente de 1, 163 00:08:48,000 --> 00:08:51,000 ajoutant la quantité minimale de travail que vous voulez faire, ce qui est de +1. 164 00:08:51,000 --> 00:08:55,000 Vous avez maintenant 2, et que vous me remettre quelle valeur? 165 00:08:55,000 --> 00:08:57,000 3, je veux dire, je suis désolé, 2. 166 00:08:57,000 --> 00:08:59,000 Bon. 167 00:08:59,000 --> 00:09:02,000 >> Eh bien, nous avons eu 0 à gauche. 168 00:09:02,000 --> 00:09:05,000 Puis nous avons eu 1, puis on ajoute 2, 169 00:09:05,000 --> 00:09:07,000 et maintenant tu me donnant le numéro 2, 170 00:09:07,000 --> 00:09:10,000 et si ce que je dis, ok, +1, 3. 171 00:09:10,000 --> 00:09:13,000 Il ya en effet 3 personnes debout à côté de moi sur cette scène, 172 00:09:13,000 --> 00:09:16,000 de sorte que nous aurions pu évidemment fait cela très linéaire, 173 00:09:16,000 --> 00:09:19,000 beaucoup de la façon évidente, mais qu'avons-nous vraiment faire? 174 00:09:19,000 --> 00:09:21,000 Nous avons pris un problème de taille 3 initialement. 175 00:09:21,000 --> 00:09:24,000 Nous avons ensuite il est tombé en panne à un problème de taille 2, 176 00:09:24,000 --> 00:09:27,000 alors un problème de taille 1, et enfin le scénario de base 177 00:09:27,000 --> 00:09:29,000 C'était vraiment, oh, il n'y a personne là-bas, 178 00:09:29,000 --> 00:09:33,000 à quel point Willy revint effectivement une réponse codée en dur une couple de fois, 179 00:09:33,000 --> 00:09:36,000 et le second a ensuite fait barboter jusqu'à, barboter, barboter, 180 00:09:36,000 --> 00:09:39,000 puis en ajoutant dans ce 1 un supplémentaire 181 00:09:39,000 --> 00:09:41,000 nous avons mis en œuvre cette idée de base de la récursivité. 182 00:09:41,000 --> 00:09:44,000 >> Maintenant, dans ce cas, il n'a pas vraiment résoudre un problème 183 00:09:44,000 --> 00:09:46,000 plus efficace alors que nous avons vu jusqu'à présent. 184 00:09:46,000 --> 00:09:48,000 Mais pensez à les algorithmes que nous avons fait sur scène ce jour. 185 00:09:48,000 --> 00:09:51,000 Nous avons eu 8 morceaux de papier sur le tableau noir, 186 00:09:51,000 --> 00:09:55,000 sur la vidéo quand Sean était à la recherche pour le numéro 7, et qu'at-il vraiment faire? 187 00:09:55,000 --> 00:09:58,000 Eh bien, il n'a pas fait n'importe quel type de diviser pour régner. 188 00:09:58,000 --> 00:10:01,000 Il n'a pas fait n'importe quel type de récursivité. 189 00:10:01,000 --> 00:10:03,000 Au contraire, il vient de faire cet algorithme linéaire. 190 00:10:03,000 --> 00:10:07,000 Mais lorsque nous avons lancé l'idée de numéros triés sur scène en direct la semaine dernière 191 00:10:07,000 --> 00:10:09,000 puis nous avons eu cet instinct d'aller vers le centre, 192 00:10:09,000 --> 00:10:13,000 à quel point nous avons eu une petite liste de taille 4 ou d'une autre liste de taille 4, 193 00:10:13,000 --> 00:10:17,000 et puis nous avons eu exactement le même problème, donc nous avons répété, répété, répété. 194 00:10:17,000 --> 00:10:19,000 En d'autres termes, nous recursed. 195 00:10:19,000 --> 00:10:24,000 Merci beaucoup à nos 3 bénévoles ici pour démontrer la récursivité avec nous. 196 00:10:24,000 --> 00:10:28,000 >> Voyons voir si nous ne pouvons pas faire cela maintenant un peu plus concrète, 197 00:10:28,000 --> 00:10:30,000 résoudre un problème nouveau que nous pouvions faire assez facilement, 198 00:10:30,000 --> 00:10:34,000 mais nous allons l'utiliser comme un tremplin pour la mise en œuvre de cette idée de base. 199 00:10:34,000 --> 00:10:37,000 Si je veux calculer la somme d'une série de chiffres, 200 00:10:37,000 --> 00:10:39,000 Par exemple, si vous passez dans le numéro 3, 201 00:10:39,000 --> 00:10:42,000 Je veux vous donner la valeur de sigma 3, 202 00:10:42,000 --> 00:10:46,000 de sorte que la somme de 3 + 2 + 1 + 0. 203 00:10:46,000 --> 00:10:48,000 Je veux revenir la réponse 6, 204 00:10:48,000 --> 00:10:51,000 donc nous allons implémenter cette fonction sigma, cette fonction de sommation 205 00:10:51,000 --> 00:10:54,000 que, de plus, prend en entrée, puis retourne la somme 206 00:10:54,000 --> 00:10:57,000 de ce nombre tout en bas à 0. 207 00:10:57,000 --> 00:10:59,000 Nous pourrions le faire assez simplement, non? 208 00:10:59,000 --> 00:11:01,000 Nous pourrions le faire avec une sorte de structure en boucle, 209 00:11:01,000 --> 00:11:04,000 alors laissez-moi aller de l'avant et obtenir cela a commencé. 210 00:11:04,000 --> 00:11:07,000 >> Inclure stdio.h. 211 00:11:07,000 --> 00:11:09,000 Permettez-moi de me mettre en principal de travailler ici. 212 00:11:09,000 --> 00:11:12,000 Sauvons ce que sigma.c. 213 00:11:12,000 --> 00:11:14,000 Alors je vais aller ici, et je vais déclarer un int n, 214 00:11:14,000 --> 00:11:18,000 et je vais faire ce qui suit pendant que l'utilisateur ne coopère pas. 215 00:11:18,000 --> 00:11:22,000 Pendant que l'utilisateur ne m'a pas donné un nombre positif 216 00:11:22,000 --> 00:11:26,000 laissez-moi aller de l'avant et de les inviter pour n = getInt, 217 00:11:26,000 --> 00:11:28,000 et permettez-moi de donner quelques instructions sur ce qu'il faut faire, 218 00:11:28,000 --> 00:11:33,000 de sorte printf ("Entier positif s'il vous plaît"). 219 00:11:33,000 --> 00:11:39,000 Juste une chose relativement simple comme celui-ci de sorte qu'au moment où nous avons atteint la ligne 14 220 00:11:39,000 --> 00:11:42,000 nous avons maintenant un nombre entier positif sans doute au n. 221 00:11:42,000 --> 00:11:44,000 >> Maintenant, nous allons faire quelque chose avec elle. 222 00:11:44,000 --> 00:11:50,000 Permettez-moi aller de l'avant et de calculer la somme, alors int somme = sigma (n). 223 00:11:50,000 --> 00:11:54,000 Sigma est juste sommation, alors je vais juste écrire dans l'amateur moyen. 224 00:11:54,000 --> 00:11:56,000 Nous allons l'appeler sigma là. 225 00:11:56,000 --> 00:11:58,000 C'est la somme, et maintenant je vais imprimer le résultat, 226 00:11:58,000 --> 00:12:08,000 printf ("La somme est% d \ n", somme). 227 00:12:08,000 --> 00:12:11,000 Et puis je vais retourner 0 pour faire bonne mesure. 228 00:12:11,000 --> 00:12:15,000 Nous avons fait tout ce que ce programme nécessite l'exception de la partie la plus intéressante, 229 00:12:15,000 --> 00:12:18,000 qui est en fait de mettre en œuvre la fonction sigma. 230 00:12:18,000 --> 00:12:22,000 >> Permettez-moi de descendre ici vers le bas, et laissez-moi déclarer la fonction sigma. 231 00:12:22,000 --> 00:12:26,000 Il faut que ça prend une variable qui est de type entier, 232 00:12:26,000 --> 00:12:30,000 et quel type de données que je veux revenir sans doute à partir de sigma? 233 00:12:30,000 --> 00:12:34,000 Int, parce que je veux qu'il corresponde à mes attentes sur la ligne 15. 234 00:12:34,000 --> 00:12:37,000 Ici laissez-moi aller de l'avant et de mettre en œuvre cette 235 00:12:37,000 --> 00:12:41,000 d'une manière assez simple. 236 00:12:41,000 --> 00:12:45,000 >> Allons de l'avant et de dire la somme int = 0, 237 00:12:45,000 --> 00:12:47,000 et maintenant je vais avoir un peu de boucle ici 238 00:12:47,000 --> 00:12:50,000 qui va dire quelque chose comme ça, 239 00:12:50,000 --> 00:13:01,000 for (int i = 0; I <= nombre; i + +) somme + = i. 240 00:13:01,000 --> 00:13:05,000 Et puis je vais revenir somme. 241 00:13:05,000 --> 00:13:07,000 J'aurais pu en œuvre cette dans un certain nombre de façons. 242 00:13:07,000 --> 00:13:09,000 J'aurais pu utiliser une boucle while. 243 00:13:09,000 --> 00:13:11,000 J'aurais pu sauter en utilisant la variable somme si je voulais vraiment, 244 00:13:11,000 --> 00:13:15,000 mais en bref, nous avons seulement une fonction que si je n'ai pas gaffe déclare somme est 0. 245 00:13:15,000 --> 00:13:18,000 Puis il parcourt de 0 sur place par le nombre, 246 00:13:18,000 --> 00:13:23,000 et sur chaque itération, il ajoute que la valeur actuelle de la somme, puis retourne la somme. 247 00:13:23,000 --> 00:13:25,000 >> Maintenant, il ya une légère optimisation ici. 248 00:13:25,000 --> 00:13:29,000 C'est probablement une étape gaspillée, mais ainsi soit-il. C'est très bien pour l'instant. 249 00:13:29,000 --> 00:13:32,000 Nous sommes au moins d'être approfondie et va 0 tout le chemin sur un maximum. 250 00:13:32,000 --> 00:13:34,000 Pas très dur et assez simple, 251 00:13:34,000 --> 00:13:37,000 mais il s'avère que la fonction sigma nous avons la possibilité même 252 00:13:37,000 --> 00:13:39,000 comme nous l'avons fait ici sur scène. 253 00:13:39,000 --> 00:13:42,000 Sur la scène que nous venons compté combien de personnes étaient à côté de moi, 254 00:13:42,000 --> 00:13:47,000 mais si l'on voulait compter le nombre 3 + 2 + 1 255 00:13:47,000 --> 00:13:51,000 sur le bas à 0 que nous pouvions même plate à une fonction 256 00:13:51,000 --> 00:13:55,000 que je vais plutôt décrire comme étant récursif. 257 00:13:55,000 --> 00:13:57,000 Ici, nous allons faire un rapide check santé mentale et assurez-vous que je n'ai pas gaffe. 258 00:13:57,000 --> 00:14:00,000 >> Je sais qu'il ya au moins une chose dans ce programme que je n'ai fait de mal. 259 00:14:00,000 --> 00:14:04,000 Quand j'ai frappé entrer vais-je obtenir toute sorte de me crier dessus? 260 00:14:04,000 --> 00:14:06,000 Que vais-je faire engueuler à propos? 261 00:14:06,000 --> 00:14:11,000 Ouais, j'ai oublié le prototype, donc je suis en utilisant une fonction appelée sigma sur la ligne 15, 262 00:14:11,000 --> 00:14:16,000 mais ce n'est pas déclaré avant la ligne 22, donc je meilleure façon proactive monter ici 263 00:14:16,000 --> 00:14:22,000 et de déclarer un prototype, et je dirai int sigma (nombre entier), et c'est tout. 264 00:14:22,000 --> 00:14:24,000 Il est mis en œuvre par le bas. 265 00:14:24,000 --> 00:14:27,000 >> Ou d'une autre façon, je pouvais résoudre ce problème, 266 00:14:27,000 --> 00:14:30,000 Je pourrais passer la fonction de là-haut, ce qui n'est pas mauvais, 267 00:14:30,000 --> 00:14:32,000 mais au moins quand vos programmes commencent à devenir long, franchement, 268 00:14:32,000 --> 00:14:35,000 Je pense qu'il ya une certaine valeur en ayant toujours principal en haut 269 00:14:35,000 --> 00:14:38,000 de sorte que vous dans le lecteur peut ouvrir le fichier et puis tout de suite voir 270 00:14:38,000 --> 00:14:40,000 ce que le programme fait sans avoir à chercher dans l' 271 00:14:40,000 --> 00:14:42,000 la recherche de cette fonction principale. 272 00:14:42,000 --> 00:14:49,000 Descendons à ma fenêtre de terminal ici, essayez de faire sigma sigma faire, 273 00:14:49,000 --> 00:14:51,000 et j'ai foiré ici aussi. 274 00:14:51,000 --> 00:14:55,000 Déclaration implicite de la fonction getInt signifie que j'ai oublié de faire quoi d'autre? 275 00:14:55,000 --> 00:14:57,000 [Inaudible étudiant] 276 00:14:57,000 --> 00:15:00,000 Bon, donc apparemment une erreur commune, nous allons donc mettre ce là-haut, 277 00:15:00,000 --> 00:15:04,000 cs50.h, et maintenant, revenons à ma fenêtre de terminal. 278 00:15:04,000 --> 00:15:08,000 >> Je vais effacer l'écran, et je vais relancer faire sigma. 279 00:15:08,000 --> 00:15:11,000 Il semble avoir compilé. Laisse-moi courir sigma. 280 00:15:11,000 --> 00:15:15,000 Je vais saisir le numéro 3, et je n'ai obtenez 6, donc pas un contrôle rigoureux, 281 00:15:15,000 --> 00:15:18,000 mais au moins il semble fonctionner à première vue, mais maintenant nous allons le déchirer, 282 00:15:18,000 --> 00:15:21,000 et nous allons tirer parti de fait l'idée de la récursivité, encore une fois, 283 00:15:21,000 --> 00:15:24,000 dans un contexte très simple de sorte que dans quelques semaines " 284 00:15:24,000 --> 00:15:27,000 quand nous commençons à explorer les structures de données plus fantaisistes que les tableaux 285 00:15:27,000 --> 00:15:30,000 nous avons un autre outil dans la boîte à outils avec lesquels 286 00:15:30,000 --> 00:15:33,000 manipuler ces structures de données comme nous le verrons. 287 00:15:33,000 --> 00:15:36,000 C'est l'approche itérative, l'approche à base de boucles. 288 00:15:36,000 --> 00:15:39,000 >> Permettez-moi maintenant plutôt le faire. 289 00:15:39,000 --> 00:15:44,000 Permettez-moi de dire à la place que la somme du nombre 290 00:15:44,000 --> 00:15:48,000 sur le bas à 0 est vraiment la même chose que 291 00:15:48,000 --> 00:15:53,000 + numéro sigma (nombre - 1). 292 00:15:53,000 --> 00:15:57,000 En d'autres termes, tout comme sur scène, je comptèrent sur le hasard pour chacune des personnes à côté de moi, 293 00:15:57,000 --> 00:16:00,000 et à leur tour en barque maintenu jusqu'à ce que nous touché le fond à Willy, 294 00:16:00,000 --> 00:16:03,000 qui a dû retourner une réponse codée en dur comme 0. 295 00:16:03,000 --> 00:16:07,000 Voici maintenant nous sommes même barque au sigma 296 00:16:07,000 --> 00:16:10,000 la même fonction que s'appelait à l'origine, mais l'idée fondamentale ici 297 00:16:10,000 --> 00:16:12,000 est que nous ne demandons pas sigma identique. 298 00:16:12,000 --> 00:16:14,000 Nous ne sommes pas passer au n. 299 00:16:14,000 --> 00:16:17,000 Nous sommes clairement en passant en nombre - 1, 300 00:16:17,000 --> 00:16:20,000 si un problème un peu plus petit, un peu plus petit problème. 301 00:16:20,000 --> 00:16:23,000 >> Malheureusement, ce n'est pas tout à fait une solution encore, et avant de nous fixons 302 00:16:23,000 --> 00:16:26,000 ce qui pourrait être sauter aussi évident à certains d'entre vous 303 00:16:26,000 --> 00:16:28,000 laissez-moi aller de l'avant et réexécutez: make. 304 00:16:28,000 --> 00:16:30,000 Il semble compiler bien. 305 00:16:30,000 --> 00:16:32,000 Permettez-moi de relancer sigma avec 6. 306 00:16:32,000 --> 00:16:37,000 Oups, permettez-moi de relancer sigma avec 6. 307 00:16:37,000 --> 00:16:42,000 Nous avons vu cela avant, mais le temps accidentellement dernière aussi. 308 00:16:42,000 --> 00:16:48,000 Pourquoi ai-je cette erreur de segmentation cryptique? Ouais. 309 00:16:48,000 --> 00:16:50,000 [Inaudible étudiant] 310 00:16:50,000 --> 00:16:53,000 Il n'y a aucun cas de base, et plus précisément, ce qui est probablement arrivé? 311 00:16:53,000 --> 00:16:58,000 Il s'agit d'un symptôme de ce comportement? 312 00:16:58,000 --> 00:17:00,000 Dites-le un peu plus fort. 313 00:17:00,000 --> 00:17:02,000 [Inaudible étudiant] 314 00:17:02,000 --> 00:17:05,000 C'est une boucle infinie efficace, et le problème avec les boucles infinies 315 00:17:05,000 --> 00:17:08,000 quand elles impliquent la récursivité dans ce cas, une fonction qui se fait appeler, 316 00:17:08,000 --> 00:17:10,000 ce qui se passe à chaque fois que vous appelez une fonction? 317 00:17:10,000 --> 00:17:13,000 Eh bien, pensez à la façon dont nous avons établi la mémoire dans un ordinateur. 318 00:17:13,000 --> 00:17:16,000 Nous avons dit qu'il ya ce morceau de mémoire appelée la pile qui se trouve en bas, 319 00:17:16,000 --> 00:17:19,000 et chaque fois que vous appelez une fonction de mémoire un peu plus se mettre 320 00:17:19,000 --> 00:17:24,000 sur cette dite pile contenant des variables locales de cette fonction ou de paramètres, 321 00:17:24,000 --> 00:17:27,000 si sigma sigma sigma appelle des appels appelle sigma 322 00:17:27,000 --> 00:17:29,000  appelle sigma où vient cette fin de l'histoire? 323 00:17:29,000 --> 00:17:31,000 >> Eh bien, il finit par le montant total des dépassements 324 00:17:31,000 --> 00:17:33,000 de mémoire dont vous disposez sur votre ordinateur. 325 00:17:33,000 --> 00:17:37,000 Vous envahi le segment que vous êtes censé rester à l'intérieur, 326 00:17:37,000 --> 00:17:40,000 et vous obtenez cette erreur de segmentation, core dumped, 327 00:17:40,000 --> 00:17:43,000 et ce core dumped signifie, c'est que j'ai maintenant un fichier appelé core 328 00:17:43,000 --> 00:17:46,000 qui est un fichier contenant des zéros et des uns 329 00:17:46,000 --> 00:17:49,000 qui fait à l'avenir sera utile au diagnostic. 330 00:17:49,000 --> 00:17:52,000 Si ce n'est pas évident pour vous où votre bogue est 331 00:17:52,000 --> 00:17:54,000 vous pouvez réellement faire un peu d'analyse médico-légale, pour ainsi dire, 332 00:17:54,000 --> 00:17:58,000 sur ce fichier core dump, ce qui, encore une fois, c'est juste un tas de zéros et de uns 333 00:17:58,000 --> 00:18:02,000 qui représente l'essentiel de l'état de votre programme dans la mémoire 334 00:18:02,000 --> 00:18:05,000 le moment où il s'est écrasé dans cette voie. 335 00:18:05,000 --> 00:18:11,000 >> La solution ici est que nous ne pouvons pas aveuglément retourner sigma, 336 00:18:11,000 --> 00:18:14,000 le nombre + sigma d'un problème légèrement plus petit. 337 00:18:14,000 --> 00:18:16,000 Nous avons besoin d'une sorte de scénario de base ici, 338 00:18:16,000 --> 00:18:19,000 et quel devrait être le cas de base sans doute? 339 00:18:19,000 --> 00:18:22,000 [Inaudible étudiant] 340 00:18:22,000 --> 00:18:25,000 Bon, tant que le nombre est positif nous devrions renvoyer ce, 341 00:18:25,000 --> 00:18:29,000 ou, autrement dit, si le nombre est, par exemple, <= à 0 342 00:18:29,000 --> 00:18:32,000 vous savez quoi, je vais aller de l'avant et retourner 0, 343 00:18:32,000 --> 00:18:36,000 un peu comme Willy a fait, et le reste, je vais aller de l'avant 344 00:18:36,000 --> 00:18:41,000 et retourner ce, donc ce n'est pas que beaucoup plus courte 345 00:18:41,000 --> 00:18:44,000 que la version itérative que nous attisé la première utilisation d'une boucle for, 346 00:18:44,000 --> 00:18:48,000 mais remarquez qu'il ya cette sorte d'élégance à elle. 347 00:18:48,000 --> 00:18:51,000 Au lieu de renvoyer un certain nombre et l'exécution de toutes ces maths 348 00:18:51,000 --> 00:18:54,000 et en ajoutant les choses avec des variables locales 349 00:18:54,000 --> 00:18:57,000 vous êtes au lieu dit «Bon, si c'est un problème très facile, 350 00:18:57,000 --> 00:19:01,000 comme le nombre est <0, permettez-moi de revenir immédiatement à 0. " 351 00:19:01,000 --> 00:19:03,000 >> Nous n'allons pas prendre la peine de soutien nombres négatifs, 352 00:19:03,000 --> 00:19:05,000 donc je vais coder en dur la valeur de 0. 353 00:19:05,000 --> 00:19:08,000 Mais sinon, pour mettre en œuvre cette idée de sommation 354 00:19:08,000 --> 00:19:11,000 tous ces chiffres ensemble, vous pouvez effectivement prendre une petite bouchée 355 00:19:11,000 --> 00:19:14,000 sortir de ce problème, tout comme nous l'avons fait ici, sur scène, 356 00:19:14,000 --> 00:19:18,000 ensuite botté le reste du problème à la personne suivante, 357 00:19:18,000 --> 00:19:20,000 mais dans ce cas la prochaine personne, c'est vous. 358 00:19:20,000 --> 00:19:22,000 C'est une fonction portant le même nom. 359 00:19:22,000 --> 00:19:25,000 Il suffit de passer ce un problème de plus en plus petits et plus petits à chaque fois, 360 00:19:25,000 --> 00:19:28,000 et même si nous n'avons pas des choses assez formalisées dans le code ici 361 00:19:28,000 --> 00:19:33,000 c'est exactement ce qui se passait à la semaine 0 avec l'annuaire. 362 00:19:33,000 --> 00:19:36,000 C'est exactement ce qui se passait dans les dernières semaines avec Sean 363 00:19:36,000 --> 00:19:39,000 et avec nos démonstrations de chercher des numéros. 364 00:19:39,000 --> 00:19:42,000 C'est en prenant un problème et en le divisant encore et encore. 365 00:19:42,000 --> 00:19:44,000 >> En d'autres termes, il existe un moyen maintenant de traduire 366 00:19:44,000 --> 00:19:47,000 cette construction du monde réel, ce concept de niveau supérieur 367 00:19:47,000 --> 00:19:51,000 de diviser pour régner et faire quelque chose de nouveau et de nouveau 368 00:19:51,000 --> 00:19:56,000 dans le code, donc c'est quelque chose que nous verrons à nouveau au fil du temps. 369 00:19:56,000 --> 00:20:00,000 Maintenant, en passant, si vous êtes nouveau récurrence que vous devriez au moins savoir maintenant 370 00:20:00,000 --> 00:20:02,000 pourquoi c'est drôle. 371 00:20:02,000 --> 00:20:05,000 Je vais aller à google.com, 372 00:20:05,000 --> 00:20:17,000 et je vais chercher quelques trucs et astuces sur la récursivité, entrez. 373 00:20:17,000 --> 00:20:21,000 Dites à la personne à côté de vous si elles n'étaient pas rire tout à l'heure. 374 00:20:21,000 --> 00:20:23,000 Vouliez-vous dire récursion? 375 00:20:23,000 --> 00:20:25,000 Vouliez-vous dire, ah, voilà. 376 00:20:25,000 --> 00:20:28,000 Bon, maintenant que c'est le reste du monde. 377 00:20:28,000 --> 00:20:30,000 Un oeuf de Pâques peu intégré quelque part dans Google. 378 00:20:30,000 --> 00:20:33,000 Soit dit en passant, l'un des liens que nous mettons sur le site Web du cours 379 00:20:33,000 --> 00:20:36,000 d'aujourd'hui est tout simplement cette grille de différents algorithmes de tri, 380 00:20:36,000 --> 00:20:39,000 certaines d'entre elles, nous avons examiné la semaine dernière, mais ce qui est bien à propos de cette visualisation 381 00:20:39,000 --> 00:20:43,000 que vous essayez d'envelopper votre esprit autour de diverses choses liées à des algorithmes 382 00:20:43,000 --> 00:20:46,000 sachez que vous pouvez très facilement maintenant commencer avec différents types d'entrées. 383 00:20:46,000 --> 00:20:50,000 Les entrées inversée toutes les entrées triées surtout, les entrées aléatoire et ainsi de suite. 384 00:20:50,000 --> 00:20:53,000 Comme vous tenter, encore une fois, la distinction entre ces choses dans votre esprit 385 00:20:53,000 --> 00:20:57,000 se rendre compte que cette URL sur le site Web du cours sur la page Conférences 386 00:20:57,000 --> 00:21:00,000 pourrait vous aider à raison par certains d'entre eux. 387 00:21:00,000 --> 00:21:05,000 >> Aujourd'hui, nous arrivons finalement à résoudre le problème depuis un certain temps, 388 00:21:05,000 --> 00:21:08,000 qui était que cette fonction d'échange n'a pas fonctionné, 389 00:21:08,000 --> 00:21:12,000 et quel était le problème fondamental de ce swap fonction, 390 00:21:12,000 --> 00:21:15,000 dont le but était, encore une fois, d'échanger une valeur ici et ici 391 00:21:15,000 --> 00:21:17,000 de sorte que ce qui se passe? 392 00:21:17,000 --> 00:21:20,000 Cela n'a pas réellement. Pourquoi? 393 00:21:20,000 --> 00:21:22,000 Ouais. 394 00:21:22,000 --> 00:21:28,000 [Inaudible étudiant] 395 00:21:28,000 --> 00:21:31,000 Justement, l'explication de cette bugginess 396 00:21:31,000 --> 00:21:34,000 tout simplement parce que lorsque vous appelez des fonctions en C 397 00:21:34,000 --> 00:21:38,000 et ces fonctions prennent des arguments, comme a et b ici, 398 00:21:38,000 --> 00:21:42,000 vous êtes de passage dans les copies de n'importe quelle valeur que vous fournissez à cette fonction. 399 00:21:42,000 --> 00:21:46,000 Vous ne fournissent pas les valeurs d'origine eux-mêmes, 400 00:21:46,000 --> 00:21:49,000 donc nous avons vu cela dans le contexte de buggyc, 401 00:21:49,000 --> 00:21:52,000 buggy3.c, qui avait l'air un petit quelque chose comme ça. 402 00:21:52,000 --> 00:21:57,000 >> Rappelez-vous que nous avons eu x et y initialisé à 1 et 2, respectivement. 403 00:21:57,000 --> 00:21:59,000 Nous avons ensuite imprimée sur ce qu'ils étaient. 404 00:21:59,000 --> 00:22:03,000 J'ai alors déclaré que je les échanger par téléphone au swap de x, y. 405 00:22:03,000 --> 00:22:06,000 Mais le problème était que l'échange a travaillé, 406 00:22:06,000 --> 00:22:10,000 mais seulement dans le cadre de l'échange lui-même fonctionner. 407 00:22:10,000 --> 00:22:13,000 Dès que nous avons atteint la ligne 40 de ces valeurs échangées 408 00:22:13,000 --> 00:22:16,000 ont été jetés, et donc rien 409 00:22:16,000 --> 00:22:21,000 dans l'origine la principale fonction était réellement changé du tout, 410 00:22:21,000 --> 00:22:26,000 donc si vous pensez à l'époque à quoi cela ressemble sur le plan de notre mémoire 411 00:22:26,000 --> 00:22:29,000 si ce côté gauche de la carte représente- 412 00:22:29,000 --> 00:22:33,000 et je ferai de mon mieux pour tout le monde de voir ce si celui-ci côté gauche de la carte 413 00:22:33,000 --> 00:22:37,000 représente, par exemple, votre mémoire vive, et la pile va se développer sur de cette façon, 414 00:22:37,000 --> 00:22:43,000 et que nous appelons une fonction comme principal et principal dispose de 2 variables locales x et y, 415 00:22:43,000 --> 00:22:48,000 nous allons décrire ceux que x ici, et nous allons les décrire comme y ici, 416 00:22:48,000 --> 00:22:55,000 et il faut mettre dans les valeurs 1 et 2, si ce n'est ici principal, 417 00:22:55,000 --> 00:22:58,000 et quand principale appelle la fonction d'échange du système d'exploitation 418 00:22:58,000 --> 00:23:02,000 donne la fonction de permutation son propre andain de mémoire sur la pile, 419 00:23:02,000 --> 00:23:04,000 son propre cadre sur la pile, pour ainsi dire. 420 00:23:04,000 --> 00:23:08,000 Elle alloue également 32 bits pour ces ints. 421 00:23:08,000 --> 00:23:11,000 Il arrive de les appeler a et b, mais c'est totalement arbitraire. 422 00:23:11,000 --> 00:23:13,000 Il aurait pu les appelait tout ce qu'il veut, mais ce qui arrive quand principale 423 00:23:13,000 --> 00:23:19,000 Swap appels est qu'il faut ce 1, place une copie là, il met une copie. 424 00:23:19,000 --> 00:23:23,000 >> Il ya 1 autre variable locale dans la pagination, mais, s'appelle comment? >> Tmp. 425 00:23:23,000 --> 00:23:27,000 Tmp, alors laissez-moi me donner un autre 32 bits ici, 426 00:23:27,000 --> 00:23:29,000 et qu'est-ce que je fais dans cette fonction? 427 00:23:29,000 --> 00:23:34,000 J'ai dit tmp int obtient un, donc un a 1, ce que j'ai fait lorsque nous avons joué la dernière fois avec cet exemple. 428 00:23:34,000 --> 00:23:39,000 Ensuite, un obtient b, alors b est 2, alors maintenant cela devient 2, 429 00:23:39,000 --> 00:23:42,000 et maintenant b obtient temp, temp est donc 1, 430 00:23:42,000 --> 00:23:44,000 alors maintenant b devient cela. 431 00:23:44,000 --> 00:23:46,000 C'est très bien. Il a travaillé. 432 00:23:46,000 --> 00:23:49,000 Mais dès que la fonction retourne 433 00:23:49,000 --> 00:23:52,000 mémoire swap disparaît de manière efficace afin qu'il puisse être réutilisé 434 00:23:52,000 --> 00:23:58,000 par une autre fonction dans le futur, et principal est bien évidemment totalement inchangé. 435 00:23:58,000 --> 00:24:00,000 Nous devons trouver un moyen de résoudre ce problème fondamental, 436 00:24:00,000 --> 00:24:03,000 et aujourd'hui, nous allons enfin avoir un moyen de le faire où 437 00:24:03,000 --> 00:24:06,000 nous pouvons introduire quelque chose qui s'appelle un pointeur. 438 00:24:06,000 --> 00:24:09,000 Il s'avère que nous pouvons résoudre ce problème 439 00:24:09,000 --> 00:24:12,000 pas par passage dans des copies de x et y 440 00:24:12,000 --> 00:24:18,000 mais en passant quoi, pensez-vous, à la fonction d'échange? 441 00:24:18,000 --> 00:24:20,000 Ouais, qu'en est-il l'adresse? 442 00:24:20,000 --> 00:24:22,000 Nous n'avons pas vraiment parlé des adresses dans beaucoup de détails, 443 00:24:22,000 --> 00:24:25,000 mais si ce tableau représente la mémoire de mon ordinateur 444 00:24:25,000 --> 00:24:28,000 nous pourrions certainement commencer la numérotation des octets dans ma RAM 445 00:24:28,000 --> 00:24:31,000 et dire que c'est l'octet # 1, c'est l'octet # 2, # 3 octets, 446 00:24:31,000 --> 00:24:35,000 N ° 4 octets, l'octet # ... 2 milliards d'euros si je dispose de 2 Go de RAM, 447 00:24:35,000 --> 00:24:38,000 si nous pourrions certainement trouver quelque régime arbitraire de numérotation 448 00:24:38,000 --> 00:24:41,000 pour tous les octets individuels dans la mémoire de mon ordinateur. 449 00:24:41,000 --> 00:24:43,000 >> Et si au lieu de swap quand je l'appelle 450 00:24:43,000 --> 00:24:47,000 plutôt que de passer à des copies de x et y 451 00:24:47,000 --> 00:24:51,000 pourquoi ne puis-je pas plutôt passer à l'adresse de x ici, 452 00:24:51,000 --> 00:24:55,000 l'adresse de y ici, essentiellement l'adresse postale 453 00:24:55,000 --> 00:24:59,000 de x et y, car alors échanger, s'il est informé 454 00:24:59,000 --> 00:25:01,000 de l'adresse dans la mémoire de x et y, 455 00:25:01,000 --> 00:25:04,000 alors échanger, si nous avons formé lui un peu, 456 00:25:04,000 --> 00:25:07,000 il pourrait conduire à cette adresse, pour ainsi dire, 457 00:25:07,000 --> 00:25:11,000 x et y modifier le numéro, puis route vers l'adresse de y, 458 00:25:11,000 --> 00:25:16,000 changer le numéro de là, même s'il n'est pas réellement obtenir des copies de ces valeurs lui-même, 459 00:25:16,000 --> 00:25:19,000 ainsi, même si nous en avons parlé comme étant la mémoire principale 460 00:25:19,000 --> 00:25:23,000 et cet échange comme étant la mémoire des puissants et la partie dangereuse de C 461 00:25:23,000 --> 00:25:28,000 est une fonction qui peut toucher n'importe où dans la mémoire de l'ordinateur, 462 00:25:28,000 --> 00:25:32,000 et c'est puissant que vous pouvez faire des choses très chics avec des programmes informatiques en C 463 00:25:32,000 --> 00:25:36,000 C'est dangereux parce que vous pouvez également visser en place très facilement. 464 00:25:36,000 --> 00:25:39,000 En fait, l'une des façons les plus communes pour les programmes de nos jours à être exploitée 465 00:25:39,000 --> 00:25:42,000 est encore pour un programmeur de ne pas se rendre compte 466 00:25:42,000 --> 00:25:45,000 qu'il ou elle est un ensemble de données permettant 467 00:25:45,000 --> 00:25:49,000 à écrire dans un emplacement mémoire qui n'a pas été prévu. 468 00:25:49,000 --> 00:25:51,000 >> Par exemple, il ou elle déclare un tableau de taille 10 469 00:25:51,000 --> 00:25:56,000 mais essaie de mettre accidentellement 11 octets dans ce tableau de la mémoire, 470 00:25:56,000 --> 00:25:59,000 et vous commencez à toucher des parties de la mémoire qui ne sont plus valables. 471 00:25:59,000 --> 00:26:02,000 Juste à ce contexte, certains d'entre vous savez peut-être que 472 00:26:02,000 --> 00:26:06,000 le logiciel vous entraîne souvent des numéros de série ou les clés d'enregistrement, 473 00:26:06,000 --> 00:26:08,000 Photoshop et Word et des programmes de ce genre. 474 00:26:08,000 --> 00:26:12,000 Il existe des fissures, comme certains d'entre vous le savez, en ligne où vous pouvez exécuter un petit programme, 475 00:26:12,000 --> 00:26:14,000 et voila, pas plus d'une demande de numéro de série. 476 00:26:14,000 --> 00:26:16,000 Comment est-ce de travail? 477 00:26:16,000 --> 00:26:21,000 Dans de nombreux cas, ces choses sont tout simplement trouver dans les ordinateurs 478 00:26:21,000 --> 00:26:24,000 segments de texte dans zéros réels de l'ordinateur et ceux 479 00:26:24,000 --> 00:26:28,000 où est cette fonction où le numéro de série est demandé, 480 00:26:28,000 --> 00:26:31,000 et vous écrasez l'espace, ou alors que le programme est en cours d'exécution 481 00:26:31,000 --> 00:26:33,000 vous pouvez savoir où la clé est en fait stocké 482 00:26:33,000 --> 00:26:37,000 en utilisant ce qu'on appelle un débogueur, et vous pouvez craquer logiciels de cette façon. 483 00:26:37,000 --> 00:26:40,000 Cela ne veut pas dire que c'est notre objectif pour les deux prochains jours, 484 00:26:40,000 --> 00:26:42,000 mais il a de très réelles conséquences. 485 00:26:42,000 --> 00:26:45,000 Que l'on arrive à impliquer le vol de logiciels, 486 00:26:45,000 --> 00:26:47,000 mais il ya aussi des compromis machines complètes. 487 00:26:47,000 --> 00:26:50,000 >> En fait, lorsque les sites Web de nos jours sont exploitées 488 00:26:50,000 --> 00:26:53,000 et compromis et de données est une fuite et mots de passe sont volés 489 00:26:53,000 --> 00:26:58,000 cette très souvent trait à la mauvaise gestion de son mémoire, 490 00:26:58,000 --> 00:27:01,000 ou, dans le cas de bases de données, défaut d'anticipation 491 00:27:01,000 --> 00:27:03,000 entrée contradictoire, donc plus à ce sujet dans les semaines à venir, 492 00:27:03,000 --> 00:27:07,000 mais pour l'instant juste un avant-goût du genre de dégâts que vous pouvez faire 493 00:27:07,000 --> 00:27:11,000 pas tout à fait par comprendre comment les choses fonctionnent sous le capot. 494 00:27:11,000 --> 00:27:14,000 Allons de comprendre pourquoi il en est rompu 495 00:27:14,000 --> 00:27:17,000 avec un outil qui va devenir de plus en plus utiles 496 00:27:17,000 --> 00:27:19,000 que nos programmes deviennent plus complexes. 497 00:27:19,000 --> 00:27:21,000 Jusqu'à présent, quand vous avez eu un bug dans le programme 498 00:27:21,000 --> 00:27:23,000 comment avez-vous fait à ce sujet le débogage? 499 00:27:23,000 --> 00:27:25,000 Qu'est-ce que vos techniques sont à ce jour, que ce soit enseignée par votre carte de TF 500 00:27:25,000 --> 00:27:27,000 ou juste un autodidacte? 501 00:27:27,000 --> 00:27:29,000 [Étudiants] Printf. 502 00:27:29,000 --> 00:27:31,000 Printf, alors printf a probablement été votre ami, si vous voulez voir 503 00:27:31,000 --> 00:27:33,000 ce qui se passe à l'intérieur de votre programme 504 00:27:33,000 --> 00:27:36,000 vous venez de mettre printf ici, printf ici, printf ici. 505 00:27:36,000 --> 00:27:38,000 Puis vous l'exécutez, et vous obtenez tout un tas de choses sur l'écran 506 00:27:38,000 --> 00:27:43,000 que vous pouvez utiliser pour en déduire ce qui se passe mal dans votre programme. 507 00:27:43,000 --> 00:27:45,000 >> Printf tend à être une chose très puissante, 508 00:27:45,000 --> 00:27:47,000 mais c'est un processus très manuel. 509 00:27:47,000 --> 00:27:49,000 Vous devez mettre un printf ici, un printf ici, 510 00:27:49,000 --> 00:27:51,000 et si vous le mettez à l'intérieur d'une boucle que vous pourriez obtenir 100 lignes 511 00:27:51,000 --> 00:27:53,000 de sortie que vous avez alors de passer au crible. 512 00:27:53,000 --> 00:27:58,000 Ce n'est pas un mécanisme très convivial ou interactif pour les programmes de débogage, 513 00:27:58,000 --> 00:28:00,000 mais heureusement, il existe des solutions de rechange. 514 00:28:00,000 --> 00:28:03,000 Il s'agit d'un programme, par exemple, appelé GDB, le débogueur GNU, 515 00:28:03,000 --> 00:28:06,000 qui est un peu obscur dans la façon dont vous l'utilisez. 516 00:28:06,000 --> 00:28:08,000 C'est un peu complexe, mais franchement, 517 00:28:08,000 --> 00:28:11,000 c'est une de ces choses où si vous avez mis dans cette semaine et la suivante 518 00:28:11,000 --> 00:28:14,000 l'heure supplémentaire pour comprendre quelque chose comme GDB 519 00:28:14,000 --> 00:28:18,000 il vous fera économiser probablement des dizaines d'heures sur le long terme, 520 00:28:18,000 --> 00:28:21,000 Donc, avec cela, permettez-moi de vous donner un avant-goût de la façon dont ça fonctionne. 521 00:28:21,000 --> 00:28:23,000 >> Je suis dans ma fenêtre de terminal. 522 00:28:23,000 --> 00:28:26,000 Permettez-moi aller de l'avant et de compiler ce programme, buggy3. 523 00:28:26,000 --> 00:28:28,000 Il est déjà à jour. 524 00:28:28,000 --> 00:28:31,000 Permettez-moi de faire fonctionner tout comme nous avons fait un retour tout, et en effet, il est cassé. 525 00:28:31,000 --> 00:28:34,000 Mais pourquoi est-ce? Peut-être que j'ai foiré la fonction swap. 526 00:28:34,000 --> 00:28:37,000 Peut-être que c'est a et b. Je ne suis pas tout à fait les déplacer correctement. 527 00:28:37,000 --> 00:28:39,000 Permettez-moi aller de l'avant et de le faire. 528 00:28:39,000 --> 00:28:43,000 Plutôt que de simplement exécuter buggy3 laissez-moi plutôt exécuter ce programme GDB, 529 00:28:43,000 --> 00:28:48,000 et je vais lui dire de lancer buggy3, 530 00:28:48,000 --> 00:28:52,000 et je vais inclure un argument en ligne de commande,-tui, 531 00:28:52,000 --> 00:28:55,000 et nous allons mettre cela dans de futurs problèmes pour rappeler au spec. 532 00:28:55,000 --> 00:28:57,000 Et maintenant, cette interface en noir et blanc surgi qui, encore une fois, 533 00:28:57,000 --> 00:28:59,000 est un peu écrasante au premier abord, car il ya toute cette 534 00:28:59,000 --> 00:29:02,000 informations sur la garantie ici-bas, mais au moins il ya quelque chose de familier. 535 00:29:02,000 --> 00:29:04,000 Dans la partie supérieure de la fenêtre est mon code actuel, 536 00:29:04,000 --> 00:29:08,000 et si je défiler vers le haut ici permettez-moi de faire défiler jusqu'en haut de mon dossier, 537 00:29:08,000 --> 00:29:11,000 et en effet, il ya buggy3.c, et de l'avis au bas de cette fenêtre 538 00:29:11,000 --> 00:29:13,000 J'ai cette invite GDB. 539 00:29:13,000 --> 00:29:16,000 >> Ce n'est pas la même chose que mon invite normale John Harvard. 540 00:29:16,000 --> 00:29:19,000 Il s'agit d'une invite de commande qui va me permettre de contrôler GDB. 541 00:29:19,000 --> 00:29:21,000 GDB est un débogueur. 542 00:29:21,000 --> 00:29:24,000 Un débogueur est un programme qui vous permet de marcher à travers 543 00:29:24,000 --> 00:29:27,000 l'exécution de votre programme ligne par ligne par ligne, 544 00:29:27,000 --> 00:29:30,000 le long du chemin que vous voulez faire quelque chose au programme, 545 00:29:30,000 --> 00:29:33,000 même appeler des fonctions, ou à la recherche, plus important encore, 546 00:29:33,000 --> 00:29:35,000 à différentes valeurs de la variable d'. 547 00:29:35,000 --> 00:29:37,000 Allons de l'avant et de le faire. 548 00:29:37,000 --> 00:29:40,000 Je vais aller de l'avant et tapez run à l'invite GDB, 549 00:29:40,000 --> 00:29:43,000 si remarquerez en bas à gauche de l'écran, j'ai tapé courir, 550 00:29:43,000 --> 00:29:45,000 et j'ai appuyez sur Entrée, et qu'est-ce que cela fait? 551 00:29:45,000 --> 00:29:50,000 Il a littéralement couru mon programme, mais je n'ai pas vu beaucoup de quoi continuer ici 552 00:29:50,000 --> 00:29:55,000 parce que je n'ai pas vraiment dit le débogueur 553 00:29:55,000 --> 00:29:57,000 pour faire une pause à un moment précis dans le temps. 554 00:29:57,000 --> 00:29:59,000 Juste en tapant run exécute le programme. 555 00:29:59,000 --> 00:30:01,000 Je n'ai pas vraiment vu quelque chose. Je ne peux pas le manipuler. 556 00:30:01,000 --> 00:30:03,000 >> Au lieu de me laisser faire cela. 557 00:30:03,000 --> 00:30:08,000 À cette invite GDB laissez-moi plutôt taper introduction par effraction. 558 00:30:08,000 --> 00:30:10,000 Ce n'est pas ce que je voulais dire à taper. 559 00:30:10,000 --> 00:30:13,000 Disons plutôt que taper rupture principale. 560 00:30:13,000 --> 00:30:15,000 En d'autres termes, je veux mettre quelque chose qui s'appelle un point d'arrêt, 561 00:30:15,000 --> 00:30:18,000 qui porte bien son nom, car il risquerait de casser ou de pause 562 00:30:18,000 --> 00:30:21,000 exécution de votre programme à cet endroit particulier. 563 00:30:21,000 --> 00:30:23,000 Principal est le nom de ma fonction. 564 00:30:23,000 --> 00:30:25,000 Notez que GDB est assez malin. 565 00:30:25,000 --> 00:30:28,000 Il compris que se passe principal pour commencer à peu près à la ligne 18 566 00:30:28,000 --> 00:30:32,000 de buggy3.c, puis notez ici en haut à gauche 567 00:30:32,000 --> 00:30:34,000 + b est juste à côté de la ligne 18. 568 00:30:34,000 --> 00:30:38,000 C'est en me rappelant que j'ai mis un point d'arrêt à la ligne 18. 569 00:30:38,000 --> 00:30:42,000 Cette fois, quand je tape course, je vais exécuter mon programme 570 00:30:42,000 --> 00:30:45,000 jusqu'à ce qu'il touche ce point d'arrêt, 571 00:30:45,000 --> 00:30:48,000 de sorte que le programme se met en pause pour moi à la ligne 18. 572 00:30:48,000 --> 00:30:50,000 Here we go, de fonctionner. 573 00:30:50,000 --> 00:30:53,000 Rien ne semble avoir eu lieu, mais préavis en bas à gauche 574 00:30:53,000 --> 00:30:58,000 démarrage du programme, buggy3, point d'arrêt 1 dans la ligne principale buggy3.c 18. 575 00:30:58,000 --> 00:31:00,000 Que puis-je faire maintenant? 576 00:31:00,000 --> 00:31:03,000 >> Remarquez que je peux commencer à taper des choses comme impression, 577 00:31:03,000 --> 00:31:08,000 pas printf, x impression, et maintenant c'est étrange. 578 00:31:08,000 --> 00:31:11,000 Le $ 1 est juste une curiosité, comme nous le verrons 579 00:31:11,000 --> 00:31:14,000 chaque fois que vous imprimez quelque chose que vous obtenez une nouvelle valeur de $. 580 00:31:14,000 --> 00:31:18,000 C'est ainsi que vous pouvez vous référer aux valeurs précédentes au cas où, 581 00:31:18,000 --> 00:31:21,000 mais pour l'instant ce n'est impression de me dire que la valeur de x, à ce moment de l'histoire 582 00:31:21,000 --> 00:31:26,000 est apparemment 134514032. 583 00:31:26,000 --> 00:31:29,000 Quoi? Où cela s'est-il encore venir? 584 00:31:29,000 --> 00:31:31,000 [Inaudible étudiant] 585 00:31:31,000 --> 00:31:34,000 En effet, c'est ce que nous appellerons une valeur ordures, et nous n'avons pas parlé encore, 586 00:31:34,000 --> 00:31:37,000 mais la raison pour laquelle vous initialiser les variables 587 00:31:37,000 --> 00:31:40,000 est évidemment de sorte qu'ils ont une certaine valeur que vous voulez leur donner. 588 00:31:40,000 --> 00:31:44,000 Mais le hic c'est rappeler que vous pouvez déclarer des variables 589 00:31:44,000 --> 00:31:46,000 comme je l'ai fait il ya un instant dans mon exemple sigma 590 00:31:46,000 --> 00:31:48,000 sans pour autant leur donner une valeur. 591 00:31:48,000 --> 00:31:50,000 Rappelez-vous ce que j'ai fait ici en sigma. 592 00:31:50,000 --> 00:31:52,000 Je déclare n, mais quelle valeur ai-je lui donner? 593 00:31:52,000 --> 00:31:56,000 Aucun, parce que je savais que, dans les quelques lignes qui suivent 594 00:31:56,000 --> 00:31:59,000 GetInt prendrait en charge le problème de mettre une valeur à l'intérieur de n. 595 00:31:59,000 --> 00:32:02,000 >> Mais à ce moment de l'histoire de la ligne 11 596 00:32:02,000 --> 00:32:05,000 ligne 12 et la ligne 13 et la ligne 14 et 597 00:32:05,000 --> 00:32:08,000 tout au long de ces lignes de plusieurs quelle est la valeur de n? 598 00:32:08,000 --> 00:32:10,000 En C, vous ne savez pas. 599 00:32:10,000 --> 00:32:14,000 C'est généralement une valeur ordures, un certain nombre totalement aléatoire 600 00:32:14,000 --> 00:32:17,000 Il ne reste plus essentiellement une fonction précédente 601 00:32:17,000 --> 00:32:21,000 ayant été exécuté, de sorte que votre programme s'exécute 602 00:32:21,000 --> 00:32:24,000 Rappelons que la fonction reçoit, fonction, fonction. 603 00:32:24,000 --> 00:32:27,000 Tous ces cadres se mettre sur la mémoire, puis ceux de retour des fonctions, 604 00:32:27,000 --> 00:32:31,000 et comme je l'ai suggéré avec la gomme de leur mémoire est éventuellement réutilisés. 605 00:32:31,000 --> 00:32:37,000 Eh bien, il se trouve que cette variable x dans ce programme 606 00:32:37,000 --> 00:32:41,000 semble avoir contenu une valeur ordures comme 134514032 607 00:32:41,000 --> 00:32:44,000 d'une certaine fonction précédente, pas un seul que j'ai écrit. 608 00:32:44,000 --> 00:32:47,000 Il pourrait être quelque chose qui vient efficacement avec le système d'exploitation, 609 00:32:47,000 --> 00:32:49,000 une fonction sous la hotte. 610 00:32:49,000 --> 00:32:52,000 >> D'accord, c'est très bien, mais nous allons maintenant passer à la ligne suivante. 611 00:32:52,000 --> 00:32:55,000 Si je tape "suivant" à mon invite GDB et je appuyez sur Entrée, 612 00:32:55,000 --> 00:32:58,000 remarquer que la mise en évidence se déplace vers le bas pour la ligne 19, 613 00:32:58,000 --> 00:33:01,000 mais la conséquence logique est que la ligne 18 614 00:33:01,000 --> 00:33:06,000 a maintenant terminé son exécution, donc si j'ai de nouveau taper "print x" 615 00:33:06,000 --> 00:33:10,000 Je devrais maintenant voir 1, et en effet, je le fais. 616 00:33:10,000 --> 00:33:14,000 Encore une fois, les trucs $ est une façon de vous rappeler GDB 617 00:33:14,000 --> 00:33:17,000 ce que l'histoire d'impressions sont que vous avez fait. 618 00:33:17,000 --> 00:33:21,000 Maintenant, laissez-moi aller de l'avant et d'imprimer y, et en effet, y est une valeur folle aussi, 619 00:33:21,000 --> 00:33:24,000 mais pas une grosse affaire parce que la ligne 19, nous sommes sur le point de céder 620 00:33:24,000 --> 00:33:27,000 la valeur 2, alors laissez-moi entrer "à côté" de nouveau. 621 00:33:27,000 --> 00:33:29,000 Et maintenant nous sommes sur la ligne printf. 622 00:33:29,000 --> 00:33:31,000 Permettez-moi de faire x d'impression. 623 00:33:31,000 --> 00:33:34,000 Permettez-moi de faire y imprimer. Franchement, je suis un peu fatigué de l'impression de ce. 624 00:33:34,000 --> 00:33:38,000 Permettez-moi plutôt de type "x affichage" et "affichage y», 625 00:33:38,000 --> 00:33:41,000 et maintenant chaque fois que je tape une commande dans l'avenir 626 00:33:41,000 --> 00:33:45,000 Je vais rappeler de ce qui est x et y, ce qui est x et y, ce qui est x et y. 627 00:33:45,000 --> 00:33:48,000 >> Je peux aussi, en passant, tapez "locaux d'information." 628 00:33:48,000 --> 00:33:50,000 Info est une commande spéciale. 629 00:33:50,000 --> 00:33:52,000 Les sections locales signifie qu'il me montre les variables locales. 630 00:33:52,000 --> 00:33:55,000 Juste au cas où je ne sais plus ou il s'agit d'un fou, fonction complexe 631 00:33:55,000 --> 00:33:57,000 que moi ou quelqu'un d'autre a écrit habitants d'information vous indiquera 632 00:33:57,000 --> 00:34:00,000 ce sont toutes les variables locales à l'intérieur de cette fonction locale 633 00:34:00,000 --> 00:34:03,000 que vous pourriez soucier si vous voulez fouiller. 634 00:34:03,000 --> 00:34:07,000 Maintenant, printf est sur le point de signer, alors laissez-moi aller de l'avant et il suffit de taper "suivant". 635 00:34:07,000 --> 00:34:10,000 Parce que nous sommes dans cet environnement, nous ne sommes pas réellement le voir 636 00:34:10,000 --> 00:34:14,000 exécuter ici-bas, mais remarquez qu'il devient un peu mutilé ici. 637 00:34:14,000 --> 00:34:17,000 Mais remarquez qu'il est remplaçant l'écran là-bas, 638 00:34:17,000 --> 00:34:21,000 donc ce n'est pas un programme parfait ici, mais c'est bien parce que je peux toujours fouiller 639 00:34:21,000 --> 00:34:23,000 à l'aide d'impression si je veux. 640 00:34:23,000 --> 00:34:26,000 >> Permettez-moi de saisir la prochaine fois, et maintenant voici la partie intéressante. 641 00:34:26,000 --> 00:34:29,000 À ce stade de l'histoire y est 2, et x est 1, 642 00:34:29,000 --> 00:34:32,000 comme suggéré ici, et encore une fois, 643 00:34:32,000 --> 00:34:35,000 la raison pour laquelle il est automatiquement afficher maintenant, c'est parce que j'ai utilisé la commande 644 00:34:35,000 --> 00:34:40,000 x affichage et affichage y, donc le moment je tape suivante 645 00:34:40,000 --> 00:34:43,000 en théorie x et y doivent être permutés. 646 00:34:43,000 --> 00:34:45,000 Maintenant, nous savons déjà que ça ne va pas être le cas, 647 00:34:45,000 --> 00:34:49,000 mais nous verrons dans un instant comment on peut plonger plus profond pour comprendre pourquoi c'est vrai. 648 00:34:49,000 --> 00:34:54,000 Ensuite, et malheureusement, y est toujours de 2 et x est toujours 1, et je peux le confirmer. 649 00:34:54,000 --> 00:34:56,000 Imprimer x, y d'impression. 650 00:34:56,000 --> 00:34:59,000 En effet, aucun échange qui s'est réellement passé, nous allons donc commencer ce cours. 651 00:34:59,000 --> 00:35:01,000 Il est clair swap est cassé. 652 00:35:01,000 --> 00:35:04,000 Disons plutôt que taper «run» à nouveau. 653 00:35:04,000 --> 00:35:07,000 Permettez-moi de dire oui, je veux recommencer depuis le début, entrez. 654 00:35:07,000 --> 00:35:09,000 >> Maintenant, je suis de retour à la ligne jusqu'à 18 ans. 655 00:35:09,000 --> 00:35:11,000 Maintenant, remarquez x et y sont des valeurs parasites nouveau. 656 00:35:11,000 --> 00:35:15,000 Suivant, Suivant, Suivant, à côté. 657 00:35:15,000 --> 00:35:17,000 Si je m'ennuie je peux aussi simplement taper n pour la prochaine. 658 00:35:17,000 --> 00:35:21,000 Vous pouvez l'abréger à la séquence la plus courte possible des caractères. 659 00:35:21,000 --> 00:35:23,000 Le swap est désormais rompu. 660 00:35:23,000 --> 00:35:25,000 Débutons notre étude, si au lieu de taper à côté, 661 00:35:25,000 --> 00:35:30,000 maintenant je vais taper étape de sorte que je ne suis pas à pas à l'intérieur de cette fonction 662 00:35:30,000 --> 00:35:33,000 afin que je puisse passer au travers, alors j'ai frappé étape, puis entrez. 663 00:35:33,000 --> 00:35:37,000 Notez que les sauts en soulignant descendant plus bas dans mon programme à la ligne 36. 664 00:35:37,000 --> 00:35:39,000 Maintenant, quelles sont les variables locales? 665 00:35:39,000 --> 00:35:41,000 Les habitants d'infos. 666 00:35:41,000 --> 00:35:43,000 Rien pour l'instant parce que nous n'avons pas obtenu à cette ligne, 667 00:35:43,000 --> 00:35:47,000 nous allons donc aller de l'avant et de dire "suivant". 668 00:35:47,000 --> 00:35:50,000 Maintenant, nous semblons avoir tmp tmp impression,. 669 00:35:50,000 --> 00:35:52,000 Valeur des ordures, pas vrai? Je crois. 670 00:35:52,000 --> 00:35:55,000 Que diriez-vous d'imprimer une, print b, 1 et 2? 671 00:35:55,000 --> 00:35:58,000 En un instant, dès que je tape la prochaine fois 672 00:35:58,000 --> 00:36:02,000 tmp va prendre une valeur de 1, espérons-le, 673 00:36:02,000 --> 00:36:05,000 parce tmp va être affectée la valeur d'un. 674 00:36:05,000 --> 00:36:08,000 >> Maintenant, nous allons ne imprimer un b, d'impression, 675 00:36:08,000 --> 00:36:11,000 mais maintenant imprimer tmp, et c'est en effet 1. 676 00:36:11,000 --> 00:36:14,000 Permettez-moi de faire par la suite. Permettez-moi de faire par la suite. 677 00:36:14,000 --> 00:36:16,000 J'ai fini la fonction de permutation. 678 00:36:16,000 --> 00:36:19,000 Je suis toujours à l'intérieur de celui-ci dans la ligne 40, alors permettez-moi d'imprimer une, 679 00:36:19,000 --> 00:36:22,000 print b, et je me moque de ce tmp est. 680 00:36:22,000 --> 00:36:27,000 Il ressemble échange est correct quand il s'agit de permutation a et b. 681 00:36:27,000 --> 00:36:31,000 Mais si je maintenant taper prochaine, je reviens à la ligne 25, 682 00:36:31,000 --> 00:36:34,000 et bien sûr, si je tape dans x et y imprimée 683 00:36:34,000 --> 00:36:38,000 ils sont toujours inchangée, de sorte que nous n'avons pas résolu le problème. 684 00:36:38,000 --> 00:36:41,000 Mais le diagnostic peut-être maintenant avec ce programme GDB 685 00:36:41,000 --> 00:36:44,000 nous avons au moins obtenu un peu plus de compréhension 686 00:36:44,000 --> 00:36:47,000 ce qui va mal, sans avoir à litière notre code en mettant un printf ici, 687 00:36:47,000 --> 00:36:50,000 printf ici, printf ici, puis de l'exécuter encore et encore 688 00:36:50,000 --> 00:36:52,000 à essayer de comprendre ce qui va mal. 689 00:36:52,000 --> 00:36:55,000 >> Je vais aller de l'avant et de quitter de ce tout à fait avec arrêter de fumer. 690 00:36:55,000 --> 00:36:57,000 Il va alors dire: «Quittez toute façon?" Oui. 691 00:36:57,000 --> 00:37:00,000 Maintenant, je suis de retour à mon message normal, et je suis fait à l'aide de GDB. 692 00:37:00,000 --> 00:37:03,000 Soit dit en passant, vous n'avez pas besoin d'utiliser ce drapeau-tui. 693 00:37:03,000 --> 00:37:07,000 En fait, si vous l'omettez vous obtenez essentiellement la moitié inférieure de l'écran. 694 00:37:07,000 --> 00:37:11,000 Si je puis tapez grande pause, puis exécutez 695 00:37:11,000 --> 00:37:15,000 Je peux encore exécuter mon programme, mais ce qu'elle va faire, c'est plus textuellement 696 00:37:15,000 --> 00:37:18,000 juste me montrer la ligne en cours à la fois. 697 00:37:18,000 --> 00:37:21,000 Le tui-interface utilisateur textuelle, 698 00:37:21,000 --> 00:37:25,000 vous montre juste plus du programme à la fois, ce qui est probablement un peu conceptuellement plus facile. 699 00:37:25,000 --> 00:37:27,000 Mais, en vérité, je peux juste faire par la suite, suivant, suivant, 700 00:37:27,000 --> 00:37:30,000 et je vais voir une ligne à la fois, et si je veux vraiment voir ce qui se passe 701 00:37:30,000 --> 00:37:35,000 Je peux taper liste et de voir tout un tas de lignes voisines. 702 00:37:35,000 --> 00:37:39,000 >> Il ya une vidéo que nous avons demandé à ce que vous regardez pour le problème ensembles 3 703 00:37:39,000 --> 00:37:43,000 dans lequel Nate couvre une partie de la complexité de GDB, 704 00:37:43,000 --> 00:37:46,000 et c'est une de ces choses, honnêtement, où un certain pourcentage non négligeable d'entre vous 705 00:37:46,000 --> 00:37:49,000 ne touchera jamais GDB, et ce sera une mauvaise chose 706 00:37:49,000 --> 00:37:53,000 parce que littéralement vous finirez par passer plus de temps plus tard ce semestre 707 00:37:53,000 --> 00:37:56,000 traquer les bugs, alors vous feriez si vous mettez dans cette demi-heure / heure 708 00:37:56,000 --> 00:38:00,000 cette semaine suivante et l'apprentissage à l'aise avec GDB. 709 00:38:00,000 --> 00:38:02,000 Printf était votre ami. 710 00:38:02,000 --> 00:38:05,000 GDB devrait maintenant être votre ami. 711 00:38:05,000 --> 00:38:08,000 >> Toutes les questions sur GDB? 712 00:38:08,000 --> 00:38:12,000 Et voici une liste rapide de quelques-unes des commandes les plus puissantes et utiles. 713 00:38:12,000 --> 00:38:15,000 Ouais. >> Pouvez-vous imprimer une chaîne? 714 00:38:15,000 --> 00:38:17,000 Pouvez-vous imprimer une chaîne? Tout à fait. 715 00:38:17,000 --> 00:38:19,000 Il ne doit pas seulement être des nombres entiers. 716 00:38:19,000 --> 00:38:22,000 Si une variable s est une chaîne suffit de taper dans l 'impression. 717 00:38:22,000 --> 00:38:24,000 Il va vous montrer ce que la variable chaîne est. 718 00:38:24,000 --> 00:38:26,000 [Inaudible étudiant] 719 00:38:26,000 --> 00:38:28,000 Il vous donnera l'adresse et la chaîne elle-même. 720 00:38:28,000 --> 00:38:32,000 Il vous montrera aussi. 721 00:38:32,000 --> 00:38:34,000 Et une dernière chose, juste parce que ce sont des bon de savoir aussi. 722 00:38:34,000 --> 00:38:37,000 Backtrace et le cadre, permettez-moi de plonger dans cette dernière fois, 723 00:38:37,000 --> 00:38:39,000 même programme exact avec GDB. 724 00:38:39,000 --> 00:38:44,000 Permettez-moi aller de l'avant et exécuter la version textuelle utilisateur interface, 725 00:38:44,000 --> 00:38:46,000 briser principale. 726 00:38:46,000 --> 00:38:49,000 Permettez-moi aller de l'avant et de courir à nouveau. Je suis ici. 727 00:38:49,000 --> 00:38:55,000 Maintenant, laissez-moi aller ensuite, suivant, suivant, suivant, suivant, étape, entrez. 728 00:38:55,000 --> 00:39:00,000 >> Et supposons maintenant que je suis maintenant en échange délibérément, mais je suis comme "Putain, quelle était la valeur de x?" 729 00:39:00,000 --> 00:39:02,000 Je ne peux pas faire plus x. 730 00:39:02,000 --> 00:39:05,000 Je ne peux pas y parce qu'ils ne sont pas dans la portée. 731 00:39:05,000 --> 00:39:07,000 Ils ne sont pas dans leur contexte, mais pas de problème. 732 00:39:07,000 --> 00:39:09,000 Je peux taper trace. 733 00:39:09,000 --> 00:39:13,000 Cela me montre toutes les fonctions qui ont exécutées jusqu'à ce point dans le temps. 734 00:39:13,000 --> 00:39:16,000 Notez que l'un sur le fond, main, s'aligne avec principal 735 00:39:16,000 --> 00:39:18,000 étant à la base de notre image ici. 736 00:39:18,000 --> 00:39:22,000 Le fait que d'échange ci-dessus est qu'il s'aligne avec swap étant au-dessus dans la mémoire ici, 737 00:39:22,000 --> 00:39:26,000 et si je veux revenir au menu principal temporairement je peux dire «cadre». 738 00:39:26,000 --> 00:39:30,000 Quel numéro? Principale est la trame n ° 1. 739 00:39:30,000 --> 00:39:32,000 Je vais aller de l'avant et de dire «cadre 1." 740 00:39:32,000 --> 00:39:36,000 >> Maintenant, je suis de retour dans main, et je peux imprimer x, et je peux imprimer y, 741 00:39:36,000 --> 00:39:40,000 mais je ne peux pas imprimer sur a ou b. 742 00:39:40,000 --> 00:39:43,000 Mais je peux si je dis: «Bon, attends une minute. Où était le swap?" 743 00:39:43,000 --> 00:39:46,000 Permettez-moi aller de l'avant et de dire "0 image." 744 00:39:46,000 --> 00:39:48,000 Maintenant, je suis de retour là où je veux être, et en passant, 745 00:39:48,000 --> 00:39:52,000 il ya d'autres commandes aussi, comme si vous êtes vraiment obtenir le typage s'ennuyer prochaine, prochain, prochaine, prochain, 746 00:39:52,000 --> 00:39:56,000 vous pouvez généralement dire des choses comme "10 next", et que fait défiler les 10 prochaines lignes. 747 00:39:56,000 --> 00:39:59,000 Vous pouvez également écrire «continuer» lorsque vous avez vraiment marre de pas à pas à travers elle. 748 00:39:59,000 --> 00:40:05,000 Continuer exécutera votre programme sans interruption jusqu'à ce qu'il rencontre un autre point d'arrêt, 749 00:40:05,000 --> 00:40:07,000 que ce soit dans une boucle ou plus bas dans votre programme. 750 00:40:07,000 --> 00:40:11,000 >> Dans ce cas, nous avons continué jusqu'à la fin, et le programme s'est terminé normalement. 751 00:40:11,000 --> 00:40:13,000 C'est une façon élégante, un processus de qualité inférieure. 752 00:40:13,000 --> 00:40:16,000 Tout le programme s'est terminé normalement. 753 00:40:16,000 --> 00:40:24,000 Plus sur cela dans la vidéo et le débogage des sessions à venir. 754 00:40:24,000 --> 00:40:26,000 C'était beaucoup. 755 00:40:26,000 --> 00:40:35,000 Prenons notre 5 minutes de pause ici, et nous reviendrons avec structs et les fichiers. 756 00:40:35,000 --> 00:40:38,000 >> Si vous avez plongé dans pset cette semaine déjà 757 00:40:38,000 --> 00:40:41,000 vous saurez que nous utilisons dans le code de distribution, 758 00:40:41,000 --> 00:40:45,000 le code source que nous fournissons à vous en tant que point de départ, de nouvelles techniques. 759 00:40:45,000 --> 00:40:50,000 En particulier, nous avons présenté ce nouveau mot-clé struct appelé, pour la structure, 760 00:40:50,000 --> 00:40:53,000 afin que nous puissions créer des variables personnalisées de toutes sortes. 761 00:40:53,000 --> 00:40:57,000 Nous avons également introduit la notion de fichier d'entrée de fichier I / O et de sortie, 762 00:40:57,000 --> 00:41:00,000 et c'est afin que nous puissions enregistrer l'état 763 00:41:00,000 --> 00:41:03,000 de votre conseil Scramble à un fichier sur le disque 764 00:41:03,000 --> 00:41:06,000 de sorte que les boursiers d'enseignement et je peux comprendre 765 00:41:06,000 --> 00:41:09,000 ce qui se passe à l'intérieur de votre programme sans avoir à jouer manuellement 766 00:41:09,000 --> 00:41:11,000 des dizaines de jeux de bousculade. 767 00:41:11,000 --> 00:41:13,000 Nous pouvons le faire plus manière automatisée. 768 00:41:13,000 --> 00:41:18,000 >> Cette idée d'une structure résout un problème assez convaincante. 769 00:41:18,000 --> 00:41:21,000 Supposons que nous voulons mettre en œuvre certains programmes 770 00:41:21,000 --> 00:41:25,000 qui tient en quelque sorte la trace des informations sur les élèves, 771 00:41:25,000 --> 00:41:28,000 et les élèves pourraient avoir, par exemple, une pièce d'identité, un nom 772 00:41:28,000 --> 00:41:31,000 et une maison dans un endroit comme Harvard, ce sont donc 3 morceaux de l'information 773 00:41:31,000 --> 00:41:34,000 nous voulons garder autour, alors laissez-moi aller de l'avant et commencer à écrire un petit programme ici, 774 00:41:34,000 --> 00:41:38,000 inclure stdio.h. 775 00:41:38,000 --> 00:41:42,000 Permettez-moi de faire comprendre cs50.h. 776 00:41:42,000 --> 00:41:44,000 Et puis commencer ma fonction principale. 777 00:41:44,000 --> 00:41:46,000 Je vais vous embêtez pas avec des arguments de ligne de commande, 778 00:41:46,000 --> 00:41:49,000 et ici je veux avoir un étudiant, alors je vais dire 779 00:41:49,000 --> 00:41:54,000 un élève a un nom, alors je vais dire «nom de chaîne." 780 00:41:54,000 --> 00:41:59,000 Alors je vais dire un étudiant dispose également d'un ID, id int sorte, 781 00:41:59,000 --> 00:42:03,000 et un étudiant a une maison, donc je vais aussi dire «maison chaîne." 782 00:42:03,000 --> 00:42:06,000 Alors, je vais commander ces petits une manière plus propre comme ça. 783 00:42:06,000 --> 00:42:11,000 Ok, maintenant j'ai 3 variables avec lesquelles représentent un étudiant, donc «un étudiant». 784 00:42:11,000 --> 00:42:15,000 >> Et maintenant, je veux remplir ces valeurs, alors laissez-moi aller de l'avant et dire quelque chose comme 785 00:42:15,000 --> 00:42:18,000 "Id = 123». 786 00:42:18,000 --> 00:42:21,000 Nom va se faire David. 787 00:42:21,000 --> 00:42:24,000 Disons que la maison va se faire Mather, 788 00:42:24,000 --> 00:42:31,000 et puis je vais faire quelque chose de façon arbitraire comme printf ("% s, 789 00:42:31,000 --> 00:42:37,000 dont l'ID est% d, vit dans% s. 790 00:42:37,000 --> 00:42:41,000 Et maintenant, qu'est-ce que je veux brancher ici, l'un après l'autre? 791 00:42:41,000 --> 00:42:47,000 Nom, id, maison, retourne 0. 792 00:42:47,000 --> 00:42:50,000 Bon, sauf si j'ai foiré quelque part ici 793 00:42:50,000 --> 00:42:54,000 Je pense que nous avons un très bon programme qui stocke un étudiant. 794 00:42:54,000 --> 00:42:57,000 Bien sûr, ce n'est pas du tout intéressant. Que faire si je veux avoir 2 étudiants? 795 00:42:57,000 --> 00:42:59,000 Ce n'est pas une grosse affaire. Je peux appuyer 2 personnes. 796 00:42:59,000 --> 00:43:03,000 Permettez-moi aller de l'avant et de mettre en valeur ce et de descendre ici, 797 00:43:03,000 --> 00:43:09,000 et je peux dire "id = 456" pour quelqu'un comme Rob qui vit à Kirkland. 798 00:43:09,000 --> 00:43:12,000 >> Bon, attendez, mais je ne peux pas appeler ces la même chose, 799 00:43:12,000 --> 00:43:15,000 et on dirait que je vais devoir copier ce, 800 00:43:15,000 --> 00:43:19,000 permettez-moi de dire que ce seront des variables de David, 801 00:43:19,000 --> 00:43:23,000 et laissez-moi obtenir des copies de ces documents pour Rob. 802 00:43:23,000 --> 00:43:27,000 Nous allons appeler ces Rob, mais cela ne va pas au travail maintenant 803 00:43:27,000 --> 00:43:33,000 parce que j'ai-attendre, me laisse passer à id1, nom1 et house1. 804 00:43:33,000 --> 00:43:35,000 Rob sera de 2, 2. 805 00:43:35,000 --> 00:43:42,000 Je dois changer ça ici, ici, ici, ici, ici, ici. 806 00:43:42,000 --> 00:43:45,000 Attendez, qu'est-ce à propos de Tommy? Faisons-le à nouveau. 807 00:43:45,000 --> 00:43:49,000 Évidemment, si vous pensez toujours que c'est une bonne façon de le faire, ce n'est pas, 808 00:43:49,000 --> 00:43:52,000 donc copier / coller mal. 809 00:43:52,000 --> 00:43:55,000 Mais nous avons résolu ce il ya une semaine. 810 00:43:55,000 --> 00:43:59,000 >> Quelle a été notre solution quand nous avons voulu avoir plusieurs instances d'un même type de données? 811 00:43:59,000 --> 00:44:01,000 [Etudiants] Tableau. 812 00:44:01,000 --> 00:44:03,000 Un tableau, donc je vais essayer de nettoyer tout ça. 813 00:44:03,000 --> 00:44:07,000 Permettez-moi de faire de la place pour moi en haut, et laissez-moi plutôt le faire ici. 814 00:44:07,000 --> 00:44:12,000 Nous allons appeler ces gens, et à la place, je vais dire "id int," 815 00:44:12,000 --> 00:44:14,000 et je vais appuyer 3 d'entre nous pour l'instant. 816 00:44:14,000 --> 00:44:18,000 Je vais dire "noms de chaîne," et je vais appuyer 3 d'entre nous, 817 00:44:18,000 --> 00:44:22,000 et puis je vais dire "maisons à cordes», et je vais appuyer 3 d'entre nous. 818 00:44:22,000 --> 00:44:26,000 Maintenant, ici, au lieu de faire ses propres David variables locales 819 00:44:26,000 --> 00:44:28,000 nous pouvons nous débarrasser de ceux-ci. 820 00:44:28,000 --> 00:44:30,000 Ça fait du bien que nous nettoyer cela. 821 00:44:30,000 --> 00:44:35,000 Je peux alors dire que David va être [0] et les noms [0] 822 00:44:35,000 --> 00:44:38,000 et les maisons [0]. 823 00:44:38,000 --> 00:44:41,000 Et puis Rob nous pouvons même gagner à ce sujet. 824 00:44:41,000 --> 00:44:46,000 Mettons cela ici-bas, donc il va être arbitrairement ids [1]. 825 00:44:46,000 --> 00:44:50,000 Il va y avoir des noms [1], 826 00:44:50,000 --> 00:44:53,000 puis enfin, les maisons [1]. 827 00:44:53,000 --> 00:44:57,000 >> Encore un peu fastidieux, et maintenant je dois comprendre cela, 828 00:44:57,000 --> 00:45:03,000 alors disons "noms [0], id [0], maisons [0], 829 00:45:03,000 --> 00:45:06,000 et nous allons pluriel cela. 830 00:45:06,000 --> 00:45:09,000 Ids, ids, ids. 831 00:45:09,000 --> 00:45:12,000 Et encore, je vais le faire, et là encore, je suis déjà recours à des copier / coller de nouveau, 832 00:45:12,000 --> 00:45:14,000 de sorte chances sont qu'il ya une autre solution ici. 833 00:45:14,000 --> 00:45:18,000 Je peux probablement nettoyer tout ça plus loin avec une boucle ou quelque chose comme ça, 834 00:45:18,000 --> 00:45:21,000 Donc en bref, c'est un peu mieux, mais se sent encore comme 835 00:45:21,000 --> 00:45:24,000 Je recours à copier / coller, mais même cela, je prétends, 836 00:45:24,000 --> 00:45:27,000 n'est pas vraiment fondamentalement la bonne solution parce 837 00:45:27,000 --> 00:45:29,000 Et si un jour nous décidons de vous savez quoi? 838 00:45:29,000 --> 00:45:32,000 Nous avons vraiment aurait dû stocker des adresses email pour David et Rob 839 00:45:32,000 --> 00:45:34,000 et tout le monde dans ce programme. 840 00:45:34,000 --> 00:45:36,000 Nous devrions également stocker des numéros de téléphone. 841 00:45:36,000 --> 00:45:39,000 Nous devrions également enregistrer des numéros de téléphone d'urgence. 842 00:45:39,000 --> 00:45:41,000 Nous avons tous ces éléments de données que nous voulons stocker, 843 00:45:41,000 --> 00:45:43,000 Alors, comment allez-vous faire cela? 844 00:45:43,000 --> 00:45:46,000 >> Vous déclarez un autre tableau en haut, puis vous ajoutez manuellement 845 00:45:46,000 --> 00:45:49,000 une adresse e-mail [0], adresse e-mail [1] 846 00:45:49,000 --> 00:45:51,000 David et Rob et ainsi de suite. 847 00:45:51,000 --> 00:45:56,000 Mais il ne s'agit que d'une hypothèse sous-jacente à cette conception 848 00:45:56,000 --> 00:45:59,000 que je suis en utilisant le système d'honneur de savoir que 849 00:45:59,000 --> 00:46:03,000 [I] dans chacun des réseaux de plusieurs 850 00:46:03,000 --> 00:46:06,000 se trouve juste à se référer à la même personne, 851 00:46:06,000 --> 00:46:10,000 afin [0] dans ids est le numéro 123, 852 00:46:10,000 --> 00:46:13,000 et je vais supposer que les noms [0] 853 00:46:13,000 --> 00:46:16,000 est la même personne le nom et maisons [0] 854 00:46:16,000 --> 00:46:21,000 est la maison de la même personne et ainsi de suite pour tous les différents tableaux que je crée. 855 00:46:21,000 --> 00:46:24,000 Mais remarquez qu'il n'y a aucun lien fondamental 856 00:46:24,000 --> 00:46:27,000 parmi ces 3 informations, id, name et la maison, 857 00:46:27,000 --> 00:46:32,000 même si l'entité que nous essayons de modèle à ce programme n'est pas des tableaux. 858 00:46:32,000 --> 00:46:35,000 Les tableaux sont exactement de cette manière programmatique de le faire. 859 00:46:35,000 --> 00:46:38,000 Ce que nous voulons modéliser dans notre programme est une personne 860 00:46:38,000 --> 00:46:41,000 comme David, une personne comme Rob l'intérieur de laquelle 861 00:46:41,000 --> 00:46:46,000 ou d'encapsulation est un nom et un ID et une maison. 862 00:46:46,000 --> 00:46:49,000 >> Peut-on en quelque sorte exprimer cette idée d'encapsulation 863 00:46:49,000 --> 00:46:52,000 par lequel une personne a une identité, un nom et une maison 864 00:46:52,000 --> 00:46:55,000 et ne pas recourir à ce hack vraiment où nous venons 865 00:46:55,000 --> 00:46:58,000 confiance que quelque chose support 866 00:46:58,000 --> 00:47:02,000 se réfère à la même entité humaine dans chacun de ces tableaux disparates? 867 00:47:02,000 --> 00:47:04,000 Nous pouvons y parvenir. 868 00:47:04,000 --> 00:47:08,000 Laissez-moi aller principal ci-dessus pour le moment, et laissez-moi créer mon propre type de données 869 00:47:08,000 --> 00:47:10,000 pour vraiment la première fois. 870 00:47:10,000 --> 00:47:14,000 Nous avons utilisé cette technique dans la lutte confuse, 871 00:47:14,000 --> 00:47:17,000 mais ici, je vais aller de l'avant et de créer un type de données, 872 00:47:17,000 --> 00:47:19,000 et vous savez quoi, je vais l'appeler étudiant ou une personne, 873 00:47:19,000 --> 00:47:23,000 et je vais utiliser typedef pour définir un type. 874 00:47:23,000 --> 00:47:25,000 Je vais dire que c'est une structure, 875 00:47:25,000 --> 00:47:29,000 et puis cette structure va être de l'étudiant type, disons, 876 00:47:29,000 --> 00:47:31,000 même si c'est un peu daté maintenant pour moi. 877 00:47:31,000 --> 00:47:33,000 Nous dirons "int id." 878 00:47:33,000 --> 00:47:35,000 On va dire «nom de chaîne." 879 00:47:35,000 --> 00:47:37,000 Ensuite, nous allons dire «maison chaîne" 880 00:47:37,000 --> 00:47:40,000 alors maintenant à la fin de ces quelques lignes de code 881 00:47:40,000 --> 00:47:45,000 J'ai simplement appris qu'il existe clang 882 00:47:45,000 --> 00:47:49,000 un type de données int ailleurs, en plus de chaînes, en plus de doubler, en plus des flotteurs. 883 00:47:49,000 --> 00:47:54,000 >> Dès cet instant dans la ligne 11 du temps, il ya maintenant un nouveau type de données appelé les étudiants, 884 00:47:54,000 --> 00:47:58,000 et maintenant je peux déclarer une variable étudiant où je veux, 885 00:47:58,000 --> 00:48:01,000 alors laissez-moi faire défiler ici pour les gens. 886 00:48:01,000 --> 00:48:05,000 Maintenant je peux me débarrasser de cela, et je peux redescendre à David ici, 887 00:48:05,000 --> 00:48:10,000 et David je peux vraiment dire que David, 888 00:48:10,000 --> 00:48:13,000 nous pouvons littéralement le nom de la variable après moi, 889 00:48:13,000 --> 00:48:16,000 va être de l'étudiant type. 890 00:48:16,000 --> 00:48:18,000 Cela peut sembler un peu bizarre, mais ce n'est pas si différent 891 00:48:18,000 --> 00:48:22,000 de déclarer quelque chose comme un int ou une chaîne ou un flotteur. 892 00:48:22,000 --> 00:48:24,000 Il se trouve juste à être appelé étudiant maintenant, 893 00:48:24,000 --> 00:48:28,000 et si je veux mettre quelque chose à l'intérieur de cette structure 894 00:48:28,000 --> 00:48:31,000 Je dois maintenant utiliser un nouveau morceau de syntaxe, mais il est assez simple, 895 00:48:31,000 --> 00:48:39,000 david.id = 123, david.name = "David" dans le capital D, 896 00:48:39,000 --> 00:48:42,000 et david.house = "Mather," 897 00:48:42,000 --> 00:48:46,000 et maintenant je peux me débarrasser de ce truc ici. 898 00:48:46,000 --> 00:48:51,000 Notez que nous avons redessiné notre programme vraiment une bien meilleure façon 899 00:48:51,000 --> 00:48:54,000 dans ce moment de notre programme reflète le monde réel. 900 00:48:54,000 --> 00:48:57,000 >> Il ya une notion du monde réel d'une personne ou d'un étudiant. 901 00:48:57,000 --> 00:49:02,000 Ici, nous avons maintenant une version C d'une personne ou plus précisément un étudiant. 902 00:49:02,000 --> 00:49:05,000 A l'intérieur de cette personne sont ces caractéristiques pertinentes, 903 00:49:05,000 --> 00:49:10,000 ID, le nom et la maison, donc Rob devient essentiellement la même chose ici-bas, 904 00:49:10,000 --> 00:49:14,000 si l'élève rob, et maintenant rob.id = 456, 905 00:49:14,000 --> 00:49:17,000 rob.name = "Rob". 906 00:49:17,000 --> 00:49:20,000 Le fait que la variable est appelée Rob est un peu vide de sens. 907 00:49:20,000 --> 00:49:22,000 Nous aurions pu appelé x, y ou z. 908 00:49:22,000 --> 00:49:25,000 Nous venons tout juste nommé Rob pour être sémantiquement cohérente, 909 00:49:25,000 --> 00:49:28,000 mais en réalité le nom est à l'intérieur de ce champ lui-même, 910 00:49:28,000 --> 00:49:30,000 alors maintenant j'ai cette. 911 00:49:30,000 --> 00:49:33,000 Cela ne veut pas trop envie de la meilleure conception de ce que j'ai codé en dur David. 912 00:49:33,000 --> 00:49:35,000 J'ai codé en dur Rob. 913 00:49:35,000 --> 00:49:39,000 Et j'ai encore de recourir à une copiez et collez chaque fois que je veux de nouvelles variables. 914 00:49:39,000 --> 00:49:43,000 Par ailleurs, je dois apparemment donner à chacun de ces variables un nom, 915 00:49:43,000 --> 00:49:46,000 même si je préfère de loin décrire ces variables 916 00:49:46,000 --> 00:49:48,000  étudiants plus génériquement comme. 917 00:49:48,000 --> 00:49:52,000 >> Maintenant, nous pouvons fusionner les idées qui ont bien fonctionné pour nous 918 00:49:52,000 --> 00:49:56,000 et au lieu de dire: «Vous savez quoi, donnez-moi une variable appelée étudiants, 919 00:49:56,000 --> 00:50:01,000 et mangeons que ce soit de taille 3, "alors maintenant je peux affiner plus loin, 920 00:50:01,000 --> 00:50:04,000 se débarrasser de la main déclaré David, 921 00:50:04,000 --> 00:50:08,000 et je peux dire à la place quelque chose comme étudiants [0] ici. 922 00:50:08,000 --> 00:50:11,000 Je peux alors dire que les étudiants [0] ici, 923 00:50:11,000 --> 00:50:14,000 étudiants [0] ici, et ainsi de suite, et je peux faire le tour 924 00:50:14,000 --> 00:50:16,000 et nettoyer ça pour Rob. 925 00:50:16,000 --> 00:50:19,000 Je pourrais aussi aller sur maintenant peut-être l'ajout d'une boucle 926 00:50:19,000 --> 00:50:23,000 et en utilisant GetString et getInt pour obtenir effectivement ces valeurs à l'utilisateur. 927 00:50:23,000 --> 00:50:27,000 Je pourrais continuer sur l'ajout d'une constante parce que c'est généralement une mauvaise pratique 928 00:50:27,000 --> 00:50:29,000 de coder en dur un nombre arbitraire comme 3 ici 929 00:50:29,000 --> 00:50:33,000 et puis n'oubliez pas que vous devriez mettre pas plus de 3 étudiants en elle. 930 00:50:33,000 --> 00:50:36,000 Il serait sans doute préférable d'utiliser # define dans le haut de mon dossier 931 00:50:36,000 --> 00:50:40,000 et le facteur qui, donc en fait, laissez-moi aller de l'avant et de généraliser cela. 932 00:50:40,000 --> 00:50:43,000 >> Permettez-moi d'ouvrir un exemple qui est au milieu d'aujourd'hui 933 00:50:43,000 --> 00:50:46,000 exemples à l'avance, structs1. 934 00:50:46,000 --> 00:50:49,000 Il s'agit d'un programme plus complet qui utilise # define ici 935 00:50:49,000 --> 00:50:51,000 et dit que nous allons avoir 3 étudiants par défaut. 936 00:50:51,000 --> 00:50:54,000 Ici, je suis en déclarant une valeur de classe d'étudiants, 937 00:50:54,000 --> 00:50:57,000 si une classe d'étudiants, et maintenant je suis en utilisant une boucle 938 00:50:57,000 --> 00:51:00,000 juste pour rendre le code un peu plus élégant, peupler la classe 939 00:51:00,000 --> 00:51:05,000 avec l'entrée de l'utilisateur, afin d'itérer i = 0 sur place pour les étudiants, ce qui est 3. 940 00:51:05,000 --> 00:51:07,000 Et puis je demander à l'utilisateur de cette version 941 00:51:07,000 --> 00:51:10,000  ce qui est l'ID de l'étudiant, et je l'obtenir avec getInt. 942 00:51:10,000 --> 00:51:13,000 Quel est le nom de l'étudiant, puis-je le faire avec GetString. 943 00:51:13,000 --> 00:51:15,000 Quelle est la maison de l'étudiant? Je me le procurer avec GetString. 944 00:51:15,000 --> 00:51:19,000 Et puis, au fond, j'ai tout simplement décidé de changer 945 00:51:19,000 --> 00:51:22,000 comment je vais imprimer ces cartes et d'utiliser effectivement une boucle, 946 00:51:22,000 --> 00:51:24,000 et qui suis-je imprimer? 947 00:51:24,000 --> 00:51:27,000 Selon le commentaire, je suis d'imprimer n'importe qui dans Mather, 948 00:51:27,000 --> 00:51:30,000 et c'est tellement Rob et Tommy et ainsi de suite, fait de Tommy dans Mather. 949 00:51:30,000 --> 00:51:34,000 Tommy et David serait imprimée dans ce cas, mais comment est-ce de travail? 950 00:51:34,000 --> 00:51:40,000 Nous n'avons pas vu cette fonction avant, mais faire une supposition quant à ce que cela fait. 951 00:51:40,000 --> 00:51:42,000 Compare les chaînes. 952 00:51:42,000 --> 00:51:45,000 >> C'est un peu non évidente comment il se compare des chaînes car il s'avère 953 00:51:45,000 --> 00:51:49,000 si elle retourne 0 signifie que les chaînes sont égales. 954 00:51:49,000 --> 00:51:53,000 Si elle retourne -1 signifie que l'on vient avant l'autre par ordre alphabétique, 955 00:51:53,000 --> 00:51:57,000 et si elle retourne +1 qui signifie que le mot vient d'autres par ordre alphabétique 956 00:51:57,000 --> 00:52:00,000 avant l'autre, et que vous pouvez consulter en ligne ou à la page de manuel 957 00:52:00,000 --> 00:52:04,000 pour voir exactement où est qui, mais tout cela est en train de faire, c'est que c'est en disant 958 00:52:04,000 --> 00:52:09,000 si le [i]. maison est égal à "Mather" 959 00:52:09,000 --> 00:52:13,000 alors allez-y et imprimer ainsi et est donc à Mather. 960 00:52:13,000 --> 00:52:16,000 Mais voici quelque chose que nous n'avons pas vu avant, et nous reviendrons sur ce sujet. 961 00:52:16,000 --> 00:52:21,000 Je ne me souviens pas avoir à le faire dans un de mes programmes. 962 00:52:21,000 --> 00:52:24,000 Free est apparemment référence à la mémoire, libération de la mémoire, 963 00:52:24,000 --> 00:52:31,000 mais quel souvenir je libère apparemment dans cette boucle au bas de ce programme? 964 00:52:31,000 --> 00:52:34,000 On dirait que je suis en libérant nom d'une personne 965 00:52:34,000 --> 00:52:37,000 et la maison d'une personne, mais pourquoi est-ce? 966 00:52:37,000 --> 00:52:41,000 >> Il s'avère que toutes ces semaines vous avez été en utilisant GetString 967 00:52:41,000 --> 00:52:45,000 nous avons été genre d'introduire un bogue dans chacune de vos programmes. 968 00:52:45,000 --> 00:52:51,000 GetString par la conception alloue de la mémoire pour qu'il puisse revenir à vous une chaîne, 969 00:52:51,000 --> 00:52:55,000 comme David, ou Rob, et vous pouvez alors faire ce que vous voulez 970 00:52:55,000 --> 00:52:59,000 avec cette chaîne dans votre programme parce que nous avons réservé la mémoire pour vous. 971 00:52:59,000 --> 00:53:02,000 Le problème, c'est tout ce temps, chaque fois que vous appelez GetString 972 00:53:02,000 --> 00:53:05,000 nous, les auteurs de GetString, ont demandé au système d'exploitation 973 00:53:05,000 --> 00:53:07,000 pour nous donner un peu de RAM pour cette chaîne. 974 00:53:07,000 --> 00:53:09,000 Donnez-nous un peu de RAM pour cette chaîne suivante. 975 00:53:09,000 --> 00:53:11,000 Donnez-nous un peu plus de RAM pour cette chaîne suivante. 976 00:53:11,000 --> 00:53:13,000 Qu'est-ce que vous, le programmeur, n'ont jamais fait 977 00:53:13,000 --> 00:53:15,000 nous donne que de retour de la mémoire, 978 00:53:15,000 --> 00:53:17,000 donc pour ces quelques semaines tous les programmes que vous avez écrit 979 00:53:17,000 --> 00:53:20,000 ont eu ce qu'on appelle un saut de mémoire par lequel ils continuer à utiliser 980 00:53:20,000 --> 00:53:24,000 mémoire de plus en plus à chaque fois que vous appelez GetString, et c'est très bien. 981 00:53:24,000 --> 00:53:27,000 Nous avons délibérément le faire dans les premières semaines parce que ce n'est pas si intéressant 982 00:53:27,000 --> 00:53:29,000 avoir à s'inquiéter de savoir où la chaîne est en venir. 983 00:53:29,000 --> 00:53:34,000 Tout ce que vous voulez, c'est le mot Rob revenir lorsque l'utilisateur le type po 984 00:53:34,000 --> 00:53:38,000 >> Mais aller de l'avant, nous avons maintenant de commencer à obtenir plus sophistiquée à ce sujet. 985 00:53:38,000 --> 00:53:42,000 Chaque fois que nous nous ferions mieux allouer de la mémoire finit par le remettre en arrière. 986 00:53:42,000 --> 00:53:45,000 Sinon, dans le monde réel sur votre Mac ou PC que vous pourriez avoir l'occasion expérimenté 987 00:53:45,000 --> 00:53:50,000 symptômes où votre ordinateur est de broyage pour une halte à terme 988 00:53:50,000 --> 00:53:54,000 ou le ballon de plage est juste stupide de filature occupant le l'ordinateur 989 00:53:54,000 --> 00:53:56,000 une attention entière et vous ne pouvez pas faire les choses. 990 00:53:56,000 --> 00:54:00,000 Cela peut s'expliquer par un certain nombre de bugs, mais parmi ces bugs possibles 991 00:54:00,000 --> 00:54:03,000 sont choses appelées fuites de mémoire par lequel quelqu'un qui a écrit ce morceau de logiciel 992 00:54:03,000 --> 00:54:07,000 vous utilisez ne se souvenait pas de libérer la mémoire 993 00:54:07,000 --> 00:54:10,000 qu'il ou elle a demandé au système d'exploitation pour, 994 00:54:10,000 --> 00:54:14,000 ne pas utiliser GetString, parce que c'est une chose CS50, mais en utilisant des fonctions similaires 995 00:54:14,000 --> 00:54:16,000 que demander au système d'exploitation pour la mémoire. 996 00:54:16,000 --> 00:54:19,000 Si vous ou de mauvaise manipulation, et jamais retourner cette mémoire 997 00:54:19,000 --> 00:54:24,000 un symptôme de ce que peut être un programme ralentit et freine et ralentit 998 00:54:24,000 --> 00:54:26,000 à moins que vous n'oubliez pas d'appeler gratuitement. 999 00:54:26,000 --> 00:54:28,000 >> Nous y reviendrons quand et pourquoi vous appelez gratuitement, 1000 00:54:28,000 --> 00:54:32,000 mais nous allons aller de l'avant pour faire bonne mesure et essayez d'exécuter ce programme en particulier. 1001 00:54:32,000 --> 00:54:35,000 Cela a été appelé structs1, entrez. 1002 00:54:35,000 --> 00:54:40,000 Permettez-moi aller de l'avant et exécutez structs1, 123, David Mather, 1003 00:54:40,000 --> 00:54:47,000 456, Rob Kirkland, 789, 1004 00:54:47,000 --> 00:54:50,000 Tommy Mather, et l'on voit David à Mather, de Tommy dans Mather. 1005 00:54:50,000 --> 00:54:53,000 Ceci est juste un test de cohérence peu que le programme fonctionne. 1006 00:54:53,000 --> 00:54:56,000 Maintenant, malheureusement, ce programme est un peu frustrant dans ce 1007 00:54:56,000 --> 00:55:00,000 Je n'ai tout ce travail, j'ai tapé dans 9 différentes chaînes, appuyez sur Entrée, 1008 00:55:00,000 --> 00:55:04,000 On m'a dit qui était à Mather, mais évidemment je savais qui était à Mather déjà parce que je l'ai tapé. 1009 00:55:04,000 --> 00:55:07,000 Il serait moins agréable si ce programme ressemble plus à une base de données 1010 00:55:07,000 --> 00:55:10,000 et il se souvient effectivement ce que j'ai tapé dans 1011 00:55:10,000 --> 00:55:12,000 donc je ne plus jamais avoir à saisir ces dossiers des étudiants. 1012 00:55:12,000 --> 00:55:15,000 Peut-être que c'est comme un système de registrariat. 1013 00:55:15,000 --> 00:55:21,000 >> Nous pouvons le faire en utilisant cette technique connue sous le nom de fichier du fichier d'entrée I / O et de sortie, 1014 00:55:21,000 --> 00:55:24,000 d'une manière très générique de dire chaque fois que vous voulez lire des fichiers ou écrire des fichiers 1015 00:55:24,000 --> 00:55:26,000 vous pouvez le faire avec un certain ensemble de fonctions. 1016 00:55:26,000 --> 00:55:29,000 Permettez-moi aller de l'avant et ouvrez ce structs2.c exemple, 1017 00:55:29,000 --> 00:55:33,000 qui est presque identique, mais nous allons voir ce qu'il fait maintenant. 1018 00:55:33,000 --> 00:55:36,000 Au sommet du dossier, je déclare une classe d'élèves. 1019 00:55:36,000 --> 00:55:38,000 Je puis remplir la classe avec l'entrée de l'utilisateur, 1020 00:55:38,000 --> 00:55:41,000 de sorte que ces lignes de code sont exactement comme avant. 1021 00:55:41,000 --> 00:55:45,000 Ensuite, si je défiler vers le bas ici je imprimer tout le monde qui est à Mather arbitrairement comme avant, 1022 00:55:45,000 --> 00:55:47,000 mais c'est une nouveauté intéressante. 1023 00:55:47,000 --> 00:55:51,000 Ces lignes de code sont nouveaux, et ils introduisent quelque chose ici, 1024 00:55:51,000 --> 00:55:55,000 FICHIER, tout en majuscules, et il a * ici aussi. 1025 00:55:55,000 --> 00:55:58,000 Permettez-moi de passer ce cours ici, a * ici aussi. 1026 00:55:58,000 --> 00:56:00,000 >> Cette fonction nous n'avons pas vu avant, fopen, 1027 00:56:00,000 --> 00:56:03,000 mais cela signifie fichier ouvert, nous allons donc parcourir celles-ci, 1028 00:56:03,000 --> 00:56:05,000 et c'est quelque chose que nous y reviendrons dans psets futures, 1029 00:56:05,000 --> 00:56:10,000 mais cette ligne ouvre ici essentiellement un fichier appelé base de données, 1030 00:56:10,000 --> 00:56:13,000 et il ouvre spécifiquement de telle manière qu'il puisse faire quoi pour elle? 1031 00:56:13,000 --> 00:56:15,000 [Inaudible étudiant] 1032 00:56:15,000 --> 00:56:19,000 Bon, alors "w" signifie simplement qu'il raconte le système d'exploitation 1033 00:56:19,000 --> 00:56:21,000 ouvrir ce fichier de telle sorte que je puisse écrire dessus. 1034 00:56:21,000 --> 00:56:23,000 Je n'ai pas envie de le lire. Je ne tiens pas à le regarder. 1035 00:56:23,000 --> 00:56:26,000 Je tiens à le modifier et ajouter des choses potentiellement à elle, 1036 00:56:26,000 --> 00:56:28,000 et le fichier va être appelée base de données. 1037 00:56:28,000 --> 00:56:30,000 Cela pourrait être appelé n'importe quoi. 1038 00:56:30,000 --> 00:56:32,000 Cela pourrait être database.txt. Cela pourrait être. Db. 1039 00:56:32,000 --> 00:56:37,000 Cela pourrait être un mot comme foo, mais je arbitrairement choisi de nommer le fichier base de données. 1040 00:56:37,000 --> 00:56:42,000 Il s'agit d'un test de cohérence peu que nous y reviendrons en détail au fil du temps, 1041 00:56:42,000 --> 00:56:47,000 si fp, pour pointeur de fichier, ne pas NULL égale ce qui signifie que tout va bien. 1042 00:56:47,000 --> 00:56:51,000 >> Longue histoire courte, les fonctions comme fopen parfois échouer. 1043 00:56:51,000 --> 00:56:53,000 Peut-être que le fichier n'existe pas. Peut-être que vous êtes hors de l'espace disque. 1044 00:56:53,000 --> 00:56:55,000 Peut-être que vous n'avez pas la permission de ce dossier, 1045 00:56:55,000 --> 00:56:58,000 si fopen retourne quelque chose de grave n'est arrivé nulle. 1046 00:56:58,000 --> 00:57:02,000 Inversement, si la fonction fopen ne retourne pas nulle tout va bien 1047 00:57:02,000 --> 00:57:04,000 et je peux commencer à écrire dans ce fichier. 1048 00:57:04,000 --> 00:57:06,000 Voici une nouvelle astuce. 1049 00:57:06,000 --> 00:57:08,000 Il s'agit d'une boucle pour itérer sur qui est chacun de mes élèves, 1050 00:57:08,000 --> 00:57:10,000 et cela a l'air si semblable à ce que nous avons fait avant, 1051 00:57:10,000 --> 00:57:15,000 mais cette fonction est un cousin de printf fprintf appelé pour le fichier printf, 1052 00:57:15,000 --> 00:57:18,000 et remarquez que c'est différent en seulement 2 façons. 1053 00:57:18,000 --> 00:57:20,000 Premièrement, il commence par f au lieu de p, 1054 00:57:20,000 --> 00:57:23,000 mais alors son premier argument est apparemment quoi? 1055 00:57:23,000 --> 00:57:25,000 [Etudiants] du fichier. >> C'est un fichier. 1056 00:57:25,000 --> 00:57:30,000 Cette chose appelée fp, que nous finirons par démêler ce qui est un pointeur de fichier, 1057 00:57:30,000 --> 00:57:35,000 mais pour l'instant fp représente simplement le fichier que j'ai ouvert, 1058 00:57:35,000 --> 00:57:41,000 si fprintf dit ici imprimer ID d'utilisateur pour le fichier, et non pas à l'écran. 1059 00:57:41,000 --> 00:57:44,000 Imprimer le nom de l'utilisateur dans le fichier, et non pas à l'écran, 1060 00:57:44,000 --> 00:57:47,000 la maison pour le fichier, et non pas à l'écran, puis ici, de toute évidence, 1061 00:57:47,000 --> 00:57:50,000 fermez le fichier, puis ici-bas libérer la mémoire. 1062 00:57:50,000 --> 00:57:53,000 >> La seule différence entre cette version 2 et la version 1 1063 00:57:53,000 --> 00:57:58,000 est l'introduction de la fonction fopen et ce fichier avec * 1064 00:57:58,000 --> 00:58:01,000 et cette notion de fprintf, nous allons donc voir ce que le résultat final. 1065 00:58:01,000 --> 00:58:03,000 Laissez-moi aller dans ma fenêtre de terminal. 1066 00:58:03,000 --> 00:58:06,000 Permettez-moi de lancer structs2, entrez. 1067 00:58:06,000 --> 00:58:09,000 On dirait que tout va bien. Nous allons relancer structs2. 1068 00:58:09,000 --> 00:58:15,000 123, David Mather, 456, Rob Kirkland, 1069 00:58:15,000 --> 00:58:19,000 789, Tommy Mather, entrez. 1070 00:58:19,000 --> 00:58:23,000 On dirait qu'il se comportaient de la même chose, mais si je fais maintenant ls 1071 00:58:23,000 --> 00:58:28,000 remarquez ce fichier est ici parmi tout mon code, base de données, 1072 00:58:28,000 --> 00:58:32,000 nous allons donc ouvrir ce, gedit de base de données, et coup d'oeil. 1073 00:58:32,000 --> 00:58:34,000 Ce n'est pas la plus sexy de formats de fichiers. 1074 00:58:34,000 --> 00:58:38,000 C'est vraiment un morceau de ligne de données par ligne par ligne, 1075 00:58:38,000 --> 00:58:42,000 mais ceux d'entre vous qui utilisent des fichiers Excel ou CSV, comma separated values, 1076 00:58:42,000 --> 00:58:47,000 Je pourrais certainement utilisé à la place fprintf peut-être faire quelque chose comme ceci 1077 00:58:47,000 --> 00:58:50,000 de sorte que je pouvais créer l'équivalent d'un fichier Excel 1078 00:58:50,000 --> 00:58:53,000 en séparant par des virgules choses, et pas seulement les nouvelles lignes. 1079 00:58:53,000 --> 00:58:56,000 >> Dans ce cas, si j'avais utilisé à la place des virgules au lieu de lignes nouvelles 1080 00:58:56,000 --> 00:59:01,000 Je pourrais littéralement ouvrir ce fichier de base de données dans Excel si je plutôt fait ressembler à ceci. 1081 00:59:01,000 --> 00:59:03,000 En bref, maintenant que nous avons le pouvoir d'écrire dans des fichiers 1082 00:59:03,000 --> 00:59:07,000 nous pouvons maintenant commencer la persistance des données, en le gardant dans le disque 1083 00:59:07,000 --> 00:59:10,000 afin que nous puissions garder l'information autour encore et encore. 1084 00:59:10,000 --> 00:59:14,000 Notez quelques autres choses qui sont maintenant un peu plus familier. 1085 00:59:14,000 --> 00:59:16,000 Au sommet de ce fichier C nous avons un typedef 1086 00:59:16,000 --> 00:59:21,000 parce que nous avons voulu créer un type de données qui représente un mot, 1087 00:59:21,000 --> 00:59:25,000 si ce type est appelé mot, et à l'intérieur de cette structure 1088 00:59:25,000 --> 00:59:27,000 il est maintenant un peu plus fantaisistes. 1089 00:59:27,000 --> 00:59:30,000 Pourquoi est un mot composé en apparence un tableau? 1090 00:59:30,000 --> 00:59:33,000 Qu'est-ce qu'un mot juste intuitivement? 1091 00:59:33,000 --> 00:59:35,000 >> C'est un tableau de caractères. 1092 00:59:35,000 --> 00:59:37,000 Il s'agit d'une séquence de caractères dos à dos à dos. 1093 00:59:37,000 --> 00:59:41,000 LETTRES tous les chapeaux se trouve être nous dire arbitrairement la longueur maximale 1094 00:59:41,000 --> 00:59:44,000 d'un mot dans le dictionnaire que nous utilisons pour Scramble. 1095 00:59:44,000 --> 00:59:46,000 Pourquoi dois-je avoir un +1? 1096 00:59:46,000 --> 00:59:48,000 Le caractère nul. 1097 00:59:48,000 --> 00:59:51,000 Rappelons quand nous avons l'exemple Bananagrams nous avions besoin d'une valeur spéciale 1098 00:59:51,000 --> 00:59:55,000 à la fin de la parole, afin de garder une trace 1099 00:59:55,000 --> 00:59:59,000 d'où les mots effectivement pris fin, et que la spécification du jeu de problème dit 1100 00:59:59,000 --> 01:00:03,000 ici nous associer à un mot donné une valeur booléenne, 1101 01:00:03,000 --> 01:00:05,000 un drapeau, pour ainsi dire, vrai ou faux. 1102 01:00:05,000 --> 01:00:09,000 Avez-vous trouvé ce mot déjà, parce que nous nous rendons compte 1103 01:00:09,000 --> 01:00:13,000 nous avons vraiment besoin d'un moyen de se rappeler non seulement ce qui est en un mot Scramble 1104 01:00:13,000 --> 01:00:15,000 mais si vous, l'humain, ont trouvé 1105 01:00:15,000 --> 01:00:20,000 de sorte que si vous trouvez le mot "the" vous ne pouvez pas il suffit de taper l', entrez, la, entrez, l', entrez 1106 01:00:20,000 --> 01:00:23,000 et obtenez 3 points, 3 points, 3 points, 3 points. 1107 01:00:23,000 --> 01:00:26,000 Nous voulons être en mesure à la liste noire de ce mot en fixant un bool 1108 01:00:26,000 --> 01:00:29,000 à vrai si vous avez déjà trouvé, et c'est pourquoi nous 1109 01:00:29,000 --> 01:00:31,000 il encapsulé dans cette structure. 1110 01:00:31,000 --> 01:00:35,000 >> Maintenant, ici-bas dans la lutte confuse, il ya cette autre structure appelée dictionnaire. 1111 01:00:35,000 --> 01:00:39,000 En l'absence ici est le mot typedef car dans ce cas 1112 01:00:39,000 --> 01:00:43,000 nous avions besoin d'encapsuler l'idée d'un dictionnaire, 1113 01:00:43,000 --> 01:00:46,000 et un dictionnaire contient tout un tas de mots, 1114 01:00:46,000 --> 01:00:49,000 comme le laisse entendre ce tableau, et combien de ces mots sont-ils? 1115 01:00:49,000 --> 01:00:51,000 Eh bien, quelle que soit cette taille variable appelée dit. 1116 01:00:51,000 --> 01:00:53,000 Mais nous avons juste besoin d'un dictionnaire. 1117 01:00:53,000 --> 01:00:55,000 Nous n'avons pas besoin d'un type de données appelé dictionnaire. 1118 01:00:55,000 --> 01:00:58,000 Nous avons juste besoin d'eux, de sorte qu'il s'avère en C 1119 01:00:58,000 --> 01:01:03,000 que si vous ne dites pas typedef, tu viens de dire struct, puis à l'intérieur des accolades 1120 01:01:03,000 --> 01:01:05,000 vous mettez vos variables, puis vous mettez le nom. 1121 01:01:05,000 --> 01:01:09,000 Ceci est un dictionnaire déclarant variable appelée 1122 01:01:09,000 --> 01:01:11,000 qui ressemble à ceci. 1123 01:01:11,000 --> 01:01:16,000 En revanche, ces lignes sont la création d'une structure de données appelée réutilisable mot 1124 01:01:16,000 --> 01:01:19,000 que vous pouvez créer plusieurs copies d', tout comme nous avons créé 1125 01:01:19,000 --> 01:01:22,000 plusieurs copies d'élèves. 1126 01:01:22,000 --> 01:01:24,000 >> Qu'est-ce que cela en fin de compte nous permettre de faire? 1127 01:01:24,000 --> 01:01:30,000 Permettez-moi de revenir en arrière dans, disons, un exemple plus simple d'une époque plus simple, 1128 01:01:30,000 --> 01:01:34,000 et laissez-moi ouvrir, disons, compare1.c. 1129 01:01:34,000 --> 01:01:38,000 Le problème ici est à portée de main pour réellement décoller 1130 01:01:38,000 --> 01:01:41,000 la couche d'une chaîne et commencer à décoller ces roues de formation 1131 01:01:41,000 --> 01:01:44,000 car il s'avère qu'une chaîne tout ce temps 1132 01:01:44,000 --> 01:01:47,000 comme nous l'avons promis dans la semaine 1 vraiment juste un surnom, 1133 01:01:47,000 --> 01:01:51,000 un synonyme de la bibliothèque CS50 pour quelque chose qui ressemble un peu plus cryptique, 1134 01:01:51,000 --> 01:01:53,000 char *, et nous avons vu cette étoile avant. 1135 01:01:53,000 --> 01:01:55,000 Nous l'avons vu dans le contexte de fichiers. 1136 01:01:55,000 --> 01:01:59,000 >> Voyons maintenant pourquoi nous avons caché ce détail pour un certain temps maintenant. 1137 01:01:59,000 --> 01:02:02,000 Voici un fichier appelé compare1.c, 1138 01:02:02,000 --> 01:02:07,000 et demande à l'utilisateur apparemment pour 2 chaînes, s et t, 1139 01:02:07,000 --> 01:02:11,000 et alors il essaie de comparer ces chaînes pour l'égalité dans la ligne 26, 1140 01:02:11,000 --> 01:02:14,000 et si elles sont égales il dit, "Vous avez tapé la même chose», 1141 01:02:14,000 --> 01:02:17,000 et s'ils ne sont pas égaux il dit, "Vous avez tapé choses différentes." 1142 01:02:17,000 --> 01:02:19,000 Permettez-moi aller de l'avant et exécuter ce programme. 1143 01:02:19,000 --> 01:02:23,000 Laissez-moi aller dans mon répertoire source, faire une compare1. Il compilé correct. 1144 01:02:23,000 --> 01:02:25,000 Permettez-moi de lancer compare1. 1145 01:02:25,000 --> 01:02:27,000 Je vais effectuer un zoom avant, entrez. 1146 01:02:27,000 --> 01:02:29,000 Dis quelque chose. BONJOUR. 1147 01:02:29,000 --> 01:02:32,000 Je vais dire quelque chose de nouveau. BONJOUR. 1148 01:02:32,000 --> 01:02:34,000 Je n'ai vraiment pas taper des choses différentes. 1149 01:02:34,000 --> 01:02:37,000 >> Je vais essayer encore une fois. BYE BYE. 1150 01:02:37,000 --> 01:02:40,000 Certainement pas différent, donc ce qui se passe ici? 1151 01:02:40,000 --> 01:02:44,000 Eh bien, ce qui est réellement par rapport à la ligne 26? 1152 01:02:44,000 --> 01:02:46,000 [Inaudible étudiant] 1153 01:02:46,000 --> 01:02:49,000 Oui, il s'avère qu'une chaîne, type de données, est une sorte de mensonge. 1154 01:02:49,000 --> 01:02:53,000 Une chaîne est un char *, mais ce qui est un char *? 1155 01:02:53,000 --> 01:02:56,000 Un char *, comme on dit, est un pointeur, 1156 01:02:56,000 --> 01:03:00,000 et un pointeur est effectivement une adresse, 1157 01:03:00,000 --> 01:03:05,000 un emplacement dans la mémoire de somme, et s'il vous arrive d'avoir tapé un mot comme BONJOUR, 1158 01:03:05,000 --> 01:03:08,000 rappelle des discussions passées de chaînes 1159 01:03:08,000 --> 01:03:16,000 C'est comme le mot BONJOUR. 1160 01:03:16,000 --> 01:03:19,000 Rappelez-vous qu'un mot comme BONJOUR peut être représenté 1161 01:03:19,000 --> 01:03:22,000 comme un tableau de caractères comme ceci 1162 01:03:22,000 --> 01:03:25,000 et ensuite avec un caractère spécial appelé à la fin du caractère nul, 1163 01:03:25,000 --> 01:03:27,000 comme le représente \. 1164 01:03:27,000 --> 01:03:29,000 Quelle est en fait une chaîne? 1165 01:03:29,000 --> 01:03:32,000 Notez que ceci est nombreux blocs de mémoire, 1166 01:03:32,000 --> 01:03:36,000 et en fait, la fin de celui-ci n'est connu qu'une fois que vous regardez à travers toute la chaîne 1167 01:03:36,000 --> 01:03:38,000 à la recherche pour le caractère nul spéciale. 1168 01:03:38,000 --> 01:03:41,000 Mais si c'est un morceau de mémoire de la mémoire de mon ordinateur, 1169 01:03:41,000 --> 01:03:44,000 nous allons arbitrairement que cette chaîne juste eu de la chance, 1170 01:03:44,000 --> 01:03:47,000 et il s'est placé dès le début de la RAM de mon ordinateur. 1171 01:03:47,000 --> 01:03:54,000 C'est octet 0, 1, 2, 3, 4, 5, 6 ... 1172 01:03:54,000 --> 01:04:02,000 >> Quand je dis quelque chose comme GetString et je fais string s = GetString 1173 01:04:02,000 --> 01:04:04,000 ce qui est vraiment retourné? 1174 01:04:04,000 --> 01:04:08,000 Pour ces dernières semaines, ce qui est réellement stocké dans s 1175 01:04:08,000 --> 01:04:13,000 n'est pas cette chaîne en soi, mais dans ce cas ce qui est stocké est 1176 01:04:13,000 --> 01:04:18,000 le numéro 0 parce que ce qui fait réellement GetString 1177 01:04:18,000 --> 01:04:20,000 est physiquement il ne retournera une chaîne. 1178 01:04:20,000 --> 01:04:22,000 Cela ne veut même pas vraiment de sens conceptuel. 1179 01:04:22,000 --> 01:04:24,000 Ce qu'il fait retour est un nombre. 1180 01:04:24,000 --> 01:04:28,000 Ce nombre est l'adresse de la mémoire BONJOUR, 1181 01:04:28,000 --> 01:04:32,000 et la chaîne s lors, si nous décoller cette couche, chaîne n'existe pas vraiment. 1182 01:04:32,000 --> 01:04:35,000 C'est seulement une simplification dans la bibliothèque CS50. 1183 01:04:35,000 --> 01:04:38,000 >> C'est vraiment quelque chose qui s'appelle char *. 1184 01:04:38,000 --> 01:04:41,000 Char est logique car ce qui est un mot, comme BONJOUR? 1185 01:04:41,000 --> 01:04:44,000 Eh bien, c'est une série de caractères, une série de caractères. 1186 01:04:44,000 --> 01:04:47,000 Char * signifie que l'adresse d'un personnage, 1187 01:04:47,000 --> 01:04:50,000 alors qu'est-ce que cela signifie pour retourner une chaîne? 1188 01:04:50,000 --> 01:04:53,000 Une belle façon simple de retourner une chaîne 1189 01:04:53,000 --> 01:04:57,000 est plutôt que d'essayer de comprendre comment je reviens à 5 ou 6 différents octets 1190 01:04:57,000 --> 01:05:01,000 laissez-moi retourner à l'adresse de l'octet? 1191 01:05:01,000 --> 01:05:03,000 La première. 1192 01:05:03,000 --> 01:05:06,000 En d'autres termes, permettez-moi de vous donner l'adresse d'un caractère dans la mémoire. 1193 01:05:06,000 --> 01:05:10,000 C'est ce char * représente l'adresse d'un caractère unique dans la mémoire. 1194 01:05:10,000 --> 01:05:12,000 Appelez cette variable s. 1195 01:05:12,000 --> 01:05:15,000 Conserver dans s cette adresse particulière, que j'ai dit est arbitraire 0, 1196 01:05:15,000 --> 01:05:19,000 juste pour garder les choses simples, mais en réalité, c'est généralement un plus grand nombre. 1197 01:05:19,000 --> 01:05:21,000 >> Attendez une minute. 1198 01:05:21,000 --> 01:05:23,000 Si vous êtes seulement de me donner l'adresse du premier caractère, comment puis-je savoir ce que l'adresse est 1199 01:05:23,000 --> 01:05:25,000 du caractère second, le troisième, le quatrième et le cinquième? 1200 01:05:25,000 --> 01:05:27,000 [Inaudible étudiant] 1201 01:05:27,000 --> 01:05:31,000 Vous ne savez où la fin de la chaîne est par le biais de cette astuce très pratique, 1202 01:05:31,000 --> 01:05:35,000 Ainsi, lorsque vous utilisez quelque chose comme printf, ce qui littéralement printf prend comme argument, 1203 01:05:35,000 --> 01:05:39,000 Rappelons que nous utilisons espace réservé ce% s, puis vous passez dans 1204 01:05:39,000 --> 01:05:41,000 la variable qui est une chaîne de stockage. 1205 01:05:41,000 --> 01:05:47,000 Qu'est-ce que vous êtes vraiment passer est l'adresse du premier caractère de cette chaîne. 1206 01:05:47,000 --> 01:05:50,000 Printf utilise ensuite une boucle for ou une boucle while en recevant cette adresse, 1207 01:05:50,000 --> 01:05:53,000 par exemple, 0, permettez-moi de le faire maintenant, 1208 01:05:53,000 --> 01:06:02,000 printf ("% s \ n", s); 1209 01:06:02,000 --> 01:06:07,000 Quand je l'appelle printf ("% s \ n", s), ce que je suis vraiment fournir printf avec 1210 01:06:07,000 --> 01:06:13,000 est l'adresse du premier caractère à l'art, qui dans ce cas est arbitraire H. 1211 01:06:13,000 --> 01:06:16,000 >> Comment ça printf savoir exactement quoi afficher sur l'écran? 1212 01:06:16,000 --> 01:06:19,000 La personne qui a mis en œuvre printf mis en place une boucle while ou une boucle for 1213 01:06:19,000 --> 01:06:23,000 qui dit que ce personnage ne égaler le caractère spécial null? 1214 01:06:23,000 --> 01:06:25,000 Sinon, imprimez-le. Que diriez-vous celui-ci? 1215 01:06:25,000 --> 01:06:28,000 Si ce n'est pas de l'imprimer, de l'imprimer, de l'imprimer, de l'imprimer. 1216 01:06:28,000 --> 01:06:32,000 Oh, celui-ci est spécial. Arrêtez l'impression et retourner à l'utilisateur. 1217 01:06:32,000 --> 01:06:35,000 Et c'est littéralement tout ce qui se passe sous le capot, 1218 01:06:35,000 --> 01:06:38,000 et c'est beaucoup à digérer le premier jour de classe, 1219 01:06:38,000 --> 01:06:43,000 mais pour l'instant c'est vraiment la pierre angulaire de tout comprendre 1220 01:06:43,000 --> 01:06:46,000 qui a été passe à l'intérieur de la mémoire de notre ordinateur, 1221 01:06:46,000 --> 01:06:49,000 et, finalement, nous allons taquiner cet appart avec un peu d'aide 1222 01:06:49,000 --> 01:06:51,000 d'un de nos amis à Stanford. 1223 01:06:51,000 --> 01:06:56,000 >> Professeur Nick Parlante à Stanford a fait cette séquence vidéo merveilleuse 1224 01:06:56,000 --> 01:06:58,000 de toutes sortes de langues différentes qui ont introduit 1225 01:06:58,000 --> 01:07:00,000 ce Binky Claymation peu de caractère. 1226 01:07:00,000 --> 01:07:03,000 La voix que vous allez entendre dans quelques avant-première quelques secondes 1227 01:07:03,000 --> 01:07:05,000 est celle d'un professeur de Stanford, et vous obtenez 1228 01:07:05,000 --> 01:07:07,000 seulement 5 ou 6 secondes de ce moment, 1229 01:07:07,000 --> 01:07:09,000 mais c'est la note sur laquelle nous allons terminer aujourd'hui 1230 01:07:09,000 --> 01:07:11,000 et commencer mercredi. 1231 01:07:11,000 --> 01:07:15,000 Je vous donne Fun pointeur avec Binky, l'aperçu. 1232 01:07:15,000 --> 01:07:18,000 [♪ ♪ Musique] [Professeur Parlante] Hey, Binky. 1233 01:07:18,000 --> 01:07:21,000 Réveillez-vous. Il est temps pour le plaisir pointeur. 1234 01:07:21,000 --> 01:07:24,000 [Binky] Qu'est-ce que c'est? Renseignez-vous sur les pointeurs? 1235 01:07:24,000 --> 01:07:26,000 Oh, ma bonne femme! 1236 01:07:26,000 --> 01:07:29,000 >> Nous vous voir mercredi. 1237 01:07:29,000 --> 01:07:32,000 [CS50.TV]