1 00:00:00,000 --> 00:00:02,730 [Powered by Google Translate] [SECTION 5: Moins à l'aise] 2 00:00:02,730 --> 00:00:05,180 [Nate Hardison, Université de Harvard] 3 00:00:05,180 --> 00:00:08,260 [C'est CS50.] [CS50.TV] 4 00:00:08,260 --> 00:00:11,690 Alors, bienvenue en arrière, les gars. 5 00:00:11,690 --> 00:00:16,320 Bienvenue à la section 5. 6 00:00:16,320 --> 00:00:20,220 À ce stade, après avoir terminé quiz 0 et après avoir vu comment vous avez fait, 7 00:00:20,220 --> 00:00:25,770 j'espère que vous vous sentez vraiment bien parce que j'ai été très impressionné par les résultats de cette section. 8 00:00:25,770 --> 00:00:28,050 Pour nos téléspectateurs en ligne, nous avons eu quelques questions 9 00:00:28,050 --> 00:00:33,680 sur les deux derniers problèmes sur le problème posé - ou sur le quiz, plutôt. 10 00:00:33,680 --> 00:00:39,690 Donc nous allons passer en revue les très rapidement afin que tout le monde voit ce qui s'est passé 11 00:00:39,690 --> 00:00:45,060 et comment aller à travers la solution réelle plutôt que la seule visualisation de la solution elle-même. 12 00:00:45,060 --> 00:00:50,330 Nous allons passer en revue les deux dernières de problèmes très rapidement, 32 et 33. 13 00:00:50,330 --> 00:00:53,240 Juste, encore une fois, de sorte que les téléspectateurs en ligne peuvent le voir. 14 00:00:53,240 --> 00:00:59,080 >> Si vous mettez à votre problème 32, qui est à la page 13, 15 00:00:59,080 --> 00:01:02,730 13 sur 16, problème 32 est tout au sujet de swaps. 16 00:01:02,730 --> 00:01:05,010 Il s'agissait de permuter deux entiers. 17 00:01:05,010 --> 00:01:08,740 C'est le problème que nous étions partis sur une couple de fois dans conférence. 18 00:01:08,740 --> 00:01:13,590 Et ici, ce que nous vous demandons de faire une trace de mémoire rapide. 19 00:01:13,590 --> 00:01:17,000 Pour remplir les valeurs des variables comme ils sont sur la pile 20 00:01:17,000 --> 00:01:20,250 que le code passe par cette fonction d'échange. 21 00:01:20,250 --> 00:01:24,500 En particulier, ce que nous cherchons à - je vais mettre cette iPad vers le bas - 22 00:01:24,500 --> 00:01:29,650 en particulier, ce que nous envisageons, c'est cette ligne numéro 6 ici. 23 00:01:29,650 --> 00:01:36,740 Et il est numéroté 6 pour seulement contiguïté avec le problème précédent. 24 00:01:36,740 --> 00:01:41,720 Ce que nous voulons faire est d'afficher ou étiqueter l'état de la mémoire 25 00:01:41,720 --> 00:01:46,090 car il est à la fois lorsque nous exécutons ce nombre 6 lignes, 26 00:01:46,090 --> 00:01:52,540 qui est effectivement un retour de notre fonction de permutation ici. 27 00:01:52,540 --> 00:01:59,450 Si nous défiler vers le bas ici, nous avons vu que les adresses de tout ce que la mémoire a été prévu pour nous. 28 00:01:59,450 --> 00:02:02,540 Cela est très essentiel, nous allons y revenir dans un instant. 29 00:02:02,540 --> 00:02:09,240 Et puis, ici-bas au fond, nous avons eu un peu de mémoire schéma que nous allons faire référence. 30 00:02:09,240 --> 00:02:12,490 En fait, j'ai fait ça sur mon iPad. 31 00:02:12,490 --> 00:02:20,720 Donc, je vais alterner les deux sens entre l'iPad et ce code juste pour la référence. 32 00:02:20,720 --> 00:02:26,540 >> Commençons. Tout d'abord, concentrons-nous sur les deux premières lignes de principal ici. 33 00:02:26,540 --> 00:02:30,220 Pour commencer, nous allons initialiser à 1 x et y à 2. 34 00:02:30,220 --> 00:02:33,040 Nous avons donc deux variables entières, ils sont tous les deux à être placé sur la pile. 35 00:02:33,040 --> 00:02:36,050 Nous allons mettre un 1 et un 2 en eux. 36 00:02:36,050 --> 00:02:43,150 Donc, si je retourne pour mon iPad, je l'espère, nous allons voir - 37 00:02:43,150 --> 00:02:48,660 Apple TV en miroir, et voilà. D'accord. 38 00:02:48,660 --> 00:02:51,670 Donc, si je retourne pour mon iPad, 39 00:02:51,670 --> 00:02:56,220 Je tiens à initialiser à 1 x et y à 2. 40 00:02:56,220 --> 00:03:00,580 Nous faisons cela tout simplement en écrivant un 1 dans la case x 41 00:03:00,580 --> 00:03:07,730 et a 2 dans la case y. Assez simple. 42 00:03:07,730 --> 00:03:11,620 Alors maintenant, revenons à l'ordinateur portable, voir ce qui se passe ensuite. 43 00:03:11,620 --> 00:03:15,810 Donc cette ligne suivante est l'endroit où les choses se compliquent. 44 00:03:15,810 --> 00:03:28,110 Nous passons l'adresse de x et de y l'adresse que les paramètres a et b de la fonction de permutation. 45 00:03:28,110 --> 00:03:32,380 L'adresse de x et de y l'adresse sont des choses que nous ne pouvons pas calculer 46 00:03:32,380 --> 00:03:36,360 sans se référer à ces points de balle juste ici. 47 00:03:36,360 --> 00:03:39,750 Et heureusement, les deux premiers points nous dire exactement quelles sont les réponses. 48 00:03:39,750 --> 00:03:44,740 L'adresse dans la mémoire de x est 10, et l'adresse de y dans la mémoire est 14. 49 00:03:44,740 --> 00:03:51,870 Donc, ce sont les valeurs qui se transmises en tant que a et b là-haut dans notre fonction d'échange. 50 00:03:51,870 --> 00:04:00,760 Encore une fois, le passage à notre schéma, je peux écrire un 10 dans une 51 00:04:00,760 --> 00:04:07,400 et un 14 en b. 52 00:04:07,400 --> 00:04:11,610 Maintenant, ce point est l'endroit où nous procédons à l'échange. 53 00:04:11,610 --> 00:04:14,520 Alors renversant en arrière de l'ordinateur portable à nouveau, 54 00:04:14,520 --> 00:04:21,079 nous voyons que la façon dont fonctionne le swap, c'est que je déréférencement d'abord un magasin et le résultat dans tmp. 55 00:04:21,079 --> 00:04:27,650 Ainsi, l'opérateur de déréférencement dit: "Hé. Traiter le contenu de la variable a comme adresse. 56 00:04:27,650 --> 00:04:33,830 Aller à tout ce qui est stocké à cette adresse, et le charger. " 57 00:04:33,830 --> 00:04:41,720 Que vous chargez de la variable qui va être stocké dans notre variable tmp. 58 00:04:41,720 --> 00:04:45,150 Retournement de retour à l'iPad. 59 00:04:45,150 --> 00:04:51,690 Si nous allons à traiter 10, nous savons que l'adresse 10 est le x varible 60 00:04:51,690 --> 00:04:55,480 parce qu'on nous a dit à notre point de balle que l'adresse de x dans la mémoire est de 10. 61 00:04:55,480 --> 00:05:00,180 Ainsi, nous pouvons y aller, obtenir la valeur de celui-ci, qui est de 1, comme on le voit sur notre iPad, 62 00:05:00,180 --> 00:05:06,300 et le recharger dans tmp. 63 00:05:06,300 --> 00:05:08,250 Encore une fois, ce n'est pas le contenu final. 64 00:05:08,250 --> 00:05:14,350 Nous allons marcher à travers et nous allons arriver à notre état final du programme à la fin. 65 00:05:14,350 --> 00:05:17,210 Mais pour le moment, nous avons la valeur 1 stockée dans tmp. 66 00:05:17,210 --> 00:05:19,210 >> Et il ya une petite question à poser ici. 67 00:05:19,210 --> 00:05:23,980 [Alexander] Est l'opérateur de déréférencement - c'est juste le droit étoiles en face de la variable? 68 00:05:23,980 --> 00:05:27,600 Oui >>. Ainsi, l'opérateur de déréférencement, que l'on s'apprête à notre ordinateur portable une fois de plus, 69 00:05:27,600 --> 00:05:33,780 cette étoile est juste en face. 70 00:05:33,780 --> 00:05:37,460 En ce sens, il est - vous l'opposer à l'opérateur de multiplication 71 00:05:37,460 --> 00:05:42,400 ce qui nécessite deux choses: l'opérateur de déréférencement est un opérateur unaire. 72 00:05:42,400 --> 00:05:46,130 Seulement appliqué à une valeur, par opposition à un opérateur binaire, 73 00:05:46,130 --> 00:05:48,810 où vous appliquez à deux valeurs différentes. 74 00:05:48,810 --> 00:05:52,080 Donc, c'est ce qui se passe dans cette ligne. 75 00:05:52,080 --> 00:05:58,390 Nous avons chargé la valeur 1 et stockées dans notre variable entière temporaire. 76 00:05:58,390 --> 00:06:05,800 La ligne suivante, nous stockons le contenu de b en - 77 00:06:05,800 --> 00:06:12,630 ou, plutôt, nous stockons le contenu que b est en pointant vers l'endroit où une pointe. 78 00:06:12,630 --> 00:06:17,690 Si nous analysons ce de droite à gauche, nous allons b déréférencement, 79 00:06:17,690 --> 00:06:23,580 nous allons aborder 14, nous allons prendre l'entier qui est là, 80 00:06:23,580 --> 00:06:26,900 puis nous allons aller à l'adresse 10, 81 00:06:26,900 --> 00:06:34,240 et nous allons jeter le résultat de notre déréférencement de b dans cet espace. 82 00:06:34,240 --> 00:06:40,080 Retournement à notre iPad, où nous pouvons faire cela un peu plus concret, 83 00:06:40,080 --> 00:06:44,070 cela pourrait aider si je écrire les nombres sur toutes les adresses ici. 84 00:06:44,070 --> 00:06:53,820 Donc, nous savons qu'à y, nous sommes à l'adresse 14, x est à l'adresse 10. 85 00:06:53,820 --> 00:07:00,180 Quand nous commençons à b, nous déréférencer b, nous allons récupérer la valeur 2. 86 00:07:00,180 --> 00:07:08,320 Nous allons saisir cette valeur parce que c'est la valeur qui vit à l'adresse 14. 87 00:07:08,320 --> 00:07:15,700 Et nous allons le mettre dans la variable qui vit à l'adresse 10, 88 00:07:15,700 --> 00:07:19,160 qui est là, ce qui correspond à nos variable x. 89 00:07:19,160 --> 00:07:21,810 Ainsi, nous pouvons faire un peu d'écraser ici 90 00:07:21,810 --> 00:07:35,380 où nous nous débarrassons de nos 1 et à la place nous écrire un 2. 91 00:07:35,380 --> 00:07:39,560 Donc, tout va très bien dans le monde, même si nous avons x écrasés maintenant. 92 00:07:39,560 --> 00:07:44,890 Nous avons stocké ancienne valeur x dans notre variable tmp. 93 00:07:44,890 --> 00:07:50,210 Ainsi, nous pouvons terminer le swap avec la ligne suivante. 94 00:07:50,210 --> 00:07:53,030 Retournement à notre ordinateur portable. 95 00:07:53,030 --> 00:07:58,150 Maintenant tout ce qui reste est de prendre le contenu de notre variable entière temporaire 96 00:07:58,150 --> 00:08:05,630 et de les stocker dans la variable qui vit à l'adresse que b est retenue. 97 00:08:05,630 --> 00:08:10,230 Donc, nous allons b déréférencement efficace pour accéder à la variable 98 00:08:10,230 --> 00:08:14,340 qui est à l'adresse que b possède en elle, 99 00:08:14,340 --> 00:08:19,190 et nous allons farcir la valeur tmp tient en elle. 100 00:08:19,190 --> 00:08:23,280 Retournement de retour à l'iPad une fois de plus. 101 00:08:23,280 --> 00:08:31,290 Je peux effacer cette valeur ici, 2, 102 00:08:31,290 --> 00:08:41,010 et à la place nous allons copier le droit 1 dans celui-ci. 103 00:08:41,010 --> 00:08:43,059 Puis la ligne suivante qui exécute, bien sûr - 104 00:08:43,059 --> 00:08:47,150 si nous retournons en arrière de l'ordinateur portable - est-ce 6 points, 105 00:08:47,150 --> 00:08:52,500 qui est le point à partir duquel nous voulions avoir notre schéma complètement rempli. 106 00:08:52,500 --> 00:08:58,940 Alors renversant en arrière de l'iPad une fois de plus, pour que vous puissiez voir le schéma terminé, 107 00:08:58,940 --> 00:09:06,610 vous pouvez voir que nous avons un 10 dans un, un 14 en b, un 1 dans tmp, un 2 en x, et 1 en y. 108 00:09:06,610 --> 00:09:11,000 Y at-il des questions à ce sujet? 109 00:09:11,000 --> 00:09:14,640 Est-ce plus logique, après avoir marché à travers elle? 110 00:09:14,640 --> 00:09:24,850 Moins de sens? J'espère que non. D'accord. 111 00:09:24,850 --> 00:09:28,230 >> Les pointeurs sont un sujet très délicat. 112 00:09:28,230 --> 00:09:33,420 Un des gars avec qui nous travaillons a un dicton très répandu: 113 00:09:33,420 --> 00:09:36,590 «Pour comprendre les pointeurs, vous devez d'abord comprendre les pointeurs." 114 00:09:36,590 --> 00:09:40,530 Je pense que c'est tout à fait vrai. Cela prend un certain temps pour s'habituer à elle. 115 00:09:40,530 --> 00:09:45,360 Tirage au sort des photos, tirage au sort des schémas de mémoire comme celui-ci sont très utiles, 116 00:09:45,360 --> 00:09:49,480 et après vous guidera à travers par exemple après exemple après exemple, 117 00:09:49,480 --> 00:09:54,450 il va commencer à donner un sens un peu plus et le sentiment un peu plus et un peu plus de sens. 118 00:09:54,450 --> 00:10:01,560 Enfin, un jour, vous aurez tout complètement maîtrisé. 119 00:10:01,560 --> 00:10:13,800 Vous avez des questions avant de passer au problème suivant? Très bien. 120 00:10:13,800 --> 00:10:18,840 Alors retournez à l'ordinateur portatif. 121 00:10:18,840 --> 00:10:23,300 Le problème suivant est de 33, nous avons le problème numéro un dans le dossier I / O. 122 00:10:23,300 --> 00:10:26,350 Zoom sur cela un peu petite. 123 00:10:26,350 --> 00:10:28,710 Problème 33 - Oui? 124 00:10:28,710 --> 00:10:32,110 >> [Daniel] Je viens d'avoir une petite question. Cette étoile, ou l'astérisque, 125 00:10:32,110 --> 00:10:35,590 ça s'appelle le déréférencement lorsque vous utilisez un astérisque avant. 126 00:10:35,590 --> 00:10:38,820 Comment ça s'appelle lorsque vous utilisez l'esperluette avant? 127 00:10:38,820 --> 00:10:43,140 L'esperluette est >> avant l'adresse de l'opérateur. 128 00:10:43,140 --> 00:10:45,880 Donc, nous allons faire défiler vers le haut. 129 00:10:45,880 --> 00:10:49,310 Oops. Je suis en mode zoom donc je ne peux pas vraiment défilement. 130 00:10:49,310 --> 00:10:52,780 Si nous regardons ce code très rapidement ici, 131 00:10:52,780 --> 00:10:54,980 à nouveau, la même chose se passe. 132 00:10:54,980 --> 00:10:59,180 Si nous regardons ce code ici, sur cette ligne où nous faisons l'appel à échanger, 133 00:10:59,180 --> 00:11:10,460 l'esperluette est juste en disant "obtenir l'adresse à laquelle vit la variable x." 134 00:11:10,460 --> 00:11:14,460 Lorsque votre compilateur compile votre code, 135 00:11:14,460 --> 00:11:20,590 il doit marquer physiquement une place en mémoire pour toutes vos variables à vivre. 136 00:11:20,590 --> 00:11:24,910 Et qu'est-ce que le compilateur peut alors faire une fois qu'il est compilé tout, 137 00:11:24,910 --> 00:11:31,110 il sait: "Oh, je mets x à l'adresse 10. J'ai mis y à l'adresse 14." 138 00:11:31,110 --> 00:11:34,640 Il peut ensuite remplir ces valeurs pour vous. 139 00:11:34,640 --> 00:11:44,740 Ainsi, vous pouvez alors - il peut alors passer cette séquence et en y passe et en tant que bien. 140 00:11:44,740 --> 00:11:50,730 Ces gars-là obtenir l'adresse, mais aussi, quand vous les croisez dans la fonction de permutation, 141 00:11:50,730 --> 00:11:55,690 ce type d'information, cette int * ici, indique au compilateur, 142 00:11:55,690 --> 00:12:01,350 «D'accord, nous allons interpréter cette adresse comme adresse d'une variable entière." 143 00:12:01,350 --> 00:12:05,900 Comme une adresse d'un int, qui est différente de l'adresse d'une variable de caractère 144 00:12:05,900 --> 00:12:09,930 parce qu'un int occupe, sur une machine 32-bit, occupe 4 octets d'espace, 145 00:12:09,930 --> 00:12:13,310 alors qu'un personnage prend seulement 1 octet de l'espace. 146 00:12:13,310 --> 00:12:17,310 Il est donc important de savoir aussi ce qui est - ce qui vit, ce type de valeur 147 00:12:17,310 --> 00:12:20,340 vit à l'adresse que s'est passé po 148 00:12:20,340 --> 00:12:22,020 Ou à l'adresse que vous avez à faire. 149 00:12:22,020 --> 00:12:29,020 De cette façon, vous savez combien d'octets d'informations à charger réellement de votre RAM. 150 00:12:29,020 --> 00:12:31,780 Et puis, oui, opérateur de déréférencement, comme vous me demandiez, 151 00:12:31,780 --> 00:12:37,200 va et accède à des informations à une adresse donnée. 152 00:12:37,200 --> 00:12:42,820 Donc, dit-il, avec cette variable a ici, de traiter le contenu d'un comme une adresse, 153 00:12:42,820 --> 00:12:47,880 aller à cette adresse, et tirez, chargez-le dans le processeur, la charge dans un registre 154 00:12:47,880 --> 00:12:56,340 les valeurs réelles ou les contenus qui vivent à cette adresse. 155 00:12:56,340 --> 00:12:59,620 D'autres questions? Ce sont de bonnes questions. 156 00:12:59,620 --> 00:13:01,650 C'est beaucoup trop d'une nouvelle terminologie. 157 00:13:01,650 --> 00:13:09,800 C'est aussi un peu funky, voir & * et dans des lieux différents. 158 00:13:09,800 --> 00:13:13,180 >> Très bien. 159 00:13:13,180 --> 00:13:18,530 Mais revenons au problème 33, déposer I / O. 160 00:13:18,530 --> 00:13:22,540 Ce fut l'un de ces problèmes que je pense d'un certain nombre de choses qui s'est passé. 161 00:13:22,540 --> 00:13:25,400 Premièrement, il s'agit d'un sujet assez nouveau. 162 00:13:25,400 --> 00:13:30,590 Il a été présenté très bientôt avant le test, 163 00:13:30,590 --> 00:13:33,400 et puis je pense que c'était un peu comme un de ces problèmes de mots en mathématiques 164 00:13:33,400 --> 00:13:39,720 où ils vous donnent beaucoup d'informations, mais vous avez réellement ne finissent pas avoir à utiliser une tonne de celui-ci. 165 00:13:39,720 --> 00:13:44,060 La première partie de ce problème est de décrire ce qu'est un fichier CSV est. 166 00:13:44,060 --> 00:13:50,620 Maintenant, un fichier CSV, selon la description, est un fichier de valeurs séparées par des virgules. 167 00:13:50,620 --> 00:13:55,300 La raison pour laquelle celles-ci sont toutes intéressantes, et la raison pour laquelle vous jamais les utiliser, 168 00:13:55,300 --> 00:14:00,800 est, parce que, combien d'entre vous ont déjà utilisé des trucs comme Excel? 169 00:14:00,800 --> 00:14:03,240 Figure plupart d'entre vous ont, sans doute, ou utiliseront à un certain moment dans votre vie. 170 00:14:03,240 --> 00:14:06,430 Vous allez utiliser quelque chose comme Excel. 171 00:14:06,430 --> 00:14:10,940 Afin d'obtenir les données d'une feuille de calcul Excel ou de faire toute sorte de traitement avec elle, 172 00:14:10,940 --> 00:14:17,240 si vous voulez écrire un programme C ou programme Python, programme Java, 173 00:14:17,240 --> 00:14:20,070 pour traiter les données que vous avez stockées dedans, 174 00:14:20,070 --> 00:14:23,170 l'une des façons les plus courantes pour le sortir est dans un fichier CSV. 175 00:14:23,170 --> 00:14:26,850 Et vous pouvez ouvrir Excel et quand vous allez à la «Enregistrer sous» le dialogue, 176 00:14:26,850 --> 00:14:32,840 vous pouvez sortir un fichier CSV réelle. 177 00:14:32,840 --> 00:14:35,890 >> Bon à savoir comment faire face à ces choses. 178 00:14:35,890 --> 00:14:42,010 La façon dont cela fonctionne est que c'est similaire à - je veux dire, c'est essentiellement imitant une feuille de calcul, 179 00:14:42,010 --> 00:14:47,590 où, comme nous le voyons ici, dans la pièce très extrême gauche, 180 00:14:47,590 --> 00:14:49,910 nous avons tous les noms de famille. 181 00:14:49,910 --> 00:14:54,670 Nous avons donc Malan, puis Hardison, puis Bowden, MacWilliam, puis Chan. 182 00:14:54,670 --> 00:14:59,470 Tous les noms de famille. Et puis, une virgule sépare les noms de famille des prénoms. 183 00:14:59,470 --> 00:15:02,970 David, Nate, Rob, Tommy, et Zamyla. 184 00:15:02,970 --> 00:15:06,850 J'ai toujours mélanger Robby et Tom. 185 00:15:06,850 --> 00:15:10,940 Et puis, enfin, la troisième colonne est l'adresse e-mail. 186 00:15:10,940 --> 00:15:18,500 Une fois que vous comprenez cela, le reste du programme est assez simple à mettre en œuvre. 187 00:15:18,500 --> 00:15:23,850 Ce que nous avons fait dans le but d'imiter cette structure même de notre programme C 188 00:15:23,850 --> 00:15:27,510 est que nous avons utilisé une structure. 189 00:15:27,510 --> 00:15:30,520 Nous allons commencer à jouer avec ceux-ci un peu plus aussi. 190 00:15:30,520 --> 00:15:35,790 Nous les avons vus pour le premier bit peu en 3 set problème, lorsque nous traitions avec les dictionnaires. 191 00:15:35,790 --> 00:15:40,290 Mais cette structure du personnel enregistre un nom de famille, un prénom et un email. 192 00:15:40,290 --> 00:15:44,500 Tout comme notre fichier CSV a été de le ranger. 193 00:15:44,500 --> 00:15:47,950 Donc, ce n'est que de la conversion d'un format à un autre. 194 00:15:47,950 --> 00:15:54,630 Nous devons convertir, dans ce cas, une structure du personnel dans une ligne, 195 00:15:54,630 --> 00:15:59,060 une ligne séparée par des virgules, juste comme ça. 196 00:15:59,060 --> 00:16:01,500 Est-ce logique? Vous avez tous répondu à ce questionnaire, 197 00:16:01,500 --> 00:16:07,680 donc j'imagine que vous avez au moins eu le temps de réfléchir à ce sujet. 198 00:16:07,680 --> 00:16:16,410 >> Dans la fonction de location, le problème nous demande de prendre en - Zoom sur cette we'll peu un peu - 199 00:16:16,410 --> 00:16:22,480 prendre dans une structure de personnel, une structure du personnel, avec le nom de s, 200 00:16:22,480 --> 00:16:30,900 et ajouter son contenu à notre fichier staff.csv. 201 00:16:30,900 --> 00:16:34,230 Il s'avère que c'est assez simple à utiliser. 202 00:16:34,230 --> 00:16:37,430 Nous allons sorte de jouer avec ces fonctions un peu plus aujourd'hui. 203 00:16:37,430 --> 00:16:44,510 Mais dans ce cas, la fonction fprintf est vraiment la clé. 204 00:16:44,510 --> 00:16:51,960 Donc, avec fprintf, nous pouvons imprimer, tout comme vous les gars ont eu recours à ce terme printf ensemble. 205 00:16:51,960 --> 00:16:55,050 Vous pouvez printf une ligne dans un fichier. 206 00:16:55,050 --> 00:16:59,030 Ainsi, au lieu de se contenter de l'appel d'habitude printf où vous lui donnez la chaîne de format 207 00:16:59,030 --> 00:17:05,380 et puis vous remplacez toutes les variables avec les arguments suivants, 208 00:17:05,380 --> 00:17:11,290 avec fprintf, votre argument premier est plutôt le fichier que vous souhaitez écrire. 209 00:17:11,290 --> 00:17:21,170 Si nous devions examiner cette question dans l'appareil, par exemple, l'homme fprintf, 210 00:17:21,170 --> 00:17:25,980 nous pouvons voir la différence entre printf et fprintf. 211 00:17:25,980 --> 00:17:28,960 Je vais faire un zoom avant ici un peu. 212 00:17:28,960 --> 00:17:33,140 Donc, avec printf, nous lui donnons une chaîne de format, puis les arguments suivants 213 00:17:33,140 --> 00:17:37,580 sont toutes les variables de remplacement ou de substitution dans notre chaîne de format. 214 00:17:37,580 --> 00:17:47,310 Alors qu'avec fprintf, le premier argument est en effet ce fichier * appelé un ruisseau. 215 00:17:47,310 --> 00:17:51,800 >> De retour ici à notre location, 216 00:17:51,800 --> 00:17:54,550 nous avons déjà eu notre flux * fichier ouvert pour nous. 217 00:17:54,550 --> 00:17:57,810 C'est ce que cette première ligne fait, il ouvre le fichier staff.csv, 218 00:17:57,810 --> 00:18:01,690 il l'ouvre en mode ajout, et tout ce qui nous reste à faire est 219 00:18:01,690 --> 00:18:08,640 écrire la structure du personnel dans le fichier. 220 00:18:08,640 --> 00:18:10,870 Et, voyons, ce que je veux utiliser l'iPad? 221 00:18:10,870 --> 00:18:17,900 Je vais utiliser l'iPad. Nous avons void - Mettons cela sur la table pour que je puisse écrire un peu mieux - 222 00:18:17,900 --> 00:18:33,680 annuler la location et la prend dans un argument, une structure du personnel appelé s. 223 00:18:33,680 --> 00:18:44,120 Vous avez nos accolades, nous avons notre fichier appelé fichier *, 224 00:18:44,120 --> 00:18:48,380 nous avons notre ligne fopen qui nous est donnée, 225 00:18:48,380 --> 00:18:51,890 et je vais l'écrire sous forme de points, car il est déjà dans le pedia. 226 00:18:51,890 --> 00:19:00,530 Et puis, sur notre ligne suivante, nous allons faire un appel à fprintf 227 00:19:00,530 --> 00:19:03,700 et nous allons passer dans le fichier que l'on veut imprimer, 228 00:19:03,700 --> 00:19:10,290 et puis notre chaîne de format, ce qui - 229 00:19:10,290 --> 00:19:14,300 Je vais vous laisser me dire à quoi il ressemble. 230 00:19:14,300 --> 00:19:20,500 Que diriez-vous, Stella? Savez-vous ce que la première partie de la chaîne de format ressemble? 231 00:19:20,500 --> 00:19:24,270 [Stella] Je ne suis pas sûr. >> N'hésitez pas à demander Jimmy. 232 00:19:24,270 --> 00:19:27,690 Savez-vous, Jimmy? 233 00:19:27,690 --> 00:19:31,000 [Jimmy] Serait-il juste être le dernier? Je ne sais pas. Je ne suis pas entièrement sûr de. 234 00:19:31,000 --> 00:19:39,020 Ok >>. Que diriez-vous, quelqu'un at-il obtenir ce bon à l'examen? 235 00:19:39,020 --> 00:19:41,770 Non bien. 236 00:19:41,770 --> 00:19:47,920 Il s'avère que ici tout ce que nous avons à faire, c'est que nous voulons que chaque partie de la structure du personnel 237 00:19:47,920 --> 00:19:53,290 être imprimés sous forme de chaîne de caractères dans notre fichier. 238 00:19:53,290 --> 00:19:59,900 Nous venons d'utiliser le caractère substitution de chaîne à trois reprises différentes parce que nous avons un nom de famille 239 00:19:59,900 --> 00:20:07,160 suivi par une virgule, puis un prénom suivi d'une virgule, 240 00:20:07,160 --> 00:20:12,430 et enfin l'adresse email qui est suivi - ce qui n'est pas 241 00:20:12,430 --> 00:20:15,140 montage sur mon écran - mais il est suivi par un caractère de nouvelle ligne. 242 00:20:15,140 --> 00:20:20,060 Donc, je vais l'écrire tout là-bas. 243 00:20:20,060 --> 00:20:23,560 Et puis, à la suite de notre chaîne de format, 244 00:20:23,560 --> 00:20:27,880 nous devons juste les substitutions, qui nous accédons à l'aide de la notation par points 245 00:20:27,880 --> 00:20:31,370 que nous avons vu en 3 set problème. 246 00:20:31,370 --> 00:20:48,820 Nous pouvons utiliser s.last, s.first et s.email 247 00:20:48,820 --> 00:20:58,990 de substituer à ces trois valeurs dans notre chaîne de format. 248 00:20:58,990 --> 00:21:06,190 Alors, comment ça s'est passé? Donner un sens? 249 00:21:06,190 --> 00:21:09,700 Oui? Non? Peut-être? D'accord. 250 00:21:09,700 --> 00:21:14,180 >> La dernière chose que nous faisons lorsque nous avons imprimé et après nous avons ouvert notre dossier: 251 00:21:14,180 --> 00:21:17,370 chaque fois que nous avons ouvert un dossier, il faut toujours se rappeler pour la refermer. 252 00:21:17,370 --> 00:21:19,430 Parce que sinon nous finirons par une fuite de la mémoire, 253 00:21:19,430 --> 00:21:22,500 à l'aide des descripteurs de fichiers. 254 00:21:22,500 --> 00:21:25,950 Donc, pour fermer, ce qui est la fonction que nous utilisons? Daniel? 255 00:21:25,950 --> 00:21:30,120 [Daniel] fclose? Fclose >>, exactement. 256 00:21:30,120 --> 00:21:37,520 Ainsi, la dernière partie de ce problème consistait à fermer correctement le fichier, utilisez la fonction fclose, 257 00:21:37,520 --> 00:21:40,370 qui ressemble à cela. 258 00:21:40,370 --> 00:21:43,880 Pas trop fou. 259 00:21:43,880 --> 00:21:46,990 Cool. 260 00:21:46,990 --> 00:21:49,520 Donc, c'est le problème 33 du quiz. 261 00:21:49,520 --> 00:21:52,480 Nous aurons certainement plus de fichiers I / O à venir. 262 00:21:52,480 --> 00:21:55,130 Nous allons faire un peu plus dans la conférence d'aujourd'hui, ou à l'article d'aujourd'hui, 263 00:21:55,130 --> 00:22:01,710 parce que c'est ce qui va se former l'essentiel de cette pset à venir. 264 00:22:01,710 --> 00:22:05,020 Passons à partir du questionnaire à ce stade. Oui? 265 00:22:05,020 --> 00:22:10,880 >> [Charlotte]] Pourquoi fclose (fichier) à la place de fclose (staff.csv)? 266 00:22:10,880 --> 00:22:19,100 Ah >>. Parce qu'il se trouve que - si la question, ce qui est un grand, 267 00:22:19,100 --> 00:22:27,800 C'est pourquoi, lorsque nous écrivons fclose, nous écrit variables fclose astérisque (fichier) 268 00:22:27,800 --> 00:22:33,680 plutôt que le nom du fichier, staff.csv? Est-ce exact? Ouais. 269 00:22:33,680 --> 00:22:39,570 Donc, nous allons jeter un coup d'oeil. Si je reviens à mon ordinateur portable, 270 00:22:39,570 --> 00:22:45,040 et regardons la fonction fclose. 271 00:22:45,040 --> 00:22:51,460 Ainsi, la fonction fclose ferme un ruisseau et qu'il prend dans le pointeur sur le flux que nous voulons combler, 272 00:22:51,460 --> 00:22:57,010 plutôt que le nom du fichier que l'on veut fermer. 273 00:22:57,010 --> 00:23:01,620 Et c'est parce que dans les coulisses, lorsque vous effectuez un appel à fopen, 274 00:23:01,620 --> 00:23:12,020 lorsque vous ouvrez un fichier, vous êtes en train de l'allocation de mémoire pour stocker des informations sur le fichier. 275 00:23:12,020 --> 00:23:16,380 Donc, vous avez pointeur de fichier qui contient des informations sur le fichier, 276 00:23:16,380 --> 00:23:23,080 comme il est ouvert, sa taille, où vous êtes actuellement dans le fichier, 277 00:23:23,080 --> 00:23:29,100 de sorte que vous pouvez faire la lecture et l'écriture des appels à cet endroit particulier dans le fichier. 278 00:23:29,100 --> 00:23:38,060 On finit par fermer le pointeur au lieu de fermer le nom du fichier. 279 00:23:38,060 --> 00:23:48,990 >> Oui? [Daniel] Ainsi, afin d'utiliser de location, diriez-vous - comment ça se l'entrée utilisateur? 280 00:23:48,990 --> 00:23:53,830 Est-ce que fprintf agir comme GetString dans le sens où elle va attendre pour l'entrée de l'utilisateur 281 00:23:53,830 --> 00:23:57,180 et je vous demande de taper ce - ou attendre que vous tapiez ces trois choses? 282 00:23:57,180 --> 00:24:00,480 Ou avez-vous besoin d'utiliser quelque chose pour mettre en œuvre la location? 283 00:24:00,480 --> 00:24:04,100 Ouais >>. Donc, nous ne sommes pas - la question a été, comment pouvons-nous obtenir l'entrée utilisateur 284 00:24:04,100 --> 00:24:09,220 pour mettre en œuvre la location? Et ce que nous avons ici est l'interlocuteur de la location, 285 00:24:09,220 --> 00:24:17,690 passer dans cette structure personnel avec toutes les données stockées dans la structure déjà. 286 00:24:17,690 --> 00:24:22,990 Il en est de fprintf en mesure de simplement écrire les données directement dans le fichier. 287 00:24:22,990 --> 00:24:25,690 Il n'y a pas d'attente pour l'entrée utilisateur. 288 00:24:25,690 --> 00:24:32,110 L'utilisateur a déjà donné l'entrée en bien de le mettre dans cette structure du personnel. 289 00:24:32,110 --> 00:24:36,510 Et les choses, bien sûr, se briserait si l'un de ces pointeurs sont nulles, 290 00:24:36,510 --> 00:24:40,370 donc nous revenir en arrière ici et nous regardons notre structure. 291 00:24:40,370 --> 00:24:43,640 Nous avons la dernière chaîne, première chaîne, chaîne courriel. 292 00:24:43,640 --> 00:24:48,530 Nous savons maintenant que tous ceux qui vraiment, sous le capot, sont variables char *. 293 00:24:48,530 --> 00:24:53,470 Qui peuvent ou peuvent ne pas être pointant sur NULL. 294 00:24:53,470 --> 00:24:55,800 Ils peuvent être pointant vers la mémoire sur le tas, 295 00:24:55,800 --> 00:24:59,650 peut-être la mémoire sur la pile. 296 00:24:59,650 --> 00:25:04,580 Nous ne savons pas vraiment, mais si l'un de ces pointeurs sont nuls ou invalides, 297 00:25:04,580 --> 00:25:08,120 que cela va certainement planter notre fonction de la location. 298 00:25:08,120 --> 00:25:11,050 C'était quelque chose qui était un peu au-delà de la portée de l'examen. 299 00:25:11,050 --> 00:25:16,440 Nous ne sommes pas s'inquiéter à ce sujet. 300 00:25:16,440 --> 00:25:22,170 Grande. D'accord. Ainsi, le déplacement à partir du quiz. 301 00:25:22,170 --> 00:25:25,760 >> Fermons ce gars-là, et nous allons nous pencher sur pset 4. 302 00:25:25,760 --> 00:25:34,700 Donc, si vous les gars regardez la spécification pset, une fois que vous pouvez y accéder, cs50.net/quizzes, 303 00:25:34,700 --> 00:25:42,730 nous allons passer par quelques-uns des problèmes actuels section. 304 00:25:42,730 --> 00:25:52,240 Je suis défilement vers le bas - section de questions débute à la troisième page de la spécification pset. 305 00:25:52,240 --> 00:25:57,800 Et la première partie vous demande d'aller voir le court et sur la réorientation des tuyaux. 306 00:25:57,800 --> 00:26:02,820 Qui était une sorte de court cool, vous montre quelques nouvelles fraîches, des tours de ligne de commande que vous pouvez utiliser. 307 00:26:02,820 --> 00:26:06,050 Et puis nous avons quelques questions pour vous aussi. 308 00:26:06,050 --> 00:26:10,860 Cette première question sur les flux, à laquelle printf écrit par défaut, 309 00:26:10,860 --> 00:26:15,920 nous avons un peu parlé un peu tout à l'heure. 310 00:26:15,920 --> 00:26:22,380 Cette fprintf que nous venons de discuter prend dans un flux de fichier * comme argument. 311 00:26:22,380 --> 00:26:26,580 fclose prend dans un flux de fichier * ainsi, 312 00:26:26,580 --> 00:26:32,660 et la valeur de retour de la fonction fopen vous donne un flux de fichier * ainsi. 313 00:26:32,660 --> 00:26:36,060 La raison pour laquelle nous n'avons pas vu ceux d'avant, lorsque nous avons traité avec printf 314 00:26:36,060 --> 00:26:39,450 C'est parce que printf est un flux par défaut. 315 00:26:39,450 --> 00:26:41,810 Et le flux par défaut à laquelle il écrit 316 00:26:41,810 --> 00:26:45,190 vous renseigner sur la courte. 317 00:26:45,190 --> 00:26:50,080 Il faut absolument jeter un oeil à celui-ci. 318 00:26:50,080 --> 00:26:53,010 >> Dans la section d'aujourd'hui, nous allons parler un peu de GDB, 319 00:26:53,010 --> 00:26:57,720 car plus vous êtes familier avec elle, le plus pratique, vous obtenez avec elle, 320 00:26:57,720 --> 00:27:01,390 le mieux vous serez réellement chasser les bugs dans votre propre code. 321 00:27:01,390 --> 00:27:05,540 Cela accélère le processus de débogage énormément augmenté. 322 00:27:05,540 --> 00:27:09,230 Ainsi, en utilisant printf, chaque fois que vous faites cela, vous devez recompiler votre code, 323 00:27:09,230 --> 00:27:13,000 vous devez l'exécuter à nouveau, il faut parfois se déplacer autour de l'appel printf, 324 00:27:13,000 --> 00:27:17,100 commenter le code, il faut du temps. 325 00:27:17,100 --> 00:27:20,850 Notre objectif est d'essayer de vous convaincre que avec GDB, vous pouvez essentiellement 326 00:27:20,850 --> 00:27:26,810 printf quoi que ce soit à n'importe quel point dans votre code et vous n'aurez jamais à le recompiler. 327 00:27:26,810 --> 00:27:35,120 Vous n'avez jamais à démarrer et maintenir deviner où printf suivante. 328 00:27:35,120 --> 00:27:40,910 La première chose à faire est de copier cette ligne et obtenir le code de section hors de la bande. 329 00:27:40,910 --> 00:27:47,530 Je copie cette ligne de code qui dit: «http://cdn.cs50.net wget". 330 00:27:47,530 --> 00:27:49,510 Je vais le copier. 331 00:27:49,510 --> 00:27:55,950 Je vais aller à mon appareil, un zoom arrière afin que vous puissiez voir ce que je fais, 332 00:27:55,950 --> 00:28:01,890 de le coller là-dedans, et quand je la touche Entrée, cette commande wget est littéralement une toile obtenir. 333 00:28:01,890 --> 00:28:06,210 Il va tirer vers le bas de ce fichier à partir d'Internet, 334 00:28:06,210 --> 00:28:11,790 et il va l'enregistrer dans le répertoire courant. 335 00:28:11,790 --> 00:28:21,630 Maintenant, si je inscrire mon répertoire courant, vous pouvez voir que j'ai ce fichier section5.zip juste là. 336 00:28:21,630 --> 00:28:25,260 La façon de traiter ce type est de le décompresser, 337 00:28:25,260 --> 00:28:27,650 que vous pouvez faire en ligne de commande, juste comme ça. 338 00:28:27,650 --> 00:28:31,880 Section5.zip. 339 00:28:31,880 --> 00:28:36,980 Ça décompressez-le, créez le dossier pour moi, 340 00:28:36,980 --> 00:28:40,410 gonfler la totalité du contenu, de les mettre là-dedans. 341 00:28:40,410 --> 00:28:47,410 Alors maintenant, je peux aller dans mon article 5 du répertoire en utilisant la commande cd. 342 00:28:47,410 --> 00:28:58,310 Effacer l'écran en utilisant clair. Donc effacer l'écran. 343 00:28:58,310 --> 00:29:02,280 Maintenant, j'ai un bon terminal propre à traiter. 344 00:29:02,280 --> 00:29:06,200 >> Maintenant, si je liste tous les fichiers que je vois dans ce répertoire, 345 00:29:06,200 --> 00:29:12,270 vous voyez que j'ai quatre fichiers: buggy1, buggy2, buggy3 et buggy4. 346 00:29:12,270 --> 00:29:16,180 J'ai aussi leurs correspondants. Fichiers c. 347 00:29:16,180 --> 00:29:20,400 Nous n'allons pas regarder les fichiers c. Pour l'instant. 348 00:29:20,400 --> 00:29:24,140 Au lieu de cela, nous allons les utiliser quand nous ouvrons GDB. 349 00:29:24,140 --> 00:29:28,220 Nous les avons maintenus autour de sorte que nous avons accès au code source réelle lorsque nous utilisons GDB, 350 00:29:28,220 --> 00:29:32,740 mais le but de cette partie de la section est de bricoler avec GDB 351 00:29:32,740 --> 00:29:40,370 et voir comment nous pouvons l'utiliser pour comprendre ce qui ne va pas avec chacune de ces quatre programmes en buggy. 352 00:29:40,370 --> 00:29:43,380 Donc, nous allons juste autour de la salle très rapidement, 353 00:29:43,380 --> 00:29:47,000 et je vais demander à quelqu'un d'exécuter un des programmes buggy, 354 00:29:47,000 --> 00:29:54,730 et ensuite nous passerons en tant que groupe par le biais de GDB, et nous verrons ce que nous pouvons faire pour corriger ces programmes, 355 00:29:54,730 --> 00:29:58,460 ou au moins d'identifier ce qui va mal dans chacun d'eux. 356 00:29:58,460 --> 00:30:04,760 Commençons ici avec Daniel. Est-ce que vous exécutez buggy1? Voyons voir ce qui se passe. 357 00:30:04,760 --> 00:30:09,470 [Daniel] Il dit qu'il ya une erreur d'application. Ouais >>. Exactement. 358 00:30:09,470 --> 00:30:12,460 Donc, si je lance buggy1, j'obtiens une erreur seg. 359 00:30:12,460 --> 00:30:16,210 À ce stade, je pourrais continuer et ouvrir buggy1.c, 360 00:30:16,210 --> 00:30:19,450 essayer de comprendre ce qui va mal, 361 00:30:19,450 --> 00:30:22,000 mais l'une des choses les plus désagréables au sujet de cette erreur de défaillance de segments 362 00:30:22,000 --> 00:30:27,610 c'est qu'il ne vous dit pas sur quelle ligne de ce programme fait a mal tourné et s'est cassé. 363 00:30:27,610 --> 00:30:29,880 Vous devez sorte de regarder le code 364 00:30:29,880 --> 00:30:33,990 et de déterminer à l'aide deviner et vérifier ou printf pour voir ce qui ne va pas. 365 00:30:33,990 --> 00:30:37,840 L'une des choses les plus cool à propos de GDB, c'est qu'il est vraiment, vraiment facile 366 00:30:37,840 --> 00:30:42,170 de comprendre la ligne à laquelle votre programme plante. 367 00:30:42,170 --> 00:30:46,160 Il est tout à fait vaut la peine de l'utiliser, même si c'est juste pour ça. 368 00:30:46,160 --> 00:30:56,190 Donc, pour démarrer GDB, je tape GDB, puis je lui donne le chemin vers l'exécutable que je veux courir. 369 00:30:56,190 --> 00:31:01,960 Ici, je vais taper gdb ./buggy1. 370 00:31:01,960 --> 00:31:06,600 Appuyez sur Entrée. Donne-moi toutes ces informations le droit d'auteur, 371 00:31:06,600 --> 00:31:13,000 et ici vous verrez cette ligne qui dit: «symboles de lecture de / home / 372 00:31:13,000 --> 00:31:17,680 jharvard/section5/buggy1. " 373 00:31:17,680 --> 00:31:22,060 Et si tout se passe bien, vous verrez qu'il affichera un message qui ressemble à ceci. 374 00:31:22,060 --> 00:31:25,500 Il va lire les symboles, il dira: «Je suis la lecture de symboles de votre fichier exécutable," 375 00:31:25,500 --> 00:31:29,900 et alors il aura ce message «done» ici. 376 00:31:29,900 --> 00:31:35,410 Si vous voyez une autre variante de ce, ou voyez-vous il n'a pas pu trouver les symboles 377 00:31:35,410 --> 00:31:41,460 ou quelque chose comme ça, qu'est-ce que cela signifie, c'est que vous n'avez tout simplement pas compilé votre exécutable correctement. 378 00:31:41,460 --> 00:31:49,980 Quand nous compiler des programmes pour une utilisation avec GDB, nous devons utiliser ce drapeau spéciale-g, 379 00:31:49,980 --> 00:31:54,540 et qui est fait par défaut si vous compilez vos programmes, simplement en tapant la commande make 380 00:31:54,540 --> 00:31:59,320 ou faire buggy ou faire récupérer, l'un de ceux. 381 00:31:59,320 --> 00:32:07,800 Mais si vous compilez manuellement avec Clang, alors vous aurez à aller à l'intérieur et inclure cette option-g. 382 00:32:07,800 --> 00:32:10,310 >> À ce stade, maintenant que nous avons notre prompt de GDB, 383 00:32:10,310 --> 00:32:12,310 il est assez simple pour exécuter le programme. 384 00:32:12,310 --> 00:32:19,740 On peut soit saisir run, ou nous pouvons simplement taper r. 385 00:32:19,740 --> 00:32:22,820 La plupart des commandes GDB peut être abrégée. 386 00:32:22,820 --> 00:32:25,940 Habituellement, pour seulement un ou quelques lettres d'un couple, ce qui est assez agréable. 387 00:32:25,940 --> 00:32:30,980 Alors Saad, si vous tapez r et appuyez sur Entrée, ce qui se passe? 388 00:32:30,980 --> 00:32:39,390 [Saad] J'ai eu SIGSEGV, faute de segmentation, et puis tout ce charabia. 389 00:32:39,390 --> 00:32:43,650 Ouais >>. 390 00:32:43,650 --> 00:32:47,990 Comme nous voyons sur l'écran en ce moment, et comme Saad dit: 391 00:32:47,990 --> 00:32:53,430 quand on tape RUN ou R et appuyez sur Entrée, on obtient encore la faute seg même. 392 00:32:53,430 --> 00:32:55,830 Donc, en utilisant GDB ne résout pas notre problème. 393 00:32:55,830 --> 00:32:59,120 Mais il nous donne une certaine langue de bois, et il s'avère que ce charabia 394 00:32:59,120 --> 00:33:03,080 nous dit en fait que ça se passe. 395 00:33:03,080 --> 00:33:10,680 Pour analyser ce bit un peu, ce premier bit est la fonction dans laquelle tout ce qui ne va pas. 396 00:33:10,680 --> 00:33:20,270 Il ya ce __ strcmp_sse4_2, et il nous dit que cela se passe dans ce fichier 397 00:33:20,270 --> 00:33:29,450 appelé sysdeps/i386, tout cela, à nouveau, une sorte de désordre - mais la ligne 254. 398 00:33:29,450 --> 00:33:31,670 C'est un peu difficile à analyser. Habituellement, lorsque vous voyez des trucs comme ça, 399 00:33:31,670 --> 00:33:38,770 ce qui signifie qu'il est seg failles dans l'une des bibliothèques du système. 400 00:33:38,770 --> 00:33:43,220 Donc, quelque chose à voir avec strcmp. Les gars, vous avez vu avant strcmp. 401 00:33:43,220 --> 00:33:52,730 Pas trop fou, mais cela signifie que strcmp est cassé ou qu'il ya un problème avec strcmp? 402 00:33:52,730 --> 00:33:57,110 Que pensez-vous, Alexander? 403 00:33:57,110 --> 00:34:04,890 [Alexander] Est-ce que - est de 254 la ligne? Et le - et non le binaire, mais ce n'est pas leurs plafonds, 404 00:34:04,890 --> 00:34:10,590 et puis il ya une autre langue pour chaque fonction. Est-ce que 254 à cette fin, ou -? 405 00:34:10,590 --> 00:34:21,460 >> C'est la ligne 254. On dirait que dans ce fichier. S, de sorte qu'il a probablement code assembleur. 406 00:34:21,460 --> 00:34:25,949 >> Mais, je pense que la chose la plus pressante, parce que nous avons obtenu une faute seg, 407 00:34:25,949 --> 00:34:29,960 et on dirait que ça vient de la fonction strcmp, 408 00:34:29,960 --> 00:34:38,030 ce que cela signifie, alors, que strcmp est cassé? 409 00:34:38,030 --> 00:34:42,290 Il ne devrait pas, je l'espère. Alors juste parce que vous avez une erreur de segmentation 410 00:34:42,290 --> 00:34:49,480 dans l'une des fonctions du système, généralement cela signifie que vous n'avez tout simplement pas appelée correctement. 411 00:34:49,480 --> 00:34:52,440 Le plus rapide chose à faire pour comprendre ce qui se passe réellement 412 00:34:52,440 --> 00:34:55,500 quand vous voyez quelque chose de fou comme ça, quand vous voyez une faute seg, 413 00:34:55,500 --> 00:34:59,800 surtout si vous avez un programme qui aide plus que simplement principale, 414 00:34:59,800 --> 00:35:03,570 est d'utiliser un backtrace. 415 00:35:03,570 --> 00:35:13,080 J'abrège trace en écrivant bt, par opposition au mot backtrace complet. 416 00:35:13,080 --> 00:35:16,510 Mais Charlotte, qu'est-ce qui se passe quand vous tapez bt et appuyez sur Entrée? 417 00:35:16,510 --> 00:35:23,200 [Charlotte] Il me montre deux lignes, 0 ligne et la ligne 1. 418 00:35:23,200 --> 00:35:26,150 Ouais >>. Ainsi, la ligne 0 et la ligne 1. 419 00:35:26,150 --> 00:35:34,560 Ce sont les cadres de pile réels qui sont actuellement en jeu lorsque votre programme s'est écrasé. 420 00:35:34,560 --> 00:35:42,230 A partir de la trame la plus haute, la frame 0, et aller au fond plus, ce qui est l'image 1. 421 00:35:42,230 --> 00:35:45,140 Notre cadre le plus élevé est le cadre strcmp. 422 00:35:45,140 --> 00:35:50,080 Vous pouvez considérer cela comme semblable à ce problème, nous ne faisions que sur le questionnaire avec les pointeurs, 423 00:35:50,080 --> 00:35:54,890 où nous avions échanger cadre de pile au-dessus du cadre de pile principale, 424 00:35:54,890 --> 00:35:59,700 et nous avons eu les variables qui utilisent swap a été au-dessus des variables principale a été l'aide. 425 00:35:59,700 --> 00:36:08,440 Voici notre accident s'est produit dans notre fonction strcmp, qui a été appelé par notre fonction principale, 426 00:36:08,440 --> 00:36:14,370 et backtrace nous donne non seulement les fonctions dont les choses ont échoué, 427 00:36:14,370 --> 00:36:16,440 mais c'est aussi nous dire où tout a été appelée. 428 00:36:16,440 --> 00:36:18,830 Donc, si je défiler sur un peu plus vers la droite, 429 00:36:18,830 --> 00:36:26,110 nous pouvons voir que oui, nous étions à la ligne 254 de ce fichier strcmp-sse4.s. 430 00:36:26,110 --> 00:36:32,540 Mais l'appel a été fait à buggy1.c, ligne 6. 431 00:36:32,540 --> 00:36:35,960 Cela signifie que nous pouvons faire - c'est que nous pouvons simplement aller vérifier et voir ce qui se passait 432 00:36:35,960 --> 00:36:39,930 à buggy1.c, ligne 6. 433 00:36:39,930 --> 00:36:43,780 Encore une fois, il ya deux manières de le faire. La première consiste à sortir du GDB 434 00:36:43,780 --> 00:36:49,460 ou avoir votre code s'ouvrira dans une nouvelle fenêtre et des références croisées. 435 00:36:49,460 --> 00:36:54,740 Cela, en soi, est très pratique parce que maintenant si vous êtes aux heures de bureau 436 00:36:54,740 --> 00:36:57,220 et vous avez un défaut de segmentation et de votre carte de TF se demande où tout se brisait, 437 00:36:57,220 --> 00:36:59,710 vous pouvez juste dire: "Oh, ligne 6. Je ne sais pas ce qui se passe, 438 00:36:59,710 --> 00:37:03,670 mais quelque chose dans la ligne 6 est à l'origine de mon programme à briser. " 439 00:37:03,670 --> 00:37:10,430 L'autre façon de le faire est que vous pouvez utiliser cette commande appelée liste de GDB. 440 00:37:10,430 --> 00:37:13,650 Vous pouvez également l'abréger par l. 441 00:37:13,650 --> 00:37:18,910 Donc, si nous avons atteint l, que faisons-nous ici? 442 00:37:18,910 --> 00:37:21,160 Nous obtenons un tas de trucs bizarres. 443 00:37:21,160 --> 00:37:26,030 Ceci est le code assembleur réelle 444 00:37:26,030 --> 00:37:29,860 c'est-à strcmp_sse4_2. 445 00:37:29,860 --> 00:37:32,440 Cet air un peu funky, 446 00:37:32,440 --> 00:37:36,520 et la raison pour laquelle nous obtenons c'est parce qu'en ce moment, 447 00:37:36,520 --> 00:37:40,160 GDB nous a dans la trame 0. 448 00:37:40,160 --> 00:37:43,070 >> Donc, chaque fois que nous sommes à votre écoute, une fois que nous regardons le code source, 449 00:37:43,070 --> 00:37:50,530 nous nous penchons sur le code source qui a trait à la trame de pile que nous sommes actuellement po 450 00:37:50,530 --> 00:37:53,200 Ainsi, afin d'obtenir quelque chose de significatif, nous devons 451 00:37:53,200 --> 00:37:57,070 passer à un cadre de pile qui est plus logique. 452 00:37:57,070 --> 00:38:00,180 Dans ce cas, le cadre de pile principale serait logique un peu plus, 453 00:38:00,180 --> 00:38:02,680 parce que c'était réellement le code que nous avons écrit. 454 00:38:02,680 --> 00:38:05,330 Pas le code strcmp. 455 00:38:05,330 --> 00:38:08,650 La façon dont vous pouvez vous déplacer entre les images, dans ce cas, parce que nous en avons deux, 456 00:38:08,650 --> 00:38:10,430 on a 0 et 1, 457 00:38:10,430 --> 00:38:13,650 vous faire avec le haut et vers le bas des commandes. 458 00:38:13,650 --> 00:38:18,480 Si je déménage en place un cadre, 459 00:38:18,480 --> 00:38:21,770 maintenant je suis dans la pile principale. 460 00:38:21,770 --> 00:38:24,330 Je peux me déplacer vers le bas pour revenir à l'endroit où je me trouvais, 461 00:38:24,330 --> 00:38:32,830 remonter, redescendre et remonter. 462 00:38:32,830 --> 00:38:39,750 Si jamais vous faites votre programme dans GDB, vous obtenez un crash, vous obtenez la trace, 463 00:38:39,750 --> 00:38:42,380 et vous voyez que c'est dans un fichier que vous ne savez pas ce qui se passe. 464 00:38:42,380 --> 00:38:45,460 Vous essayez liste, le code ne semble pas familier pour vous, 465 00:38:45,460 --> 00:38:48,150 jetez un oeil à vos cadres et de savoir où vous êtes. 466 00:38:48,150 --> 00:38:51,010 Vous êtes probablement dans le cadre de pile mal. 467 00:38:51,010 --> 00:38:58,760 Ou au moins vous êtes dans un cadre de pile qui n'est pas celui que vous pouvez vraiment déboguer. 468 00:38:58,760 --> 00:39:03,110 Maintenant que nous sommes dans le cadre de pile appropriée, nous sommes en principal, 469 00:39:03,110 --> 00:39:08,100 nous pouvons maintenant utiliser la commande list pour comprendre ce que la ligne était. 470 00:39:08,100 --> 00:39:13,590 Et vous pouvez le voir, il a imprimé pour nous ici. 471 00:39:13,590 --> 00:39:19,470 Mais nous pouvons atteindre la liste de tous les mêmes, et la liste nous donne cette impression agréable 472 00:39:19,470 --> 00:39:23,920 du code source réel ce qui se passe ici. 473 00:39:23,920 --> 00:39:26,420 >> En particulier, nous pouvons regarder à la ligne 6. 474 00:39:26,420 --> 00:39:29,330 Nous pouvons voir ce qui se passe ici. 475 00:39:29,330 --> 00:39:31,250 Et il semble que nous faisons une comparaison de chaînes 476 00:39:31,250 --> 00:39:41,050 entre les chaînes "CS50" rochers et argv [1]. 477 00:39:41,050 --> 00:39:45,700 Quelque chose à propos de cette plantait. 478 00:39:45,700 --> 00:39:54,120 Donc, Missy, avez-vous des idées sur ce qui pourrait se passer ici? 479 00:39:54,120 --> 00:39:59,400 [Missy] Je ne sais pas pourquoi il se plantent. >> Tu ne sais pas pourquoi il s'écraser? 480 00:39:59,400 --> 00:40:02,700 Jimmy, des idées? 481 00:40:02,700 --> 00:40:06,240 [Jimmy] Je ne suis pas tout à fait sûr, mais la dernière fois que nous avons utilisé comparaison de chaîne, 482 00:40:06,240 --> 00:40:10,260 ou strcmp, comme nous avons eu trois cas différents sous lui. 483 00:40:10,260 --> 00:40:12,800 Nous n'avons pas d'==, je ne pense pas, raison de dire que la première ligne. 484 00:40:12,800 --> 00:40:16,700 Au lieu de cela il a été séparé en trois, et celui-ci était == 0, 485 00:40:16,700 --> 00:40:19,910 celui-ci était <0, je pense, et celui-ci était> 0. 486 00:40:19,910 --> 00:40:22,590 Alors peut-être quelque chose comme ça? Ouais >>. Donc, il ya cette question 487 00:40:22,590 --> 00:40:27,200 faisons-nous de la comparaison correctement? 488 00:40:27,200 --> 00:40:31,660 Stella? Toute pensée? 489 00:40:31,660 --> 00:40:38,110 [Stella] Je ne suis pas sûr. >> Je ne sais pas. Daniel? Pensées? D'accord. 490 00:40:38,110 --> 00:40:44,770 Il s'avère ce qui se passe ici, c'est quand nous avons lancé le programme 491 00:40:44,770 --> 00:40:48,370 et nous avons obtenu la faute seg, lorsque vous avez exécuté le programme pour la première fois, Daniel, 492 00:40:48,370 --> 00:40:50,800 avez-vous lui donner tous les arguments de ligne de commande? 493 00:40:50,800 --> 00:40:58,420 [Daniel] No. No. >> Dans ce cas, quelle est la valeur de argv [1]? 494 00:40:58,420 --> 00:41:00,920 >> Il n'y a pas de valeur. Droit >>. 495 00:41:00,920 --> 00:41:06,120 Eh bien, il n'ya pas de valeur de chaîne appropriée. 496 00:41:06,120 --> 00:41:10,780 Mais il ya une certaine valeur. Quelle est la valeur qui est stockée là-dedans? 497 00:41:10,780 --> 00:41:15,130 Une valeur >> des ordures? >> C'est soit une valeur ordures ou, dans ce cas, 498 00:41:15,130 --> 00:41:19,930 la fin du tableau argv est toujours terminée par null. 499 00:41:19,930 --> 00:41:26,050 Alors, que fait été stockées dans il est nul. 500 00:41:26,050 --> 00:41:30,810 L'autre façon de résoudre ce problème, plutôt que de penser à travers, 501 00:41:30,810 --> 00:41:33,420 est d'essayer de l'imprimer. 502 00:41:33,420 --> 00:41:35,880 C'est là que je disais que l'utilisation de GDB est grande, 503 00:41:35,880 --> 00:41:40,640 parce que vous pouvez imprimer toutes les variables, toutes les valeurs que vous souhaitez 504 00:41:40,640 --> 00:41:43,230 en utilisant cette commande handy-dandy p. 505 00:41:43,230 --> 00:41:48,520 Donc, si je tape p et ensuite je tape la valeur d'une variable ou le nom d'une variable, 506 00:41:48,520 --> 00:41:55,320 dire, argc, je vois que argc est 1. 507 00:41:55,320 --> 00:42:01,830 Si je veux imprimer argv [0], je peux le faire comme ça. 508 00:42:01,830 --> 00:42:04,840 Et comme nous l'avons vu, argv [0] est toujours le nom de votre programme, 509 00:42:04,840 --> 00:42:06,910 toujours le nom de l'exécutable. 510 00:42:06,910 --> 00:42:09,740 Ici vous pouvez voir qu'il a le nom de chemin complet. 511 00:42:09,740 --> 00:42:15,920 Je peux aussi imprimer argv [1] et de voir ce qui se passe. 512 00:42:15,920 --> 00:42:20,890 >> Ici, nous avons eu ce genre de valeur mystique. 513 00:42:20,890 --> 00:42:23,890 Nous avons eu cette 0x0. 514 00:42:23,890 --> 00:42:27,850 Rappelez-vous au début de la période où nous avons parlé de nombres hexadécimaux? 515 00:42:27,850 --> 00:42:34,680 Ou que peu de doute à la fin de pset 0 sur la façon de représenter 50 en hexadécimal? 516 00:42:34,680 --> 00:42:39,410 La façon d'écrire les nombres hexadécimaux dans CS, juste pour ne pas nous confondre 517 00:42:39,410 --> 00:42:46,080 avec des nombres décimaux, c'est que nous toujours les préfixer par 0x. 518 00:42:46,080 --> 00:42:51,420 Donc, ce préfixe 0x toujours signifie simplement interpréter le numéro suivant comme un nombre hexadécimal, 519 00:42:51,420 --> 00:42:57,400 non pas comme une chaîne et non comme un nombre décimal, et non comme un nombre binaire. 520 00:42:57,400 --> 00:43:02,820 Comme le nombre 5-0 est un nombre en hexadécimal valide. 521 00:43:02,820 --> 00:43:06,240 Et c'est un nombre en décimal, 50. 522 00:43:06,240 --> 00:43:10,050 Donc, c'est juste la façon dont nous lever l'ambiguïté. 523 00:43:10,050 --> 00:43:14,860 Donc 0x0 moyens hexadécimal compris entre 0, ce qui est également décimale 0, binaire 0. 524 00:43:14,860 --> 00:43:17,030 C'est juste la valeur 0. 525 00:43:17,030 --> 00:43:22,630 Il s'avère que c'est ce nul est, en fait, dans la mémoire. 526 00:43:22,630 --> 00:43:25,940 Null est juste 0. 527 00:43:25,940 --> 00:43:37,010 Ici, l'élément stocké à argv [1] est nulle. 528 00:43:37,010 --> 00:43:45,220 Nous essayons donc de comparer notre "CS50 rochers" chaîne à une chaîne vide. 529 00:43:45,220 --> 00:43:48,130 Donc déréférencement nulle, essayez d'accéder à des choses nulles, 530 00:43:48,130 --> 00:43:55,050 ceux-ci sont généralement va provoquer une sorte de défaut de segmentation ou d'autres mauvaises choses se produisent. 531 00:43:55,050 --> 00:43:59,350 Et il s'avère que strcmp ne vérifie pas 532 00:43:59,350 --> 00:44:04,340 si oui ou non vous avez passé dans une valeur qui est nulle. 533 00:44:04,340 --> 00:44:06,370 Au contraire, il va juste devant, tente de faire sa chose, 534 00:44:06,370 --> 00:44:14,640 et si elle seg défauts, il seg défauts, et c'est votre problème. Tu dois aller le réparer. 535 00:44:14,640 --> 00:44:19,730 Très rapidement, comment pourrions-nous résoudre ce problème? Charlotte? 536 00:44:19,730 --> 00:44:23,540 [Charlotte] Vous pouvez vérifier si l'aide. 537 00:44:23,540 --> 00:44:32,240 Donc, si argv [1] est nulle, == 0, puis revenez 1, ou quelque chose [inintelligible]. 538 00:44:32,240 --> 00:44:34,590 Ouais >>. Donc, c'est une excellente façon de le faire, comme on peut le vérifier, 539 00:44:34,590 --> 00:44:39,230 la valeur que nous sommes sur le point de passer dans strcmp, argv [1], est-elle nulle? 540 00:44:39,230 --> 00:44:45,830 Si c'est nul, alors on peut dire ok, avorter. 541 00:44:45,830 --> 00:44:49,450 >> Une façon plus courante de le faire est d'utiliser la valeur argc. 542 00:44:49,450 --> 00:44:52,040 Vous pouvez voir ici au début du principal, 543 00:44:52,040 --> 00:44:58,040 que nous avons omis premier test que nous faisons quand nous généralement utiliser des arguments de ligne de commande, 544 00:44:58,040 --> 00:45:05,240 qui consiste à tester si oui ou non la valeur de notre argc est ce que nous attendons. 545 00:45:05,240 --> 00:45:10,290 Dans ce cas, nous nous attendons au moins deux arguments, 546 00:45:10,290 --> 00:45:13,660 le nom du programme, plus une autre. 547 00:45:13,660 --> 00:45:17,140 Parce que nous sommes sur le point d'utiliser le second argument ici. 548 00:45:17,140 --> 00:45:21,350 Donc, avoir une sorte de test au préalable, avant notre appel strcmp 549 00:45:21,350 --> 00:45:37,390 que les tests si oui ou non argv est au moins 2, serait aussi faire le même genre de chose. 550 00:45:37,390 --> 00:45:40,620 Nous pouvons voir si cela fonctionne en exécutant à nouveau le programme. 551 00:45:40,620 --> 00:45:45,610 Vous pouvez toujours redémarrer votre programme dans GDB, qui est vraiment agréable. 552 00:45:45,610 --> 00:45:49,310 Vous pouvez courir, et quand vous passez des arguments à votre programme, 553 00:45:49,310 --> 00:45:53,060 vous les croisez lorsque vous appelez courir, pas lorsque vous démarrez GDB. 554 00:45:53,060 --> 00:45:57,120 De cette façon, vous pouvez garder votre programme en invoquant des arguments différents à chaque fois. 555 00:45:57,120 --> 00:46:08,080 Alors courez, ou encore, je peux taper r, et voyons ce qui se passe si on tape "bonjour". 556 00:46:08,080 --> 00:46:11,140 Il vous demandera toujours si vous voulez le lancer depuis le début. 557 00:46:11,140 --> 00:46:17,490 Habituellement, vous ne souhaitez démarrer depuis le début. 558 00:46:17,490 --> 00:46:25,010 Et à ce stade, il redémarre à nouveau, il imprime 559 00:46:25,010 --> 00:46:28,920 le programme que nous utilisons, buggy1, avec l'argument bonjour, 560 00:46:28,920 --> 00:46:32,720 et l'imprime sur cette norme, il dit, "Vous obtenez un D," visage triste. 561 00:46:32,720 --> 00:46:37,610 Mais nous n'avons pas seg faute. Il a déclaré que le processus s'est terminé normalement. 562 00:46:37,610 --> 00:46:39,900 Alors que semble assez bon. 563 00:46:39,900 --> 00:46:43,050 Pas de défaut plus seg, nous en avons fait passé, 564 00:46:43,050 --> 00:46:48,190 de sorte qu'il ressemble tel était effectivement le bug faute seg que nous recevions. 565 00:46:48,190 --> 00:46:51,540 Malheureusement, il nous dit que nous obtenons un D. 566 00:46:51,540 --> 00:46:54,090 >> Nous ne pouvons revenir en arrière et regarder le code et voir ce qui se passe là-bas 567 00:46:54,090 --> 00:46:57,980 de comprendre ce qui était - pourquoi il nous a dit que nous avons obtenu un D. 568 00:46:57,980 --> 00:47:03,690 Voyons voir, ici a ce printf dire que tu as un D. 569 00:47:03,690 --> 00:47:08,540 Si nous tapons la liste, que vous gardez liste tapant, il conserve une itération à travers de votre programme, 570 00:47:08,540 --> 00:47:10,940 donc ça va vous montrer les premières lignes de votre programme. 571 00:47:10,940 --> 00:47:15,450 Ensuite, il va vous montrer les quelques lignes qui suivent, et le morceau suivant et le morceau suivant. 572 00:47:15,450 --> 00:47:18,240 Et ça va continuer à essayer de descendre. 573 00:47:18,240 --> 00:47:21,180 Et maintenant, nous allons arriver à «aligner le numéro 16 est hors de portée." 574 00:47:21,180 --> 00:47:23,940 Parce qu'il a seulement 15 lignes. 575 00:47:23,940 --> 00:47:30,310 Si vous arrivez à ce point, et vous vous demandez, "Qu'est-ce que je fais?" vous pouvez utiliser la commande help. 576 00:47:30,310 --> 00:47:34,340 Utilisez aider et puis de lui donner le nom d'une commande. 577 00:47:34,340 --> 00:47:36,460 Et vous voyez le GDB nous donne tout ce genre de choses. 578 00:47:36,460 --> 00:47:43,870 Il dit, "Sans argument, énumère dix lignes plus après ou autour de la liste précédente. 579 00:47:43,870 --> 00:47:47,920 Liste - énumère les dix lignes avant - " 580 00:47:47,920 --> 00:47:52,960 Alors essayons d'utiliser moins de liste. 581 00:47:52,960 --> 00:47:57,000 Et qui répertorie les 10 lignes précédentes, vous pouvez jouer avec la liste un peu. 582 00:47:57,000 --> 00:48:02,330 Vous pouvez faire la liste, la liste -, vous pouvez même donner la liste d'un certain nombre, comme la liste des 8, 583 00:48:02,330 --> 00:48:07,500 et il va dresser la liste des 10 lignes autour de la ligne 8. 584 00:48:07,500 --> 00:48:10,290 Et vous pouvez voir ce qui se passe ici est que vous avez un simple if else. 585 00:48:10,290 --> 00:48:13,980 Si vous tapez CS50 roches, il imprime "Vous obtenez un A.» 586 00:48:13,980 --> 00:48:16,530 Sinon, il affiche "Vous obtenez un D." 587 00:48:16,530 --> 00:48:23,770 Bummer ville. Très bien. Oui? 588 00:48:23,770 --> 00:48:26,730 >> [Daniel] Alors, quand j'ai essayé de faire CS50 rochers sans les guillemets, 589 00:48:26,730 --> 00:48:29,290 il dit: «Vous obtenez un D." 590 00:48:29,290 --> 00:48:32,560 J'avais besoin des guillemets pour le faire fonctionner, pourquoi est-ce? 591 00:48:32,560 --> 00:48:38,490 Ouais >>. Il s'avère que lorsque - c'est une autre friandise peu de plaisir - 592 00:48:38,490 --> 00:48:47,900 lorsque vous exécutez le programme, si nous l'exécutons et nous taper CS50 roches, 593 00:48:47,900 --> 00:48:50,800 tout comme Daniel a dit qu'il a fait, et que vous appuyez sur Entrée, 594 00:48:50,800 --> 00:48:52,870 il dit encore nous obtenons un D. 595 00:48:52,870 --> 00:48:55,580 Et la question est, pourquoi est-ce? 596 00:48:55,580 --> 00:49:02,120 Et il s'avère que les deux notre terminal et GDB analyser ces que deux arguments distincts. 597 00:49:02,120 --> 00:49:04,800 Parce que quand il ya un espace, qui est sous-entendu que 598 00:49:04,800 --> 00:49:08,730 le premier argument pris fin; l'argument suivant est sur le point de commencer. 599 00:49:08,730 --> 00:49:13,260 La façon de combiner les en deux, ou désolé, en un seul argument, 600 00:49:13,260 --> 00:49:18,510 est d'utiliser les guillemets. 601 00:49:18,510 --> 00:49:29,560 Alors maintenant, si nous le mettre entre guillemets et l'exécuter à nouveau, on obtient un A. 602 00:49:29,560 --> 00:49:38,780 Donc, pour récapituler, sans guillemets, CS50 et des roches sont analysés comme deux arguments distincts. 603 00:49:38,780 --> 00:49:45,320 Avec des guillemets, il est analysé comme un argument tout à fait. 604 00:49:45,320 --> 00:49:53,070 >> Nous pouvons voir cela avec un point d'arrêt. 605 00:49:53,070 --> 00:49:54,920 Jusqu'à présent, nous avons mis en place notre programme, et il a été en cours d'exécution 606 00:49:54,920 --> 00:49:58,230 jusqu'à ce qu'il seg défauts ou frappe une erreur 607 00:49:58,230 --> 00:50:05,930 ou jusqu'à ce qu'il soit sorti et tout a été tout à fait bien. 608 00:50:05,930 --> 00:50:08,360 Ce n'est pas forcément la chose la plus utile, parce que parfois, 609 00:50:08,360 --> 00:50:11,840 vous avez une erreur dans votre programme, mais ce n'est pas de provoquer une erreur de segmentation. 610 00:50:11,840 --> 00:50:16,950 Ce n'est pas la cause de votre programme pour arrêter ou quelque chose comme ça. 611 00:50:16,950 --> 00:50:20,730 La manière d'obtenir GDB pour mettre en pause votre programme à un moment donné 612 00:50:20,730 --> 00:50:23,260 est de mettre un point d'arrêt. 613 00:50:23,260 --> 00:50:26,520 Vous pouvez faire cela en mettant un point d'arrêt sur un nom de fonction 614 00:50:26,520 --> 00:50:30,770 ou vous pouvez définir un point d'arrêt sur une ligne de code. 615 00:50:30,770 --> 00:50:34,450 Je tiens à mettre des points d'arrêt sur les noms de fonctions, parce que - facile à retenir, 616 00:50:34,450 --> 00:50:37,700 et si vous allez réellement et de modifier le code source d'un petit peu, 617 00:50:37,700 --> 00:50:42,020 alors votre point d'arrêt sera effectivement rester au même endroit dans votre code. 618 00:50:42,020 --> 00:50:44,760 Alors que si vous utilisez des numéros de ligne et les numéros de ligne changer 619 00:50:44,760 --> 00:50:51,740 parce que vous ajoutez ou supprimez un code, alors vos points d'arrêt sont tous totalement foiré. 620 00:50:51,740 --> 00:50:58,590 L'une des choses les plus communes que je fais est un point d'arrêt sur la fonction principale. 621 00:50:58,590 --> 00:51:05,300 Souvent, je vais démarrer GDB, je vais taper b principal, appuyez sur Entrée, et ça va mettre un point d'arrêt 622 00:51:05,300 --> 00:51:10,630 sur la fonction principale qui dit simplement, «en pause le programme dès que vous commencez à courir», 623 00:51:10,630 --> 00:51:17,960 et de cette façon, quand je lance mon programme avec, disons, CS50 rochers que deux arguments 624 00:51:17,960 --> 00:51:24,830 et appuyez sur Entrée, il arrive à la fonction principale et il s'arrête juste à la toute première ligne, 625 00:51:24,830 --> 00:51:30,620 juste avant qu'elle évalue la fonction strcmp. 626 00:51:30,620 --> 00:51:34,940 >> Depuis que je suis en pause, je peux maintenant commencer à bidouillent et de voir ce qui se passe 627 00:51:34,940 --> 00:51:40,250 avec toutes les différentes variables qui sont passés dans mon programme. 628 00:51:40,250 --> 00:51:43,670 Ici, je peux imprimer argc et voir ce qui se passe. 629 00:51:43,670 --> 00:51:50,030 Voir à ce que argc vaut 3, parce que c'est a 3 valeurs différentes en elle. 630 00:51:50,030 --> 00:51:54,060 Il a le nom du programme, il a le premier argument et le second argument. 631 00:51:54,060 --> 00:52:09,330 Nous pouvons imprimer sur ceux en consultant d'argv [0], argv [1], et argv [2]. 632 00:52:09,330 --> 00:52:12,030 Alors maintenant, vous pouvez aussi voir pourquoi cet appel strcmp est voué à l'échec, 633 00:52:12,030 --> 00:52:21,650 parce que vous voyez que cela n'a diviser la CS50 et les roches en deux arguments distincts. 634 00:52:21,650 --> 00:52:27,250 À ce stade, une fois que vous avez atteint un point d'arrêt, vous pouvez continuer à exécuter votre programme 635 00:52:27,250 --> 00:52:32,920 ligne par ligne, au lieu de commencer votre programme. 636 00:52:32,920 --> 00:52:35,520 Donc, si vous ne voulez pas commencer votre programme à nouveau et juste continuer à partir d'ici, 637 00:52:35,520 --> 00:52:41,970 vous pouvez utiliser la commande continue et continuera va exécuter le programme jusqu'à la fin. 638 00:52:41,970 --> 00:52:45,010 Tout comme il l'a fait ici. 639 00:52:45,010 --> 00:52:54,880 Cependant, si je redémarre le programme, CS50 rochers, il frappe mon point d'arrêt à nouveau, 640 00:52:54,880 --> 00:52:59,670 et cette fois, si je ne tiens pas à aller tout le chemin à travers le reste du programme, 641 00:52:59,670 --> 00:53:08,040 Je peux utiliser la commande suivante, que j'ai également abréger avec n. 642 00:53:08,040 --> 00:53:12,960 Et cela va parcourir le programme ligne par ligne. 643 00:53:12,960 --> 00:53:17,530 Ainsi, vous pouvez regarder les choses d'exécuter, en tant que variables de changement, que les choses sont mises à jour. 644 00:53:17,530 --> 00:53:21,550 Ce qui est assez agréable. 645 00:53:21,550 --> 00:53:26,570 L'autre chose cool, c'est plutôt que de répéter la même commande à plusieurs reprises, encore et encore, 646 00:53:26,570 --> 00:53:30,670 si vous appuyez simplement sur Entrée - alors là, vous voyez, je n'ai pas tapé dans quoi que ce soit - 647 00:53:30,670 --> 00:53:33,780 si je viens d'appuyer sur Entrée, il répétera la commande précédente, 648 00:53:33,780 --> 00:53:36,900 ou la commande GDB précédente que je viens de mettre po 649 00:53:36,900 --> 00:53:56,000 Je peux continuer à appuyer sur Enter et ça va continuer pas à pas dans mon code ligne par ligne. 650 00:53:56,000 --> 00:53:59,310 J'encourage vous les gars pour aller voir les programmes bogués autres aussi. 651 00:53:59,310 --> 00:54:01,330 Nous n'avons pas eu le temps de passer à travers tous aujourd'hui dans la section. 652 00:54:01,330 --> 00:54:05,890 Le code source est là, de sorte que vous pouvez sorte de voir ce qui se passe 653 00:54:05,890 --> 00:54:07,730 dans les coulisses si vous êtes vraiment coincé, 654 00:54:07,730 --> 00:54:11,940 mais à tout le moins, juste pratiquer démarrer GDB, 655 00:54:11,940 --> 00:54:13,940 l'exécution du programme jusqu'à ce qu'il se brise sur vous, 656 00:54:13,940 --> 00:54:18,260 obtenir la trace, déterminer ce qui fonctionne le crash était, 657 00:54:18,260 --> 00:54:24,450 quelle ligne c'est sur, imprimer certaines valeurs des variables, 658 00:54:24,450 --> 00:54:30,140 juste pour vous faire une idée pour elle, parce que cela va vraiment vous aider à aller de l'avant. 659 00:54:30,140 --> 00:54:36,340 À ce stade, nous allons arrêter de sortir de GDB, qui vous aide ou tout simplement arrêter de q. 660 00:54:36,340 --> 00:54:40,460 Si votre programme est au milieu de courir encore, et il n'a pas quitté, 661 00:54:40,460 --> 00:54:43,510 il sera toujours vous demander: «Etes-vous sûr que vous voulez vraiment quitter?" 662 00:54:43,510 --> 00:54:48,770 Vous pouvez appuyez simplement oui. 663 00:54:48,770 --> 00:54:55,250 >> Maintenant, nous allons nous pencher sur le problème suivant que nous avons, qui est le programme de chat. 664 00:54:55,250 --> 00:54:59,880 Si vous regardez le court et sur la réorientation des tuyaux, vous verrez que Tommy utilise ce programme 665 00:54:59,880 --> 00:55:07,540 qui imprime essentiellement toute la sortie d'un fichier à l'écran. 666 00:55:07,540 --> 00:55:12,660 Donc, si je lance chat, il s'agit en fait d'un programme intégré à l'appareil, 667 00:55:12,660 --> 00:55:16,860 et si vous avez Mac, vous pouvez le faire sur votre Mac aussi, si vous ouvrez terminal. 668 00:55:16,860 --> 00:55:25,630 Et nous - chat, disons, cp.c, et appuyez sur Entrée. 669 00:55:25,630 --> 00:55:29,640 Ce que cela fait, si nous défiler vers le haut un peu et de voir où nous avons couru de la ligne, 670 00:55:29,640 --> 00:55:40,440 ou lorsque nous avons couru la commande cat, il est littéralement juste imprimé sur le contenu de cp.c à notre écran. 671 00:55:40,440 --> 00:55:44,140 On peut l'exécuter à nouveau et vous pouvez mettre plusieurs fichiers en même temps. 672 00:55:44,140 --> 00:55:49,880 Ainsi, vous pouvez faire cp.c chat, et alors nous pouvons également concaténer le fichier Cat.C, 673 00:55:49,880 --> 00:55:53,250 qui est le programme que nous sommes sur le point d'écrire, 674 00:55:53,250 --> 00:55:58,140 et il va imprimer les deux fichiers dos à dos à notre écran. 675 00:55:58,140 --> 00:56:05,490 Donc, si nous défiler vers le haut un peu, on voit que quand nous avons eu cette cp.c chat, Cat.C, 676 00:56:05,490 --> 00:56:17,110 abord imprimé sur le fichier cp, puis en dessous, elle imprimée sur le fichier Cat.C juste ici. 677 00:56:17,110 --> 00:56:19,650 Nous allons l'utiliser pour simplement remettre les pieds mouillés. 678 00:56:19,650 --> 00:56:25,930 Jouez avec la simple impression à la borne, voir comment ça fonctionne. 679 00:56:25,930 --> 00:56:39,170 Si vous les gars ouvrir avec gedit Cat.C, appuyez sur Entrée, 680 00:56:39,170 --> 00:56:43,760 vous pouvez voir le programme que nous sommes en train d'écrire. 681 00:56:43,760 --> 00:56:48,980 Nous avons inclus cette plaque de la chaudière agréable, donc nous n'avons pas à passer du temps en tapant tout cela. 682 00:56:48,980 --> 00:56:52,310 Nous vérifions également le nombre d'arguments passé po 683 00:56:52,310 --> 00:56:56,910 Nous imprimons sur un message d'utilisation agréable. 684 00:56:56,910 --> 00:57:00,950 >> C'est le genre de chose qui, encore une fois, comme nous venons de parler, 685 00:57:00,950 --> 00:57:04,490 c'est presque comme si la mémoire musculaire. 686 00:57:04,490 --> 00:57:07,190 N'oubliez pas de continuer à faire le même genre de trucs 687 00:57:07,190 --> 00:57:11,310 et toujours l'impression à une sorte de message utile 688 00:57:11,310 --> 00:57:17,670 de sorte que les gens sachent comment exécuter votre programme. 689 00:57:17,670 --> 00:57:21,630 Avec un chat, c'est assez simple, nous allons juste passer en revue tous les arguments différents 690 00:57:21,630 --> 00:57:24,300 qui ont été transmis à notre programme, et nous allons imprimer 691 00:57:24,300 --> 00:57:29,950 leur contenu sur l'écran à une à la fois. 692 00:57:29,950 --> 00:57:35,670 Pour imprimer des fichiers en dehors de l'écran, nous allons faire quelque chose de très similaire 693 00:57:35,670 --> 00:57:38,120 à ce que nous avons fait à la fin du quiz. 694 00:57:38,120 --> 00:57:45,350 A la fin du questionnaire, qui embauchent programme, nous avons dû ouvrir un fichier, 695 00:57:45,350 --> 00:57:48,490 et puis nous avons eu à imprimer. 696 00:57:48,490 --> 00:57:54,660 Dans ce cas, nous allons ouvrir un fichier, et nous allons lire à partir de ce lieu. 697 00:57:54,660 --> 00:58:00,630 Ensuite, nous allons imprimer, au lieu d'un fichier, nous allons afficher à l'écran. 698 00:58:00,630 --> 00:58:05,830 Ainsi, l'impression à l'écran que vous avez tous fait avant avec printf. 699 00:58:05,830 --> 00:58:08,290 Donc, ce n'est pas trop fou. 700 00:58:08,290 --> 00:58:12,190 Mais la lecture d'un fichier est un peu bizarre. 701 00:58:12,190 --> 00:58:17,300 Nous allons passer par un petit peu à la fois. 702 00:58:17,300 --> 00:58:20,560 Si vous les gars revenir à ce dernier problème sur votre quiz, problème 33, 703 00:58:20,560 --> 00:58:27,280 la première ligne que nous allons faire ici, en ouvrant le fichier, est très similaire à ce que nous faisions là. 704 00:58:27,280 --> 00:58:36,370 Donc, Stella, qu'est-ce que ce regard ligne comme, quand on ouvre un fichier? 705 00:58:36,370 --> 00:58:47,510 [Stella] FILE * Capital, fichier - >> Okay. >> - Est égale à la fonction fopen. Yup >>. 706 00:58:47,510 --> 00:58:55,980 Qui dans ce cas est? C'est dans le commentaire. 707 00:58:55,980 --> 00:59:06,930 >> C'est dans le commentaire? argv [i] et r? 708 00:59:06,930 --> 00:59:11,300 >> Exactement. Tout à fait. Donc, Stella est tout à fait raison. 709 00:59:11,300 --> 00:59:13,720 C'est ce que la ligne ressemble. 710 00:59:13,720 --> 00:59:19,670 Nous allons obtenir une variable flux de fichier, le stocker dans un FILE *, afin que tous les capuchons, 711 00:59:19,670 --> 00:59:25,720 FILE *, et le nom de cette variable sera de fichier. 712 00:59:25,720 --> 00:59:32,250 Nous pourrions l'appeler comme on veut. Nous pourrions l'appeler first_file ou file_i, tout ce que nous aimerions. 713 00:59:32,250 --> 00:59:37,590 Et puis le nom du fichier a été adoptée en ligne de commande pour ce programme. 714 00:59:37,590 --> 00:59:44,450 Donc, il est stocké dans argv [i], et ensuite nous allons ouvrir ce fichier en mode lecture. 715 00:59:44,450 --> 00:59:48,100 Maintenant que nous avons ouvert le fichier, quelle est la chose que nous avons toujours se rappeler de faire 716 00:59:48,100 --> 00:59:52,230 chaque fois que nous avons ouvert un dossier? Fermez-le. 717 00:59:52,230 --> 00:59:57,220 Donc, Missy, comment pouvons-nous fermer un fichier? 718 00:59:57,220 --> 01:00:01,020 [Missy] fclose (fichier) >> fclose (fichier). Exactement. 719 01:00:01,020 --> 01:00:05,340 Grande. D'accord. Si nous regardons ce commentaire à faire ici, 720 01:00:05,340 --> 01:00:11,940 dit-il, «Ouvrir argv [i] et imprimer son contenu sur la sortie standard." 721 01:00:11,940 --> 01:00:15,460 >> La sortie standard est un nom bizarre. Stdout est juste notre façon de dire 722 01:00:15,460 --> 01:00:22,880 nous voulons imprimer à la borne, nous voulons l'imprimer sur le flux de sortie standard. 723 01:00:22,880 --> 01:00:26,450 On peut réellement se débarrasser de ce commentaire ici. 724 01:00:26,450 --> 01:00:36,480 Je vais le copier et le coller puisque c'est ce que nous avons fait. 725 01:00:36,480 --> 01:00:41,290 À ce stade, nous avons maintenant de lire le fichier binaire à peu. 726 01:00:41,290 --> 01:00:46,300 Nous avons discuté quelques moyens de lecture des fichiers. 727 01:00:46,300 --> 01:00:51,830 Lesquels sont vos favoris si loin? 728 01:00:51,830 --> 01:00:57,960 Quels moyens avez-vous vu ou avez-vous souvenir, de lire les fichiers? 729 01:00:57,960 --> 01:01:04,870 [Daniel] fread? Fread >>? Donc, fread est un. Jimmy, savez-vous d'autres? 730 01:01:04,870 --> 01:01:12,150 [Jimmy] No. >> Okay. Nope. Charlotte? Alexander? Toutes les autres? D'accord. 731 01:01:12,150 --> 01:01:20,740 Alors que les autres sont fgetc, est celui que nous allons utiliser beaucoup. 732 01:01:20,740 --> 01:01:26,410 Il ya aussi fscanf, vous avez vu un modèle ici? 733 01:01:26,410 --> 01:01:29,170 Ils commencent tous par f. Rien à voir avec un fichier. 734 01:01:29,170 --> 01:01:35,260 Il ya fread, fgetc, fscanf. Ce sont toutes les fonctions de lecture. 735 01:01:35,260 --> 01:01:49,120 Pour l'écriture, nous avons fwrite, nous avons fputc au lieu de fgetc. 736 01:01:49,120 --> 01:01:58,250 Nous avons également fprintf comme nous l'avons vu sur le quiz. 737 01:01:58,250 --> 01:02:01,680 Comme il s'agit d'un problème qui implique la lecture d'un fichier, 738 01:02:01,680 --> 01:02:04,940 nous allons utiliser l'une de ces trois fonctions. 739 01:02:04,940 --> 01:02:10,890 Nous n'allons pas utiliser ces fonctions ici-bas. 740 01:02:10,890 --> 01:02:14,880 Ces fonctions se trouvent tous dans la norme E / S de la bibliothèque. 741 01:02:14,880 --> 01:02:17,510 Donc, si vous regardez en haut de ce programme, 742 01:02:17,510 --> 01:02:24,110 vous pouvez voir que nous avons déjà inclus le fichier d'en-tête pour l'E / S standard de la bibliothèque. 743 01:02:24,110 --> 01:02:27,120 Si nous voulons savoir laquelle nous voulons utiliser, 744 01:02:27,120 --> 01:02:29,690 on peut toujours ouvrir les pages de manuel. 745 01:02:29,690 --> 01:02:34,350 Donc, on peut taper stdio homme 746 01:02:34,350 --> 01:02:43,180 et lire tout sur l'entrée stdio et fonctions de sortie en C. 747 01:02:43,180 --> 01:02:49,870 Et nous pouvons déjà voir oh, regarde. Il est mentionné fgetc, il est mentionné fputc. 748 01:02:49,870 --> 01:02:57,220 Ainsi, vous pouvez descendre un peu et de regarder, par exemple, fgetc 749 01:02:57,220 --> 01:03:00,060 et de regarder sa page de manuel. 750 01:03:00,060 --> 01:03:03,430 Vous pouvez voir qu'il va de pair avec tout un tas d'autres fonctions: 751 01:03:03,430 --> 01:03:12,640 fgetc, fgets, getc, getchar, ungetc, et son entrée de caractères et les chaînes. 752 01:03:12,640 --> 01:03:19,180 Voilà donc comment on peut lire en caractères et les chaînes de fichiers à partir de l'entrée standard, 753 01:03:19,180 --> 01:03:21,990 qui est essentiellement de l'utilisateur. 754 01:03:21,990 --> 01:03:24,780 Et c'est ainsi que nous le faisons en effectif C. 755 01:03:24,780 --> 01:03:30,850 Donc, ce n'est pas en utilisant les méthodes GetString et fonctions getchar 756 01:03:30,850 --> 01:03:36,840 que nous avons utilisé à partir de la bibliothèque CS50. 757 01:03:36,840 --> 01:03:39,710 Nous allons faire de ce problème dans un couple des manières 758 01:03:39,710 --> 01:03:43,430 de sorte que vous pouvez voir deux façons différentes de le faire. 759 01:03:43,430 --> 01:03:48,490 Tant la fonction fread que Daniel dit et fgetc sont de bons moyens pour le faire. 760 01:03:48,490 --> 01:03:53,790 Je pense que fgetc est un peu plus facile, car il ne dispose que d', comme vous voyez, 761 01:03:53,790 --> 01:03:59,660 un argument, le FILE * que nous essayons de lire le caractère de, 762 01:03:59,660 --> 01:04:02,740 et sa valeur de retour est un int. 763 01:04:02,740 --> 01:04:05,610 Et c'est un peu déroutant, non? 764 01:04:05,610 --> 01:04:11,450 >> Parce que nous obtenons un personnage, alors pourquoi ne pas ce retour d'un char? 765 01:04:11,450 --> 01:04:18,700 Les gars, vous avez des idées sur le pourquoi cela pourrait ne pas retourner un char? 766 01:04:18,700 --> 01:04:25,510 [Missy réponses, inintelligible] >> Oui. Donc, Missy est tout à fait raison. 767 01:04:25,510 --> 01:04:31,570 Si c'est ASCII, alors cet entier pourrait être associé à un caractère réel. 768 01:04:31,570 --> 01:04:33,520 Peut-être un caractère ASCII, et c'est vrai. 769 01:04:33,520 --> 01:04:36,220 C'est exactement ce qui se passe. 770 01:04:36,220 --> 01:04:39,190 Nous utilisons un int simplement parce qu'il a plus de bits. 771 01:04:39,190 --> 01:04:44,750 C'est plus grand que un char, notre chevalier ne comporte que 8 bits, que 1 octet sur nos machines 32-bits. 772 01:04:44,750 --> 01:04:48,520 Et un int a une valeur toutes les 4 octets de l'espace ». 773 01:04:48,520 --> 01:04:50,940 Et il se trouve que la façon dont fonctionne fgetc, 774 01:04:50,940 --> 01:04:53,940 si nous défiler vers le bas dans notre résumé dans cette page de manuel un peu, 775 01:04:53,940 --> 01:05:05,000 faites défiler la liste vers le bas. Il s'avère qu'ils utilisent cette valeur spéciale appelée EOF. 776 01:05:05,000 --> 01:05:09,640 C'est une constante spéciale que la valeur de retour de la fonction fgetc 777 01:05:09,640 --> 01:05:14,570 chaque fois que vous frappez la fin du fichier, ou si vous obtenez une erreur. 778 01:05:14,570 --> 01:05:18,170 Et il se trouve que pour faire ces comparaisons avec EOF correctement, 779 01:05:18,170 --> 01:05:24,060 vous voulez avoir ce montant supplémentaire de l'information que vous avez dans un int 780 01:05:24,060 --> 01:05:28,420 plutôt que d'utiliser une variable de type char. 781 01:05:28,420 --> 01:05:32,130 Même si fgetc est effectivement d'obtenir un caractère depuis un fichier, 782 01:05:32,130 --> 01:05:38,450 vous voulez vous rappeler qu'il est de retour quelque chose qui est de type int pour vous. 783 01:05:38,450 --> 01:05:41,360 Cela dit, il est assez facile à utiliser. 784 01:05:41,360 --> 01:05:44,960 Ça va nous donner un caractère, donc tout ce que nous avons à faire est de continuer à demander le fichier, 785 01:05:44,960 --> 01:05:48,440 «Donnez-moi le caractère suivant, donnez-moi le caractère suivant, donnez-moi le caractère suivant," 786 01:05:48,440 --> 01:05:51,400 jusqu'à ce que nous arrivons à la fin du fichier. 787 01:05:51,400 --> 01:05:54,730 Et qui va tirer dans un caractère à la fois de notre fichier, 788 01:05:54,730 --> 01:05:56,250 et alors nous pouvons faire ce que nous voulons avec elle. 789 01:05:56,250 --> 01:06:00,160 Nous pouvons stocker, nous pouvons l'ajouter à une chaîne, on peut l'imprimer. 790 01:06:00,160 --> 01:06:04,630 Faire de tout ça. 791 01:06:04,630 --> 01:06:09,600 >> Zoom arrière sur et de revenir à notre programme Cat.C, 792 01:06:09,600 --> 01:06:16,170 si nous allons utiliser fgetc, 793 01:06:16,170 --> 01:06:21,710 comment pourrions-nous aborder cette ligne de code suivante? 794 01:06:21,710 --> 01:06:26,020 Nous allons utiliser - fread fera quelque chose de légèrement différent. 795 01:06:26,020 --> 01:06:32,600 Et cette fois, nous allons juste utiliser fgetc pour obtenir un caractère à la fois. 796 01:06:32,600 --> 01:06:40,910 Pour traiter un fichier entier, que peut-on faire? 797 01:06:40,910 --> 01:06:44,030 Combien de caractères y at-il dans un fichier? 798 01:06:44,030 --> 01:06:47,390 Il ya beaucoup de choses. Donc, vous voulez probablement obtenir un 799 01:06:47,390 --> 01:06:49,860 puis obtenir un autre et obtenir un autre et obtenir un autre. 800 01:06:49,860 --> 01:06:53,330 Quel type d'algorithme pensez-vous que nous pourrions avoir à utiliser ici? 801 01:06:53,330 --> 01:06:55,470 Quel type de -? [Alexander] Une boucle for? >> Exactement. 802 01:06:55,470 --> 01:06:57,500 Certains type de boucle. 803 01:06:57,500 --> 01:07:03,380 Une boucle for est réellement grand, dans ce cas. 804 01:07:03,380 --> 01:07:08,620 Et comme vous le disiez, il semble que vous voulez une boucle sur l'ensemble du dossier, 805 01:07:08,620 --> 01:07:11,820 obtenir un caractère à la fois. 806 01:07:11,820 --> 01:07:13,850 Toutes les suggestions sur ce qui pourrait ressembler? 807 01:07:13,850 --> 01:07:22,090 [Alexander, inintelligible] 808 01:07:22,090 --> 01:07:30,050 Ok >>, dites-moi en anglais ce que vous essayez de faire? [Alexander, inintelligible] 809 01:07:30,050 --> 01:07:36,270 Donc dans ce cas, il semble que nous essayons juste de faire une boucle sur l'ensemble du dossier. 810 01:07:36,270 --> 01:07:45,330 [Alexander] Donc i > -? 811 01:07:45,330 --> 01:07:49,290 Je suppose que la taille du fichier, non? La taille - nous allons simplement écrire comme ça. 812 01:07:49,290 --> 01:07:57,470 Taille du fichier pour le moment, i + +. 813 01:07:57,470 --> 01:08:04,610 Ainsi, il s'avère que la façon dont vous faites cela avec fgetc, et c'est nouveau, 814 01:08:04,610 --> 01:08:10,460 c'est qu'il n'y a pas de moyen facile pour obtenir exactement la taille d'un fichier 815 01:08:10,460 --> 01:08:16,979 avec cette «sizeof» type de construction que vous avez vu avant. 816 01:08:16,979 --> 01:08:20,910 Lorsque nous utilisons cette fonction fgetc, nous introduisons une sorte de 817 01:08:20,910 --> 01:08:29,069 nouvelle syntaxe funky à cette boucle for, où au lieu d'utiliser simplement un compteur de base 818 01:08:29,069 --> 01:08:33,920 aller caractère par caractère, nous allons tirer un caractère à la fois, 819 01:08:33,920 --> 01:08:37,120 un caractère à la fois, et la façon dont nous savons que nous sommes à la fin 820 01:08:37,120 --> 01:08:41,290 n'est pas quand nous avons compté un nombre donné de caractères, 821 01:08:41,290 --> 01:08:49,939 mais quand le personnage nous nous retirons, c'est que la fin particulière de caractères du fichier. 822 01:08:49,939 --> 01:08:58,689 Donc, nous pouvons le faire par - C'est ce que j'appelle ch, et nous allons l'initialiser 823 01:08:58,689 --> 01:09:08,050 avec notre premier appel pour obtenir le premier caractère à partir du fichier. 824 01:09:08,050 --> 01:09:14,979 Donc cette partie ici, cela va avoir un personnage hors du fichier 825 01:09:14,979 --> 01:09:20,840 et le stocker dans le ch variable. 826 01:09:20,840 --> 01:09:25,420 Nous allons continuer à le faire jusqu'à ce que nous arrivons à la fin du fichier, 827 01:09:25,420 --> 01:09:41,170 ce que nous faisons en testant le caractère n'étant pas égale à celle du caractère EOF spéciale. 828 01:09:41,170 --> 01:09:48,750 Et puis, au lieu de faire ch + +, ce qui serait tout simplement incrémenter la valeur, 829 01:09:48,750 --> 01:09:52,710 si nous lisons un sur A du dossier, un A majuscule, par exemple, 830 01:09:52,710 --> 01:09:56,810 ch + + nous donnerait b, puis nous obtiendrions c et d. 831 01:09:56,810 --> 01:09:59,310 Ce n'est clairement pas ce que nous voulons. Ce que nous voulons ici 832 01:09:59,310 --> 01:10:05,830 dans ce dernier bit est que nous voulons obtenir le caractère suivant dans le fichier. 833 01:10:05,830 --> 01:10:09,500 >> Alors, comment pouvons-nous obtenir le caractère suivant dans le fichier? 834 01:10:09,500 --> 01:10:13,470 Comment pouvons-nous obtenir le premier caractère du fichier? 835 01:10:13,470 --> 01:10:17,200 [Étudiants] fgetfile? Fgetc >>, ou, désolé, vous étiez tout à fait raison. 836 01:10:17,200 --> 01:10:20,470 Je l'ai mal orthographié là. Donc, oui. 837 01:10:20,470 --> 01:10:26,240 Ici, au lieu de faire ch + +, 838 01:10:26,240 --> 01:10:29,560 nous allons juste d'appeler fgetc (fichier) nouveau 839 01:10:29,560 --> 01:10:39,180 et stocker le résultat dans notre variable même ml. 840 01:10:39,180 --> 01:10:43,730 [Question étudiants, inintelligible] 841 01:10:43,730 --> 01:10:52,390 >> C'est là que ces gars-là sont spéciaux * FILE. 842 01:10:52,390 --> 01:10:59,070 La façon dont ils travaillent, c'est qu'ils - lorsque vous ouvrez pour la première - quand vous d'abord que l'appel fopen 843 01:10:59,070 --> 01:11:04,260 l'FILE * sert effectivement comme un pointeur vers le début du fichier. 844 01:11:04,260 --> 01:11:12,830 Et puis, chaque fois que vous appelez fgetc, il se déplace d'un personnage à travers le fichier. 845 01:11:12,830 --> 01:11:23,280 Donc, lorsque vous appelez cela, vous êtes en incrémentant le pointeur de fichier par un caractère. 846 01:11:23,280 --> 01:11:26,210 Et quand vous fgetc encore une fois, vous vous déplacez un autre caractère 847 01:11:26,210 --> 01:11:28,910 et un autre caractère et un autre caractère et un autre caractère. 848 01:11:28,910 --> 01:11:32,030 [Question étudiants, inintelligible] >> Et C'est - oui. 849 01:11:32,030 --> 01:11:34,810 C'est un peu de cette magie sous le capot. 850 01:11:34,810 --> 01:11:37,930 Vous continuerait d'incrémenter travers. 851 01:11:37,930 --> 01:11:46,510 À ce stade, vous êtes en mesure de travailler effectivement avec un personnage. 852 01:11:46,510 --> 01:11:52,150 Alors, comment pouvons-nous imprimer ceci à l'écran, maintenant? 853 01:11:52,150 --> 01:11:58,340 Nous pouvons utiliser la même chose printf que nous avons utilisé auparavant. 854 01:11:58,340 --> 01:12:00,330 Que nous avons utilisé tout le semestre. 855 01:12:00,330 --> 01:12:05,450 Nous pouvons appeler printf, 856 01:12:05,450 --> 01:12:21,300 et on peut passer dans le caractère juste comme ça. 857 01:12:21,300 --> 01:12:27,430 Une autre façon de le faire est plutôt que d'utiliser printf et d'avoir à faire cette chaîne de format, 858 01:12:27,430 --> 01:12:29,490 on peut aussi utiliser l'une des autres fonctions. 859 01:12:29,490 --> 01:12:40,090 Nous pouvons utiliser fputc, qui imprime un caractère à l'écran, 860 01:12:40,090 --> 01:12:52,580 sauf si l'on regarde fputc - permettez-moi de faire un zoom arrière un peu. 861 01:12:52,580 --> 01:12:56,430 Nous voyons ce qui est bien c'est qu'il prend dans le caractère que nous avons lu à l'aide d'fgetc, 862 01:12:56,430 --> 01:13:05,100 mais alors il faut lui donner un flux d'imprimer. 863 01:13:05,100 --> 01:13:11,850 Nous pouvons également utiliser la fonction putchar, qui mettra directement à la sortie standard. 864 01:13:11,850 --> 01:13:16,070 Donc, il ya tout un tas d'options différentes que nous pouvons utiliser pour l'impression. 865 01:13:16,070 --> 01:13:19,580 Ils sont tous dans la norme E / S de la bibliothèque. 866 01:13:19,580 --> 01:13:25,150 Chaque fois que vous voulez imprimer - afin printf, par défaut, permet d'imprimer à la norme spéciale sur cours d'eau, 867 01:13:25,150 --> 01:13:27,910 qui est ce que stdout. 868 01:13:27,910 --> 01:13:41,300 Ainsi, nous pouvons simplement se référer à lui comme type de cette valeur magique, stdout ici. 869 01:13:41,300 --> 01:13:48,410 Oops. Placez le point-virgule à l'extérieur. 870 01:13:48,410 --> 01:13:52,790 >> C'est beaucoup de nouvelles informations géniale ici. 871 01:13:52,790 --> 01:13:58,600 Beaucoup de ce qui est très idiomatique, dans le sens où il s'agit du code 872 01:13:58,600 --> 01:14:05,700 ce qui est écrit de cette façon simplement parce que c'est propre à lire, facile à lire. 873 01:14:05,700 --> 01:14:11,520 Il ya beaucoup de façons différentes de le faire, de nombreuses fonctions que vous pouvez utiliser, 874 01:14:11,520 --> 01:14:14,680 mais nous avons tendance à vous suffit de suivre ces mêmes modèles à plusieurs reprises. 875 01:14:14,680 --> 01:14:20,180 Alors ne soyez pas surpris si vous voyez un code comme celui à venir encore et encore. 876 01:14:20,180 --> 01:14:25,690 Très bien. À ce stade, nous avons besoin de faire une pause pour la journée. 877 01:14:25,690 --> 01:14:31,300 Merci d'être venu. Merci de regarder si vous êtes en ligne. Et nous nous reverrons la semaine prochaine. 878 01:14:31,300 --> 01:14:33,890 [CS50.TV]