[Powered by Google Translate] Problème Section Set 2: Edition Hacker Rob Bowden, Harvard University C'est CS50. CS50.TV Donc, je suis Rob. Je suis un aîné à Kirkland. C'est ma troisième année TFing CS50. C'est la première fois que nous changeons de la section traditionnelle conférence de style, où nous venons genre d'examen ce qui s'est passé dans la conférence, puis vous les gars poser des questions, maintenant à être beaucoup plus axée sur les problèmes, où nous utilisons les espaces, et - Ah, si l'idée est d'aller à ce lien que je vous envoie et vous serez dans mon espace. Quelqu'un at-il pas un ordinateur portable? D'accord. Donc, nous allons utiliser cela, et nous allons faire vivre des problèmes dans la section et d'en discuter et de déterminer ce qui ne va pas et je pourrais tirer vers le haut une partie de votre code, et je pourrais discuter de vos idées. Donc, toute personne a eu de la difficulté? Vous pouvez discuter sur le côté, je ne sais pas si nous avons des raisons pour cela. Maintenant, comme le supersection précédente, si vous étiez à cette classe, vous savez de quoi il s'agit. Sur l'ensemble des séries P il va y avoir ces sections. Donc P-série 2, cahier des charges, je suppose que vous l'avez vu sur P-1 déjà ensemble. Mais nous pouvons regarder ensemble P-2 pour ce que nous allons aller plus aujourd'hui. Et vous verrez une section de questions. Donc, ce sera dans tous les P-ensembles, il y aura une section de questions. Jusqu'ici, nous avons dit: «Considérez ce l'occasion de pratiquer." Vous ne serez pas invité à présenter ce programme. L'idée est que ceux-ci sont censés sorte de vous aider à démarrer avec le problème posé. Je suppose que sur l'édition Hacker, beaucoup d'entre eux sont censés être simplement de nouvelles choses intéressantes à apprendre. Ils ne peuvent pas être directement applicables au problème posé. Et en ce moment nous ne sommes pas vous avoir les soumettre, mais en théorie, pour ensembles de problèmes plus tard, vous pouvez les soumettre, et donc vous pouvez venir à la section ou regarder la section pour obtenir les réponses, ou vous pouvez simplement les mettre sur votre propre si vous n'avez pas envie de profiter de ma présence. Ainsi, le - je pense que c'est la première. Oh. En outre, en vertu de ces sections de questions que nous vous l'avons déjà poser des questions sur le short. Donc je suppose que, en théorie, vous êtes censé regarder ces avant de venir à la section, mais c'est bien si vous ne faites pas, nous allons passer en revue toute façon. Ainsi, nous pouvons commencer par celles-ci: "Comment ça une boucle while diffèrent d'une boucle do-while? Lorsque celle-ci est particulièrement utile? " Donc, n'importe qui a une -? [Étudiants] La boucle do-while s'exécute toujours au moins une fois. Oui. Donc, c'est la différence. Une boucle while - je vais juste le faire ici - boucle while, nous avons la condition ici, alors qu'un do-while, vous n'avez pas une condition jusqu'à ce que nous obtenons ici-bas. Ainsi, lorsque votre programme est exécuter, et il arrive à la boucle while, il vérifie immédiatement si cette condition est vraie. Si cette condition n'est pas vrai, il suffit de sauter sur la boucle entièrement. Boucle do-while, car le programme est exécuté, il arrive au «faire». Rien ne se passe en ce moment, continue simplement d'exécution. Puis, quand il frappe le «tout», si la condition est vraie, ça boucle arrière et le faire à nouveau et encore et encore jusqu'à ce que la condition n'est pas vraie, puis tombe juste à travers. Donc, la différence étant que cela peut aller directement dès le début. Cette commande exécute nécessairement une fois et peut ensuite exécuter plusieurs fois si la condition est toujours vraie. Ainsi, la boucle while ne faire qu'une seule fois, ou - la boucle while - nous ne pouvons pas besoin de le faire du tout, car dès que nous y arriverons, si la condition est fausse, nous allons juste aller directement sur elle. Alors que boucle do-while, nous l'exécuterons une fois, forcément. Puis, lorsque nous arriverons à la condition, nous vérifions si c'est vrai ou faux. Si c'est vrai, nous le ferons à nouveau, si elle est fausse, nous allons continuer à aller. Ainsi, lorsque celui-ci est particulièrement utile? Donc, je peux dire que dans l'ensemble des 4 ans, 3 ans, peu importe, que j'ai été la programmation, j'ai utilisé ça, comme, de moins de 10 fois. Et probablement 5 d'entre eux sont en CS50 lorsque nous introduisons boucles do-while. Alors quand pensez-vous utilisé boucles do-while? Quel est le - ouais? [Étudiants] Lorsque vous essayez d'obtenir une entrée utilisateur, ou quelque chose que vous souhaitez vérifier - Ouais. Donc boucles do-while, l'utilisateur d'entrée est le grand. C'est pourquoi les premières séries de problèmes de couple, si vous voulez demander à l'utilisateur, comme, «Donnez-moi une corde," vous ne pouvez pas continuer jusqu'à ce que vous obtenez cette chaîne. Et si vous, nécessairement, doivent demander la chaîne au moins une fois. Mais alors, si ils répondent quelque chose de mauvais, alors vous devez faire une boucle en arrière et demander à nouveau. Mais à part de l'utilisateur, il est très rare que je rencontre un cas là où je veux en boucle "au moins une fois", mais peut-être plus. Questions ou -? Quelqu'un at-il utilisé une boucle do-while ailleurs? D'accord. Donc, la prochaine est: «Qu'est-ce que non déclarés identifiant indiquent généralement si délivrée par clang? " Alors, quel genre de code que je pourrais écrire pour obtenir 'identificateur non déclaré? [Étudiants] Cela x = 2? Ainsi, nous pouvons juste essayer ici, x = 2. Nous allons exécuter ce - oh, je n'ai pas cliquer dessus. Donc, ici nous arrivons - tous droits. "L'utilisation de x identificateur non déclaré». Donc, c'est l'identificateur non déclaré, une variable. Il sera souvent appeler une variable d'un identifiant. Ainsi, il pourrait ne pas savoir qu'il s'agit en fait d'une variable, il ne sait pas ce que c'est. Donc, c'est un identifiant. Alors, pourquoi est-il non déclarée? Ouais. Donc, pour être clair sur la terminologie, la déclaration d'une variable c'est quand vous dites "int x" ou "y", chaîne de quoi que ce soit. L'initialisation de la variable ou l'affectation de la variable, est chaque fois que vous dites "x = 2." Ainsi, nous pouvons les faire dans des étapes séparées, int x, x = 2, et jusqu'à ce que - nous pouvons avoir un tas de trucs ici - mais jusqu'à ce que cette ligne passe, x est toujours pas initialisé, mais elle a été déclarée. Et si on peut évidemment le faire en 1 ligne, et maintenant nous sommes déclaration et l'initialisation. Des questions? Et enfin, «Pourquoi le chiffrement de César pas très sûr?" Alors d'abord, personne ne veut dire ce que le chiffre de César est? [Étudiants] Caesar Cipher est juste que vous mappez, vous passez chaque lettre, un certain nombre de lettres dépasser, et de revenir plus, et ce n'est pas très sûr, car il n'y a que 26 options possibles et vous avez juste à essayer chaque 1 de ceux que vous l'obtenez. Oh. Donc, je le répète? Le chiffre de César, C'est - je veux dire, vous aurez affaire avec lui sur les problèmes que vous - ou je suppose que l'édition standard du jeu de problème, ce n'est pas sur l'édition pirate. Ainsi, sur l'édition standard au problème posé, vous obtenez un message du type: "Bonjour, monde», et vous avez également un certain nombre comme 6, et que vous prenez ce message, et chaque caractère, vous le faire pivoter en 6 positions dans l'alphabet. Ainsi, le 'h' de bonjour deviendrait h-i-j-k-l-m-n. Donc, la première lettre serait n. Nous faisons la même chose avec e. Si nous avons un, comme, z ou quelque chose, alors nous envelopper arrière autour de «une». Mais chaque personnage a recyclé 6 caractères loin dans l'alphabet, et il n'est pas très sûr car il ya seulement 26 possibilités de combien de façons que vous pouvez envelopper une seule lettre. Ainsi, vous pouvez juste essayer tous les 26 d'entre eux et, sans doute, pour un message assez long, 1 seul de ces 26 choses possibles va être lisible, et le lisible va être le message d'origine. Donc ce n'est pas une très bonne façon de chiffrer quoi que ce soit. Indépendamment de ces courts métrages, «Qu'est-ce qu'une fonction?" Alors qu'est-ce qu'une fonction? Oui. [Étudiants] C'est comme un morceau de code que vous pouvez appeler pour passer et ensuite obtenir la valeur de retour de la chose. Ouais. Donc, je vais y répondre en répondant aussi à l'autre - ou de répétition en outre que répondre à la suivante. Vous pouvez utiliser les fonctions au lieu de simplement copier et coller le code maintes et maintes fois. Il suffit de prendre ce code, le mettre dans un fuction, et alors vous pouvez appeler la fonction où vous avez été un copier-coller. Ainsi, les fonctions sont utiles. Alors maintenant, nous ferons des problèmes réels. La première. Donc, l'idée de la première, c'est que vous passez une chaîne, et quel que soit le - ou faut-il dire tout en minuscules? Il ne dit pas tout en minuscules. Donc, le message peut être n'importe quoi, et - oh non. C'est le cas. "Pour plus de simplicité, vous pouvez supposer que l'utilisateur aura seulement l'entrée des lettres minuscules et les espaces." Donc, nous lui passer un message avec uniquement des lettres minuscules, puis nous alternons entre le capital et les minuscules - nous changer la chaîne pour être la capitale et les minuscules, en alternance. Donc, avant de vous donner une seconde à plonger dans le même problème, quelle est la première chose que nous devons faire? Oh, qu'est-ce que je viens de cliquer sur? Oh, j'ai juste cliqué sur un e-mail ici. Donc la première chose que nous devons faire - je regarde la mauvaise? Est-ce une partie de celle-ci? Non, ceux qui sont toujours là, cependant. Bon, encore ici. Maintenant, nous ne pouvons pas assumer -? Oui. Ici, nous ne pouvons pas supposer que c'est seulement en minuscules et les espaces. Alors maintenant, nous devons composer avec le fait que les lettres peuvent être tout ce que nous voulons qu'ils soient. Et la première chose que nous voulons faire est de simplement faire passer le message. Nous avons juste besoin d'obtenir un string, string s = GetString, d'accord. Maintenant ce problème, il ya deux façons de le faire. Mais nous allons vouloir utiliser les opérateurs binaires ici. Y at-il des gens qui soit ne sont pas à la supersection, ou quelque chose, et ne savent pas ce que les opérateurs bit à bit sont? Ou comment ils se rapportent à l'ASCII en aucune façon? [Étudiants] je n'étais pas à la supersection, mais je sais ce que les opérateurs bit à bit sont. D'accord. Alors je n'ai pas à revenir sur les bases d'entre eux, mais je vais vous expliquer ce que nous allons avoir à utiliser ici. Donc «A»: la représentation binaire du capital A, le nombre est de 65. Je vais regarder - 41 va être 01000001. Ce qui devrait être de 65 en décimal; c'est donc la représentation binaire de la capitale caractère A. Maintenant, la représentation binaire du caractère minuscule «a» va être la même chose, ou presque. Est-ce que - 6, ouais. Ce qui est juste. Ainsi, le capital binaire A minuscules, binaire «un». Donc remarquer que la différence entre A et 'a' est-ce un seul bit. Et il se trouve que le 32 bits, le bit représentant le nombre 32. Et c'est logique puisque A est de 65; 'a' est 97. La différence entre les deux est de 32. Alors maintenant, nous savons que nous pouvons convertir de A à 'a' en prenant un et il ORing bit, avec - qui ressemble à un 1. Il s'agit d'une opération de bits OR, avec 00100000, et qui va nous donner «un». Et nous pouvons obtenir de 'a' à A par bit AND avec 11, 0 à cet endroit, 11111. Donc, ce sera ensuite nous donner exactement ce que 'a' est, mais annuler ce bit individuel, alors nous aurons 01000001; je ne sais pas si j'ai bien compté droite. Mais cette technique de bit à bit pour obtenir du capital en minuscules, et au niveau du bit AND pour obtenir de minuscules en capital n'est pas exclusif à A. Toutes les lettres, K vs K, Z vs z, chacun d'entre eux vont juste diffèrent par ce seul bit. Et si vous pouvez l'utiliser pour passer d'une lettre minuscule à une majuscule et vice-versa. D'accord. Donc, un moyen facile d'obtenir à partir de ce - au lieu d'avoir à écrire quelque 1011111 est - un moyen facile de représenter ce nombre, et ce n'est pas un que je suis allé dans le supersection, mais tilde (~) est un autre opérateur de bits. Qu'est-ce ~ fait est qu'il regarde la représentation binaire. Prenons n'importe quel nombre. Ceci est juste un nombre binaire, et qu'est-ce que ~ est le retourne simplement tous les bits. Donc, ce fut un 1, un 0 aujourd'hui, c'est un 0, maintenant un 1, 010100. Donc, c'est tout ~ fait. Donc 32 est va être le nombre - se débarrasser de ce - si 32 est va être le numéro 00100000, et ainsi de ~ de ce qui se passe à ce nombre ici que je ANDed 'a' avec. Est-ce que tout le monde voit que? C'est assez commun, comme quand vous voulez comprendre pour des choses plus tard que nous pourrions voir, quand nous voulons voir si - ou nous voulons tout, chaque bit unique, sauf pour 1 vous avez tendance à ne ~ du bit que nous ne voulons pas réglé. Donc, nous ne voulons pas le bit 32, donc nous n'avons ~ de 32 ans. D'accord. Nous pouvons donc utiliser tous ceux qui sont ici. D'accord, c'est très bien si vous n'avez pas fini, nous allons marcher lentement au cours ensemble, ou marcher sur cela, donc - à travers cela. Promenade à travers cela. Donc, nous avons notre chaîne, et nous voulons faire une boucle sur chaque caractère dans cette chaîne et faire quelque chose pour elle. Alors, comment avons-nous une boucle sur une chaîne? Que devrions-nous utiliser? Je ne vais pas le faire ici. Ouais. Donc j'ai mon itérateur, et il l'a dit, mais comment puis-je savoir combien de caractères sont dans la chaîne? Strlen (s), puis i + +. Alors qu'est-ce que j'ai fait ici n'est pas la meilleure façon de faire les choses. Est-ce que quelqu'un sait pourquoi? Parce que vous vérifiez la langue de la chaîne à chaque fois. Donc, nous allons vouloir bouger strlen, je pourrais dire ici, int length = strlen (s), et puis ne i > 1 bit. Il pourrait être plus que 1 bit, aussi longtemps que tous les bits inférieurs à ce poste sont les mêmes. Nous avons donc besoin d'au moins 26 caractères - ou, il ya 26 caractères. Nous avons donc besoin d'au moins 26 chiffres pour représenter la différence - La différence entre A et "a" doit être d'au moins 26, sinon nous n'aurions pas représenté tous les numéros de capitaux. Cela signifie que A, si nous commençons à 1, il va utiliser tous ces bits, l'ensemble de ces 5 premiers bits, pour représenter tout à Z. C'est pourquoi le bit suivant, ou ce bit, le bit suivant est celui qui a choisi de faire la distinction entre A et «un». C'est aussi pourquoi, dans le tableau ASCII, il ya 5 symboles qui séparent les majuscules des minuscules. Puisque ce sont les symboles, les 5 supplémentaire qui ouvre le 32 étant la différence entre eux. [Étudiants] Donc, nous pourrions le faire, parce ASCII est conçu comme ça. Oui. Mais ASCII - la différence pourrait aussi être à la fois de ces bits. Comme, si A 10000001, et «a» est 11100001 - je ne sais plus, peu importe. Mais si c'était cela, alors nous pourrions toujours utiliser 'a' - A. C'est tout à l'heure la différence entre A et «a» est toujours ces 2 bits. Je pense que c'est écrit 48. Est-il 32 + 64? Je pense qu'il est? Il serait encore 2 bits; chaque personnage, comme, Z et z, K et k, ils ont toujours les mêmes bits exactes fixées à l'exception des 2 bits. Donc, tant que c'est toujours le cas, peu importe si nous utilisons ASCII ou un autre système, tant qu'il n'y a qu'un nombre un ensemble de bits qui sont différentes pour chaque caractère, puis qui fonctionne très bien. C'est juste que 32 a été mis en place parce que c'est la première que nous pourrions peut-être utiliser. >> Cool. J'ai tendance à préférer, dans le cas où vous n'avez pas vu, si le bloc est une seule ligne, vous pouvez vous débarrasser des accolades, donc j'ai tendance à préférer le faire. Aussi, vous savez comment nous pouvons faire des choses comme s [i] + = 1? Vous pouvez également faire s [i] = 32 ET bit à bit. Et bit à bit OU = 32. En outre, compte mod 2 == 0. Alors, n'oubliez pas que - je ne vais pas écrire - n'importe quelle valeur non nulle est vraie, et 0 est faux. Ainsi, «si nombre de mod 2 == 0" est la même chose que dire "si pas compter mod 2." J'aurais probablement juste inversé les lignes et a dit, "si le nombre de mod 2, ne l'OR 1, sinon ne l'ET 1 », de sorte que je n'ai pas besoin du" non ". Mais cela fonctionne tout aussi bien. Et qu'est-ce que je peux faire ici? Vous pouvez les combiner avec ternaire si vous voulez, mais alors que venait de rendre les choses plus désordonné et sans doute plus difficile à lire, donc nous ne ferons pas cela. Quelqu'un at-il d'autres suggestions? Est-ce que tout le problème demandé? Oh yeah. Ainsi se débarrasser de ces lignes vides, maintenant nous allons imprimer f,% s étant celui pour cordes, Nous imprimons f, s. Maintenant, nous allons l'exécuter. Ai-je fait quelque chose de mal? C'est un \ "; Je veux un n. D'accord. Maintenant, nous allons l'exécuter. Il va probablement me crier dessus. Strlen est dans string.h. Donc, c'est la bonne chose à propos Clang est-ce que vous dit ce que c'est dans, au lieu de GCC qui dit simplement: «Hé, vous avez oublié quelque chose, je ne sais pas ce que c'était." Mais cela va me dire: «Vous vouliez inclure string.h." Je n'ai donc pas demander quoi que ce soit, il ne dit rien. Mais nous ferons leur exemple, «Merci 4 the add". Cela ressemble à droite. Hourra. Donc, retour à votre main, je n'ai presque jamais le faire. Il est facultatif. Et principale est la seule fonction pour laquelle il est facultatif. Si vous ne retournez pas quelque chose de principal, il est supposé que vous vouliez retourner 0. Des questions? D'accord. Alors maintenant, le deuxième problème. "Rappel de conférence seconde 2 semaine que l'échange des valeurs 2 variables» en passant ces 2 variables dans une fonction (même si elle est appelée swap) n'est pas exactement le travail, du moins pas sans «pointeurs». Et ignorer pointeurs jusqu'à arriver à eux. Nous voulons échanger 2 variables; nous ne sommes pas en utilisant une fonction pour le faire. Nous allons encore le faire en principal comme il est dit. Mais pour utiliser ces 2 variables, nous ne voulons pas d'utiliser une variable temporaire. Il ya 2 façons de le faire. Vous pouvez le faire en utilisant vos opérateurs binaires traditionnelles. Il en va de quelqu'un connait un moyen rapide et sale de le faire? Il pourrait en fait prendre une minute de réflexion. Si je dois - Je vais régler le problème vers le haut comme ce qu'ils demandent. Donc, si j'ai 2 variables A, qui est juste un nombre entier qu'ils me donnent, et la variable B la somme, ce qui est un autre entier que je me donne. Donc, si j'ai ces 2 variables, maintenant je veux les échanger. Le traditionnel, en utilisant vos opérateurs binaires régulières, je veux dire, comme +, -, ÷. Pas opérateurs de bits qui agissent sur binaire. Donc, en utilisant -, +, ÷, et tous ceux. Nous pourrions échanger en faisant quelque chose comme a = a + b et b = a - b, a = a - b. Donc, vérification de cohérence, et puis nous verrons pourquoi cela fonctionne. Disons que a = 7, b = 3, alors a + b va être 10. Nous sommes donc en train de mettre a = 10, puis nous faisons b = a - b. Nous faisons donc b = a - b, qui va être 7 et b = a - b nouveau, ou a = a - b. Qui va être de 10 - 7, qui est de 3. Alors maintenant, à juste titre, «a» était de 7, b est de 3, et maintenant b est 7 et «a» est de 3. Donc, ce genre de logique; «a» est la combinaison des 2 chiffres. À ce stade, «a» est la combinaison, puis nous soustrayant à l'origine b, puis nous soustraire à ce qui était l'original «un». Mais cela ne fonctionne pas pour tous les numéros. Pour le voir, considérons un système, de sorte que nous pensons habituellement que des entiers 32 bits. Nous devons travailler sur quelque chose qui n'est que comme 4 bits. J'espère trouver un bon exemple en ce moment. Alors, je sais, ce sera facile. Disons que nos 2 chiffres sont 1111, et 1111, de sorte que nous sommes en binaire en ce moment. En décimales réelles, si vous voulez penser de cette façon, une. = 15 et b = 15 Et nous nous attendons donc, après que nous les échanger - ils n'ont même pas besoin d'être les mêmes numéros, mais je l'ai fait de cette façon. Laissons-les faire pas les mêmes numéros. Faisons 1111 et 0001. Donc a = 15 et b = 1. Après que nous les échanger, nous nous attendons à 'a' à 1 et b à 15. Donc, notre première étape consiste a = a + b. Nos chiffres sont seulement 4 bits de large, donc «une», qui est 1111, + b, qui est 0001, va finir par être 10000, mais nous n'avons que 4 bits. Alors maintenant, a = 0. Et maintenant, nous voulons mettre en b = a - b - en fait, ça fonctionne toujours parfaitement. a = a - nous allons voir si cela fonctionne parfaitement - b. Alors b = 0 - 1, ce qui serait encore 15 ans, et alors a = a - b, qui serait 1. Peut-être que cela ne fonctionne. J'ai l'impression qu'il ya une raison, il ne fonctionne pas à l'aide régulière. Ok, donc de l'hypothèse qu'il ne fonctionne pas avec les opérations binaires régulières, et je chercherai - je vais sur Google pour voir si c'est vrai. Donc, nous voulons le faire en utilisant les opérateurs binaires, et l'idée ici est XOR. Ainsi, l'introduction XOR (^) si vous ne l'avez pas encore vu. C'est, encore une fois, un opérateur de bits de sorte qu'il agit peu à peu, et C'est - Si vous avez les bits 0 et 1, puis ce sera 1. Si vous avez les bits 1 et 0, ce sera 1, vous avez les bits 0 et 0 ça va être 0, et si vous avez les bits 1 et 1, ce sera 0. Donc, c'est comme OR. Si l'un des bits sont vraies, c'est 1, mais à la différence OU, il ne peut pas être les deux bits qui sont vraies. OU aurait-il être 1, XOR aurait cet être égal à 0. Donc, nous allons avoir à utiliser XOR ici. Pensez-y une minute, je vais à Google. Eh bien, vous ne pouvez pas lire cela, je suis actuellement sur la page algorithme XOR swap. J'espère que cela va vous expliquer pourquoi je ne peux pas - C'est exactement l'algorithme que nous venons de faire. Je ne vois toujours pas pourquoi - je devais avoir juste pris un mauvais exemple, mais ce cas où «a» est arrivé à devenir 0, après avoir obtenu de 5 bits, alors maintenant 'a' est 0, c'est ce que l'on appelle "integer overflow". Selon Wikipedia, «Contrairement à l'échange XOR, cette variation exige qu'il utilise des méthodes de garantir que x + y ne provoque pas un dépassement d'entier. " Donc, cela ne rencontrez des problèmes, ce qui était débordement d'entier, mais je l'ai fait quelque chose de mal. Je ne suis pas sûr. Je vais essayer de trouver un autre. [Étudiants] Eh bien, ce n'est pas de dépassement d'entier lorsque vous essayez de mettre un numéro en y plus grand que le nombre de bits que vous avez alloué? Ouais. Nous disposons de 4 bits. C'est - nous avons eu 4 bits, nous puis essayez d'ajouter 1 pour l', donc on se retrouve avec 5 bits. Mais le cinquième bit obtient juste coupé, oui. Il pourrait en fait - [Étudiants] Est-ce que vous jeter une erreur, ou est-ce que - ce que cela génère une erreur? Non Il n'y a donc pas d'erreur. Lorsque vous arrivez au niveau de l'assemblage, un peu spécial est mis quelque part que dit qu'il y avait un débordement, mais en C, vous sorte de juste ne pas s'en occuper. En fait, vous ne pouvez pas traiter avec elle sauf si vous utilisez des instructions de montage spécifiques à C. Pensons échange XOR. Et je pense que l'article de Wikipédia aurait également pu dire que - Ainsi, il a également évoqué l'arithmétique modulaire, donc je suppose que j'ai été, en théorie, faire de l'arithmétique modulaire quand j'ai dit que 0 à 1 est de 15 fois. Alors que pourrait en fait - sur un processeur régulière qui passe de 0 - 1 = 15. Depuis nous nous retrouvons à 0, nous soustrayons 1, donc il termine tout juste de retour autour de 1111. Donc cet algorithme pourrait en fait travailler, l'a + b, l'a - b, b - a, c'est peut-être bien. Mais il ya certains processeurs qui ne font pas cela, et il ne serait pas bien dans les plus spécifiques. Échange XOR fonctionne sur n'importe quel processeur. D'accord. L'idée est que c'est censé être le même, cependant. Où sommes-nous en utilisant XOR en quelque sorte à obtenir l'information à la fois dans 1 des variables, puis extraire les informations des variables individuelles nouveau. Il en va de ce que quelqu'un a des idées / la réponse? [Réponse de l'étudiant, inintelligible] Donc, cela devrait fonctionner, et aussi, XOR est commutatif. Quel que soit l'ordre dans lequel ces 2 numéros se trouvent dans là-haut, ce résultat sera le même. Donc a ^ b ^ b est un. Vous pouvez également voir ce écrit comme a ^ = b, b ^ = a, a ^ = b à nouveau. Donc, cela est juste, et de voir comment cela fonctionne, pense que des bits. L'utilisation d'un nombre assez petit, disons 11001, et 01100. C'est donc «a», ce qui est b. Donc a ^ = b. Nous allons être mise en 'a' = au XOR de ces 2 choses. Si une ^ 0 est égal à 1; 1 ^ 1 est égal à 0; 0 ^ 1 est 1, et 0 ^ 0 est égal à 0; 1 ^ 0 est égal à 1. Ainsi, 'a,' si vous regardez le nombre décimal, il va y avoir - vous n'allez pas voir grand-chose d'une relation entre l'original «a» et le nouveau 'a,' mais en regardant les bits, 'a' est maintenant comme un maillage de l'information à la fois de l'original 'a' et b l'original. Donc, si nous prenons b ^ a, nous voyons que nous finirons à l'original 'a.' Et si nous prenons l'original 'a' ^ la nouvelle 'a,' nous voyons nous nous retrouvons à l'origine b. Donc (a ^ b) = b ^ l'original «un». Et (a ^ b) ^ a = b l'original. Il ya - une autre façon de voir cela est XOR quoi que ce soit lui-même est toujours 0. Donc 1101 ^ 1101, tous les bits vont être les mêmes. Donc, il ne va jamais être un cas où 1 est un 0 et l'autre est 1. Donc, c'est 0000. La même chose avec cela. (A ^ b) ^ b est comme a ^ (b ^ b). (B ^ b) va être égal à 0, un ^ 0 va tout simplement être «un», puisque tous les bits sont à 0. Donc, les seuls qui vont être là où «a» était à l'origine un 1 - avait les. Et la même idée ici, je suis sûr que c'est aussi commutative. Ouais. J'ai dit avant que c'était commutative. Le ^ 'a,' et il est associative, alors maintenant (b ^ a) ^ a. Et nous pouvons faire b ^ (a ^ a). Et à nouveau, on obtient le b originale. Ainsi, 'a' est maintenant la combinaison de 'a' et b ensemble. Grâce à notre nouveau combo 'a' nous disons b = combo 'a' ^ b l'origine, nous obtenons l'original «un». Et maintenant, un combo = 'a' ^ b la nouvelle, qui était l'original - ou qui est maintenant ce qui était 'a' ou b. C'est le cas ici. Il s'agit d'= b, b ancienne. Alors maintenant, tout est rentré dans l'ordre permuté. Si nous avons effectivement examiné les bits b = a ^ b, va XOR ces 2, et la réponse va être présent, et alors a = a ^ b est XOR ces 2 et la réponse est la suivante. Des questions? D'accord. Donc, le dernier est un peu beaucoup plus difficile. [Étudiants] Je pense qu'il a un doute à ce sujet. >> Oh, désolé. [Étudiants] Quelle est vraiment le plus rapide? Si vous utilisez cette XOR, ou est-il si vous déclarez une nouvelle variable? Alors, quel est vraiment le plus rapide, la déclaration d'une nouvelle variable ou en utilisant XOR pour échanger? La réponse est, selon toute vraisemblance, une variable temporaire. Et c'est parce qu'une fois qu'il est compilé vers le bas - donc au niveau de l'assemblage, il n'y a aucune une telle chose comme des variables locales ou des variables temporaires ou tout ce genre de choses. Ils sont comme - il ya la mémoire, et il existe des registres. Les registres sont là que les choses sont activement passe. Vous n'ajoutez pas 2 choses en mémoire, vous ajoutez 2 choses dans les registres. Et vous apporter des choses à partir de la mémoire dans les registres pour ensuite les ajouter, et alors vous pourriez les remettre en mémoire, mais toute l'action se passe dans les registres. Ainsi, lorsque vous utilisez l'approche variable temporaire, le plus souvent ce qui arrive est ces 2 numéros sont déjà dans les registres. Et puis, à partir de ce moment, après les avoir échangées, ça va juste commencer à utiliser l'autre registre. Partout où vous avait été l'aide de b, il vous reste plus qu'à utiliser le registre qui a été déjà stockage 'un. Donc, il n'a pas besoin de faire quelque chose de réellement faire le swap. Ouais? [Étudiants] Mais il faut aussi plus de mémoire, non? Cela ne prendra que plus de mémoire si elle a besoin de stocker cette variable temporaire. Comme si plus tard vous utilisez cette variable temporaire à nouveau quelque part, ensuite - ou que vous affectez quelque chose à cette variable temporaire. Donc, si à n'importe quel point dans le temps 'a,' b dans temp ont des valeurs distinctes ou quelque chose, alors il va avoir des endroits distincts dans la mémoire, mais il est vrai que il ya beaucoup de variables locales qui existent uniquement dans les registres. Dans ce cas, il n'a jamais mis en mémoire, et ainsi vous n'êtes jamais perdre la mémoire. D'accord. Une dernière question est un peu plus. Donc, ici, dans cet appareil CS50, il ya un dictionnaire. Et la raison en est que [? B66] est un correcteur orthographique où vous devrez écrire en utilisant les tables de hachage ou tente ou une structure de données. Vous allez être écrit un correcteur orthographique, et que vous allez utiliser ce dictionnaire pour le faire. Mais pour ce problème, nous allons nous contenter de regarder pour voir si un mot est dans le dictionnaire. Donc, au lieu de stocker l'ensemble du dictionnaire dans une structure de données puis regarder par-dessus un document entier pour voir si quelque chose a mal orthographié, nous voulons juste trouver 1 mot. Ainsi, nous pouvons simplement numériser sur l'ensemble du dictionnaire et si nous ne trouvons jamais le mot dans l'ensemble du dictionnaire, il n'était pas là. Si nous numérisons sur l'ensemble du dictionnaire et je vois le mot, puis nous sommes bons, nous l'avons trouvé. On dit ici que nous voulons commencer à regarder C de fichiers fonction de gestion, depuis que nous avons envie de lire le dictionnaire, mais je vous donne l'astuce ici pour les fonctions auxquelles vous devez penser. Je vais les écrire sur les espaces. Ainsi, les principaux que vous aurez envie de regarder à f sont ouverts, puis, inévitablement, f fermé, qui ira à la fin de votre programme, et f balayage f. Vous pouvez aussi utiliser f lire, mais vous ne voulez probablement pas à parce que - vous ne finissent pas par avoir besoin de ça. F balayage f est ce que vous allez utiliser pour numériser sur le dictionnaire. Et si vous n'avez pas besoin de coder la solution, juste essayer et comme pseudo-code à votre façon à une solution, puis nous en discuterons. Et en fait, depuis que je vous ai déjà donné ceux-ci, si vous allez dans n'importe quel terminal ou shell de votre appareil, Je voudrais - J'ai l'habitude - si vous n'avez pas encore vu, je ne sais pas si vous l'avez fait en classe, mais l'homme, de sorte que les pages de manuel, sont très utiles pour regarder à peu près n'importe quelle fonction. Donc, je peux faire, comme, f homme, balayage f. C'est aujourd'hui le plus sur la famille de fonctions f balayage. Je pourrais aussi faire f homme, ouvert, et que vous me donner les détails de cette. Donc, si vous savez quelle est la fonction que vous utilisez, ou que vous lisez le code et vous voyez une fonction et vous êtes comme, "Qu'est ce que cela fait?" Tout nom de la fonction que l'homme. Il ya quelques exemples bizarres où vous pourriez avoir à dire le souhaitez. man 2 que le nom de la fonction ou le man 3 que le nom de la fonction, mais vous n'avez qu'à faire ce nom si la fonction homme n'arrive pas à travailler la première fois. [Étudiants] Donc je lis la page de manuel ouvert, mais je suis encore confus sur la façon de l'utiliser et le programme. D'accord. Un grand nombre de pages de manuel sont moins utiles. Ils sont plus utiles si vous savez déjà ce qu'ils font et puis vous avez juste besoin de se rappeler l'ordre des arguments ou quelque chose. Ou ils peuvent vous donner un aperçu général, mais certains d'entre eux sont très accablante. Comme f f scan, aussi. Il vous donne des informations pour l'ensemble de ces fonctions, et 1 ligne vers le bas qui se passe ici pour dire, "F balayage f lit à partir du point de corde ou d'un ruisseau." Mais f ouvrir. Alors, comment pourrions-nous utiliser f ouverte? L'idée d'un programme qui a besoin de faire le fichier I / O est que vous devez d'abord ouvrir le fichier que vous souhaitez faire des choses avec, et inévitablement, lire des choses de ce fichier et faire des choses avec eux. F ouvert ce que nous utilisons pour ouvrir le fichier. La chose nous revenons, si ce fichier que nous voulons ouvrir, il nous donne la - ici il est écrit "/ user / share / dict / words." C'est le fichier que nous voulons ouvrir, et nous voulons l'ouvrir - nous devons spécifier explicitement si nous voulons l'ouvrir pour lire ou si l'on veut l'ouvrir pour écrire. Il ya un couple de combinaisons et tout ça, mais nous voulons ouvrir ce pour la lecture. Nous voulons lire à partir du fichier. Alors qu'est-ce que ce retour? Elle retourne un fichier (*) étoile, et je vais juste vous montrer tout dans la variable f, de sorte *, encore une fois, c'est un pointeur, mais nous ne voulons pas faire face à des pointeurs. Vous pouvez penser que f, f est la variable que vous allez utiliser pour représenter le fichier. Donc, si vous voulez lire à partir du fichier, vous lisez à partir de f. Si vous voulez fermer le fichier, vous fermez f. Ainsi, à la fin du programme lorsque nous avons inévitablement à fermer le fichier, que devons-nous faire? Nous voulons combler f. Alors maintenant, la fonction du dernier fichier que nous allons avoir à utiliser est le balayage f, f f balayage. Et qu'est-ce qui ne se fait-il balaye le fichier à la recherche d'un modèle assorti. En regardant la page de manuel ici, nous voyons int f f balayage, ignorer la valeur de retour pour le moment. Le premier argument est le flux de fichier *, de sorte que le premier argument que nous allons vouloir passer est f. Nous scannons sur f. Le second argument est une chaîne de format. Je vais vous donner une chaîne de format pour le moment. Je pense que nous arrive de dire, 127S \ n, beaucoup de ce que c'est inutile. L'idée de ce que la chaîne de format est, est que vous pouvez penser f balayage comme l'opposé de f d'impression. F impression Donc, f d'impression, nous utilisons également ce type de paramètre format, mais f impression que nous faisons est - Voyons un équivalent. Donc imprimer f, et il ya en fait également impression f f, où le premier argument va être f. Lorsque vous imprimez f, on pourrait dire quelque chose comme, "print 127S \ n" et si nous lui passer une chaîne de caractères, ça va pour imprimer cette chaîne, puis une nouvelle ligne. 127, ce qui, je suis sûr, mais je ne me suis jamais limité à l', Vous n'auriez même pas besoin de dire '127 'dans la f impression, mais ce que cela signifie, c'est d'imprimer les 127 premiers caractères. Donc, je suis à peu près sûr que c'est le cas. Vous pouvez Google pour cela. Mais dans le prochain je suis presque positif, cela signifie que. Il s'agit donc d'imprimer les 127 premiers caractères, suivi d'une nouvelle ligne. F balayage f maintenant, au lieu de regarder une variable et l'impression, il va regarder une chaîne et enregistrer le modèle dans la variable. Nous allons utiliser effectivement f balayage dans un autre exemple. Donc, disons que nous avons eu quelques int, x = 4, et nous avons voulu créer une chaîne faite de - a voulu créer la chaîne qui était comme, cela viendra beaucoup plus tard, quelque chose qui est juste comme 4.jpg. Donc, cela pourrait être un programme où vous aurez totalisateur, Bref i contrer, et que vous souhaitez enregistrer une série d'images. Donc, vous voulez sauver I.jpg, où i est une itération de la boucle. Alors, comment pouvons-nous faire pour que cette chaîne JPEG? Si vous voulez imprimer 4.jpg, nous pourrions simplement dire f d'impression, d.jpg%, et alors il serait imprimer pour que JPEG. Mais si nous voulons sauver la 4.jpg chaîne, nous utilisons f balayage. Ainsi, la chaîne s - en fait, nous ne peux pas - caractère, char s, allons-y 100. Donc je vient de déclarer certains tableau de 100 caractères, et c'est ce que nous allons inévitablement à stocker que JPEG po Donc, nous allons utiliser f numérisation et le format, la façon dont nous dirions d.jpg% afin d'imprimer 4.jpg, le format de ce qui se passe à d.jpg%. Ainsi, le format est d.jpg%, ce que nous voulons remplacer avec% d est x, et maintenant nous avons besoin de stocker cette chaîne quelque part. Et où nous allons stocker cette chaîne figure dans la chaîne s. Donc, après cette ligne de code, s, si nous imprimons% s f, de la variable s, il va imprimer 4.jpg. Donc f f balayage est la même que la numérisation f, sauf que maintenant c'est regarder par-dessus ce fichier pour quoi stocker à l'art. C'est ce dernier argument va être. Nous voulons stocker - «famille f Analyse des scans des fonctions à la fois en fonction du format que ci-dessous essayé. Si tout est stocké dans les points de localisation que vous pourriez retourner - " Non, nous pourrions être bon. Laissez-moi réfléchir une seconde. Donc balayage f ne fonctionne pas - ce que le diable est la fonction qui fait ça? Donc balayage f ne va pas prendre un entier et ne point jpg. Il va [marmonne]. Enregistrer variable de type int en string int C. Qu'est-ce que cette variable, ou ce qui est appelé cette fonction? Oui. C'est - oui. Donc, ce que je vous définir avant impression était s f, qui - qui est beaucoup plus logique, pourquoi j'ai dit que c'était beaucoup plus comme f d'impression. Balayage f est toujours un peu comme f d'impression, mais f print s va le numériser sur et remplacez les variables et maintenant le stocker dans une chaîne. Au lieu de l'imprimer, il le stocke dans une chaîne. Donc ignorer complètement. Vous pouvez toujours penser que le spécificateur de format comme celui de f d'impression. Alors maintenant, si nous voulions faire la chose 4.jpg, nous ferions f print s, x de cela. Alors qu'est-ce balayage f fait - ce qui était votre question va être? [Étudiants] Je suis tout confus sur ce que nous essayons de faire ici avec cette JPEG. Pouvez-vous expliquer cette époque 1 plus? Donc, ce fut - il est moins pertinents aux f f scan maintenant, je l'espère, il sera attacher en arrière en quelque sorte de façon. Mais ce que j'ai d'abord été l'intention de montrer était - il s'agit en fait directement liées à ces [? F5] Vous allez utiliser f print s, où, disons que nous avons 100 images, et que vous voulez lire l'image 1.jpg, 2.jpg, 3.jpg. Ainsi, afin de faire cela, vous avez besoin de f ouverte, puis vous devez passer à la chaîne que vous souhaitez ouvrir. Donc, nous voulons ouvrir 1.jpg; afin de créer la chaîne qui est 1.jpg, f impression que nous faisons de s% d.jpg--nous n'avons pas fait pour int i = 0. i <40, i + +. Donc f% s d.jpg impression de i. Donc, après cette ligne, maintenant la variable ou la chaîne s va 1.jpg. Ou, 0.jpg, 1.jpg, 2.jpg. Et afin que nous puissions ouvrir, à son tour, chaque image pour la lecture. Donc, c'est ce que l imprimer f le fait. Voyez-vous ce que l'art d'imprimer f est en train de faire? [Étudiants] Bon, alors ça prend - elle crée une chaîne de caractères, something.jpg, puis il stocke. Oui. Il crée - c'est une autre chaîne de format, tout comme f numérisation et d'impression f, où il insère toutes les variables dans le second argument, peut-être s au lieu de i. Peut-être - je veux dire, c'est le cas. Mais quel que soit l'ordre des arguments est. Il va insérer toutes les variables dans la chaîne de format et ensuite le stocker dans notre mémoire tampon; nous appelons cela un tampon, c'est là que nous stockons la chaîne. Donc, nous gardons à l'intérieur de la chaîne s correctement formaté, d% ayant été remplacé par 4. [Étudiants] Donc, si nous le faisions, est la variable f tout va être réaffecté? Oui. Donc, nous devrions fermer la f d'origine avant de le faire. Mais - et puis aussi, s'il n'y avait pas une f ouvrir ici, nous aurions besoin de le dire - Ouais. Mais ce serait ouvrir une centaine de dossiers différents. [Étudiants] Mais nous ne serions pas en mesure d'accéder ou - d'accord. D'accord. Donc balayage f, f f balayage, est en quelque sorte de la même idée, mais au lieu d', au lieu de le stocker dans une chaîne, c'est plus comme vous êtes maintenant exploitation sur une piqûre et pattern matching contre cette chaîne et stocker les résultats dans des variables. Vous pouvez utiliser f scan pour analyser plus quelque chose comme 4.jpg et stocker l'entier 4 x int en somme. C'est ce que nous pouvons utiliser pour f balayage. F f scan va le faire à la ligne de commande. En fait je suis sûr que c'est ce que la bibliothèque ne CS50. Donc, quand vous dites: "get int,« c'est de balayage f-ment plus - f scan est la façon dont vous obtenez une entrée utilisateur. F f scan va faire la même chose mais en utilisant un fichier à numériser sur. Donc, ici, nous sommes le balayage sur ce fichier. Le modèle que nous essayons de faire correspondre une certaine chaîne de caractères qui est de 127 caractères suivie d'une nouvelle ligne Donc, je suis sûr que nous pourrions même dire simplement "s égaler", puisque dans le dictionnaire nous avons la chance d'avoir, nous garantis pas un mot, c'est que depuis longtemps, et aussi f f scan, je pense, va s'arrêter à la nouvelle ligne, peu importe quoi. Mais nous allons inclure la nouvelle ligne dans le match, et - [Étudiants] Si nous n'avons pas inclus la nouvelle ligne, ne serait-il trouver des pièces d'un mot? Il - chacun - en regardant le dictionnaire - Ainsi, dans le dictionnaire, ce sont toutes nos paroles. Chacun est sur une nouvelle ligne. Le balayage f va ramasser ce mot. Si nous ne comprennent pas la nouvelle ligne, alors il est possible que le balayage f prochaine viens de lire la nouvelle ligne. Mais en incluant la nouvelle ligne, puis sera simplement ignorer la nouvelle ligne. Mais nous ne sortirons jamais partie d'un mot, puisque nous sommes toujours à la lecture à une nouvelle ligne, peu importe quoi. [Étudiants] Mais que faire si vous recherchez le mot "CISSA», comme CISSA. Est-il trouver cela, et dire que c'est un match? Nous voilà donc - il va lire dans - c'est réellement un bon point. Nous ne sommes jamais à l'aide du courant - le mot que nous voulons, c'est l'argument première commande en ligne. Alors chaîne, mot = argv 1. Ainsi, la chaîne que nous voulons, c'est argv 1. Nous ne sommes pas à la recherche d'un mot à tous dans notre analyse f. Ce que nous faisions avec le balayage f devient chaque mot dans le dictionnaire, et puis une fois que nous avons ce mot nous allons utiliser strcmp pour les comparer. Nous allons comparer notre mot et ce que nous venons de lire po Alors forcément, nous allons finir par faire un tas de balayage fs jusqu'à ce qu'il se trouve que f scan sera de retour - il sera de retour un, tant qu'il n'a égalé un nouveau mot, et il reviendra à autre chose dès qu'il a omis de faire correspondre le mot. Nous lisons sur l'ensemble du dictionnaire, le stockage, ligne par ligne chaque mot en la variable s. Ensuite, nous comparons mot avec s, et si la comparaison == 0, strcmp arrive à mettre 0 si une correspondance a été établie. Donc, si il était de 0, alors nous pouvons imprimer f, assorti, ou un mot dans le dictionnaire est, ou ce que vous souhaitez imprimer f. Et puis - nous ne voulons pas fermer à f maintes et maintes fois. C'est le genre de chose que nous voulons faire, et nous ne cherchons pas uniquement pour mot dans le dictionnaire. Donc, nous pourrions le faire, si nous voulions chercher leur modèle, CISSA, comme vous l'avez dit, si nous voulions regarder pour ce motif, il ne permettrait pas, dans le cas car ce n'est pas réellement un mot, mais l'un des mots du dictionnaire qui se trouve à avoir en elle. Donc, il correspondrait à ce mot, mais ce sous-ensemble de ce mot n'est pas un mot lui-même. Mais ce n'est pas la façon dont nous l'utilisons; nous lisons dans chaque mot et en comparant ensuite le mot que nous avons avec ce mot. Donc, nous sommes toujours à la comparaison des mots pleins. Je peux envoyer les solutions finalisées plus tard. C'est une sorte de près la bonne réponse, je pense. [Commentaire étudiants, inintelligible] Oh, ai-je me débarrasser de ça avant? Char s, je pense que nous avons dit 127 - J'ai oublié ce que le plus grand est. Nous allons juste faire 128; donc maintenant l'art est assez long. Nous n'avons pas besoin d'imprimer quoi que ce soit. Nous allons aussi envie d'avoir à fermer notre dossier, et cela devrait être sur la bonne réponse. CS50.TV