[Jouer de la musique] DAVID J. Malan: Très bien. [Rires] Bienvenue. C'est CS50. Et c'est la fin de la cinquième semaine. Et jusqu'à maintenant, nous avons à peu près été prise pour acquis qu'il n'y existe ce compilateur, Clang, que vous avez été invoquer par le biais de cette autre outil appelé Faire que quelque transforme comme par magie votre code source en code objet, les zéros et de uns que le processeur de votre ordinateur, central unité de traitement, comprend réellement. Mais il s'avère qu'il ya un certain nombre qui est passe sous le capot en entre l'entrée et la sortie. Et je voudrais proposer que nous chair que dans un peu plus en détail dans ces quatre étapes, ont quelque chose appelé pré-traitement, quelque chose appelée compilation, qui nous l'avons vu, quelque chose qui s'appelle l'assemblage et quelque chose qui s'appelle la liaison. Donc, jusqu'à présent, dans certains de nos programmes, nous avons eu tranchant comprend. Plus récemment, nous avons eu un peu de tranchant définit des constantes. Ainsi, il s'avère que ces choses qui sont précédés du symbole dièse ou le symbole de la livre sont pré-processeur directives. C'est juste une façon élégante de dire que c'est une ligne de code qui est réellement transformé en quelque chose d'autre avant l' ordinateur même essayer de convertir votre programme en zéros et de uns. Par exemple, forte inclut norme I / O. H, à peu près signifie simplement aller l'avance, récupérer le contenu des fichiers stdio.h et les coller là. Donc, pas de zéros et de uns à ce moment-là encore. C'est vraiment juste une substitution. Et cela est fait au cours de la soi-disant phase de pré-traitement, lorsque vous effectivement parcourue Clang ou spécifiquement Faire dans la plupart des cas. Donc, tout ce qui s'est passé première automatiquement jusqu'à présent. Puis vient l'étape de compilation. Mais nous avons été trop simplifiée compilation. Compiler un programme signifie vraiment prendre à partir de quelque chose comme C, le code source que nous avons écrit, en baisse à quelque chose qui s'appelle l'assemblage. Assemblée langue est un niveau inférieur langage qui, heureusement, nous ne serons pas ont beaucoup l'occasion d' écrire ce semestre. Mais c'est au niveau le plus bas dans l' sens où vous littéralement commencer à écrire additionner et soustraire et multiplier et charger à partir de la mémoire et sauvegarder dans la mémoire, l' instructions très simples qu'un ordinateur, sous le capot, comprend réellement. Enfin, l'assemblage prend cette langue les zéros et de uns que nous avons été décrivant ce jour. Et vraiment, enfin, il ya le soi-disant édition de liens, que nous allons voir dans un instant, qui combine vos zéros et de uns avec des zéros et ceux d'autres personnes avant vous avez créé. Ainsi, considérer ce programme super simple. C'est à partir de la semaine 1. Il a simplement dit: Bonjour tout le monde, sur l'écran. Nous avons couru à travers cette Clang. Or nous avons couru il Faire travers qui s'est déroulée Clang. Et sorti à l'époque où certains zéros et de uns. Mais il s'avère qu'il ya une étape intermédiaire. Si je vais ici - oups, n'a pas veux le voir encore. Si je vais sur ici pour mon appareil et j'ouvre hello.c, ici est que même programme. Et ce que je vais faire dans mon terminal fenêtre est ici, je vais Clang courir plutôt que de faire, ce qui automatise l'ensemble des quatre ces étapes pour nous. Et je vais faire clang-S et puis hello.c puis entrez. Et je reçois un message clignotant encore une fois, ce qui est bon. Et maintenant, dans un peu plus grande fenêtre, Je vais ouvrir gedit ici. Et je vais ouvrir un fichier, s'avère, est appelé hello.s cette contient que langage d'assemblage J'ai parlé plus tôt. Et c'est ce qu'on appelle l'Assemblée langue, niveau assez faible instructions que votre CPU Intel ou quoi que ce soit qui est à l'intérieur comprend. Et mov est pour le mouvement. appel est pour l'appel, une fonction de très faible activité. sous est pour soustraire. Ainsi, lorsque vous avez un processeur particulier à l'intérieur de votre ordinateur, ce qui le rend processeurs distincts, par rapport aux autres sur le marché, qui est elle instructions comprend et souvent de son efficacité est, comment il est rapide à exécuter certaines de ces instructions. Maintenant, pour en savoir plus, vous pouvez prendre prochaine CS61 d'automne au collège. Mais ici, nous avons, par exemple, quelques-uns identificateurs qui pourrait sembler familier. hello.c est le nom du programme. . Texte - il n'ya pas beaucoup d'intérêt il tout à l'heure, rappelons que le texte secteur, à partir de lundi, c'est là en mémoire de votre programme se termine effectivement en place. C'est donc au moins vaguement familier là. Ici, bien sûr, est une mention de notre fonction principale. Défilement vers le bas, ceux-ci concernent des choses appelés registres très petits morceaux de à l'intérieur de la mémoire de votre CPU réelle. Et si je fais défiler vers le bas, même plus loin, je vois une sorte mention indirecte de l'ASCII. Et là, en effet, cette chaîne, bonjour, une virgule monde. Tant histoire courte, cela a été se passe pour vous, automatiquement, sous le capot tout ce temps. Et ce qui se passe est vraiment une fois vous avez couru Clang, ou par voie de Faites, vous obtenez d'abord, à partir du code source, l' ce qu'on appelle en langage assembleur. Puis Clang est de convertir cette assemblée langue vers zéros et de uns. Et c'est la diapositive que nous avons commencé notre discussion à la Semaine 0 sur - puis 1 semaine de suite. Et enfin, ces zéros et de uns sont combinées avec des zéros et des uns à partir de ces bibliothèques que nous avons pris des pour acquis, comme E / S standard ou la Chaîne bibliothèque ou même la bibliothèque CS50. Donc, pour peindre ce tableau plus Visuellement, nous avons hello.c. Et, bien sûr, utilise la fonction printf fonctionner à dire, bonjour tout le monde. L'étape de compilation prend le bas à ce fichier que nous venons de voir hello.s, même mais qui est généralement supprimé automatiquement pour vous. Mais c'est le code assembleur à l'étape intermédiaire. Et puis, quand nous montons l'Assemblée langue, pour ainsi dire, c'est quand vous obtenir ces zéros et de uns. Donc, nous avons zoomé efficacement aujourd'hui sur ce que nous avons prenons pour acquis, signifie aller code source de s'opposer code. Mais enfin, maintenant que même image - nous allons le pousser vers le côté gauche. Et noter que dans le top il J'ai mentionné stdio.h. C'est un dossier que nous avons inclus dans la quasi-totalité de la programmes que nous avons écrit. Et c'est le fichier dont le contenu Obtenir une copie collé, effectivement au sommet de votre code. Mais il s'avère que, sur un ordinateur système quelque part, il ya sans doute une fichier stdio.c que quelqu'un écrivait ans Il ya ce que met en œuvre l'ensemble de la fonctions qui ont été déclarées dans stdio.h. Maintenant, en réalité, ce n'est probablement pas le votre Mac ou votre PC, ou même dans la CS50 appareil est un code C brut. Quelqu'un a déjà compilé et inclus Fichier de code objet. O ou. Une fichier, qui se réfère à une bibliothèque partagée qui a été pré-installés et pré-compilé pour vous. Mais supposons qu'il existe effectivement sur notre stdio.c informatique en parallèle avec Clang. Votre code est en cours de compilation et assemblés. Code de l 'stdio.c est compilé et assemblé, de sorte que cette dernière étape, ici-bas, nous avons en quelque sorte lien, pour ainsi dire, vos zéros et de uns avec ses zéros et de uns dans une programme simple qui est en fin de compte appelé juste Bonjour. C'est donc toute la magie qui est s'est passé jusqu'à présent. Et nous continuerons à prendre ces processus pour acquis, mais se rendent compte il ya beaucoup de détails croustillants se passe là-dessous. Et c'est ce qui fait votre ordinateur avec Intel inside particulièrement nette. Donc, sur cette note, si vous souhaitez vous joindre à nous pour le déjeuner ce vendredi, le faire aller au lieu cs50.net/rsvp d'habitude, 13h15 ce vendredi. Et maintenant quelques annonces. Donc, nous avons quelques bonnes nouvelles. Et nous avons de mauvaises nouvelles. Commencez par quelques bonnes nouvelles ici. [Gémissant] Très bien. Eh bien, c'est techniquement un jour férié, donc ce n'est pas tellement un cadeau de nous. Mais alors, les mauvaises nouvelles bien sûr. [Gémissant] J'ai passé beaucoup de temps sur ces animations. [Rires] Il y aura une session d'examen lundi prochain. Ça va être à 17h30. Nous allons vous rappeler de tous ces détails via e-mail sur le cours de site Web en seulement quelques jours de temps. Il sera filmé et mis à disposition peu de temps après. Donc, si vous ne pouvez pas faire ce lundi fente de la nuit, ne vous inquiétez pas. Sections cette semaine à venir sera également se concentrer sur l'examen pour le quiz. Si votre section est le lundi, ce qui est En effet vacances universitaires, nous encore satisfaire à la section. Si vous ne pouvez pas faire ce que section parce que vous allez de là, c'est très bien. Assister à un dimanche ou mardi ou section mise au point pour la section de Jason, qui est disponibles en ligne. Ainsi, plus de mauvaises nouvelles. Ainsi, selon le programme, nous avons conférence vendredi prochain. Mais les bonnes nouvelles - clairement, j'ai passé trop de temps sur ce sujet. [Rires] Nous annulerons suivant les cours de vendredi. Donc, ça va être un cadeau pour nous, de sorte que vous peut vraiment avoir un bon répit entre cette semaine et deux semaines plus tard. Donc, pas de conférences la semaine prochaine, un tout petit petit quiz, pour lequel vous devriez être se faire de plus en plus excité. Donc, nous allons maintenant tourner notre attention vers quelque chose qui est bien plus visuelle et de plus excitant et de préparer le terrain pour ce qui va être à l'horizon en seulement quelques semaines. Après le premier questionnaire, nous allons transformer le l'accent de nos ensembles de problèmes à l'autre problème spécifique à un domaine, celui de judiciaire ou de sécurité plus général. En fait, la tradition avec ce problème ensemble est pour moi l'un des enseignement boursier ou CA de marcher à travers campus de prendre quelques photos de personnes évidents identifiables, mais non, endroits ou des choses, puis tous les ans je en quelque sorte réussi à effacer accidentellement ou endommager la carte des médias numériques C'est à l'intérieur de notre caméra. Mais pas une grosse affaire. Je peux aller de l'avant et de le brancher que dans mon ordinateur. Je peux faire une image légale de celui-ci, de sorte dire, en copiant les zéros et celles au large de cette carte mémoire, que ce soit c'est une carte SD ou une carte compact flash ou ce que vous êtes familier avec. Et puis, nous pouvons remettre cela. Et si le défi à relever, entre autres, choses pour vous, sera d'écrire Code C qui récupère tout un tas d' JPEG pour moi et révélées seront ces personnes, des lieux ou des choses. Et nous parlerons également, dans ce problème définir et dans les jours à venir, sur graphiques plus générale. Nous les avons utilisés, un cours, pour sortir. Mais vous avez en quelque sorte pris pour acquis il existe ces notions de haut niveau des rectangles et des ovales. Mais sous le capot il ya des pixels. Et vous avez dû commencer penser à ceux-ci. Ou vous pour p-set 4 avoir à penser sur l'écart entre vos briques, comment rapidement vous n'êtes balle se déplace à travers l'écran pour sortir. Donc, il ya cette notion de l' points sur votre écran qui est entrer en jeu déjà. Maintenant, ce que vous voyez, cependant, c'est ce vous arrivez sur un écran d'ordinateur. Si vous avez déjà regardé un bien ou mauvaise télévision, les chances sont-ils assez bien traiter le public comme technophobes qui n'ont pas vraiment en savoir beaucoup sur l'informatique. Et il est donc très facile pour la police detective-à-dire, pouvez-vous nettoyer ça pour moi? Ou renforcer, non? Améliorer, c'est comme le mot à la mode dans plus aucune émission liée à la criminalité. Et la réalité est que si vous prenez une très image floue d'un suspect faisant quelque chose de mauvais, vous ne pouvez pas juste l'améliorer. Vous ne pouvez pas zoomer en continu. Vous ne pouvez pas le voir dans le reflet de quelqu'un d' oeil qui a commis le crime particulier, malgré le la prévalence de ce phénomène sur la télévision. Et ainsi, avec qui nous allons motiver que à venir problème réglé avec un aperçu quelques spectacles avec qui vous peut-être familier. [LECTURE VIDEO] -OK. Maintenant, nous allons obtenir un look bien à vous. -Tenez-le. Exécutez ce retour. -Attendez une minute. Allez à droite. -Il. Congeler cela. Écran plein. -OK. Congeler cela. Serrez-vous à ce sujet, voulez-vous? Vector-en sur ce mec par la roue arrière. -Zoom, ici, sur cette place. -Avec le bon équipement, le imagée peuvent être agrandies et aiguisé. -Qu'est-ce que c'est? -Il s'agit d'un programme d'amélioration. -Pouvez-vous éclaircir ce point tout? -Je ne sais pas. Nous allons l'améliorer. -Améliorer la section A-6. -J'ai augmenté le détail et - -Je pense qu'il ya suffisamment de renforcer. Relâchez à mon écran. -Améliorer la réflexion dans son oeil. -Courons à travers cette amélioration de la vidéo. -Edgar, pouvez-vous améliorer ce? -Attends. -J'ai travaillé sur cette réflexion. -Quelqu'un de réflexion. -Réflexion. -Il ya une réflexion du visage de l'homme. -La réflexion. -Il ya une réflexion. -Zoom sur le miroir. Vous pouvez voir un reflet. -Pouvez-vous améliorer l'image à partir d'ici? -Pouvez-vous améliorer le droit ici? -Pouvez-vous améliorer? -Pouvez-vous améliorer? -Pouvons-nous améliorer ce? -Pouvez-vous améliorer? -Attends une seconde, je vais améliorer. -Zoomez sur la porte. -X10. -Zoom. [Rires] -Emménager -Attendez, arrêtez. -Stop. -Mettre en pause. -Tourner un 75 degrés autour de merci de la verticale. [Rires] -Arrêtez, et revenir à la partie sur la porte. -Vous avez une image enhancer qui peut bitmap? -Peut-être que nous pouvons utiliser la Pradeep Sen méthode pour voir à travers les fenêtres. -Ce logiciel est l'état de l'art. -La valeur d'icône est désactivée. -Avec la bonne combinaison des algorithmes. -Il a pris des algorithmes d'éclairage à le prochain niveau et je peux les utiliser pour renforcer cette photo. Verrouillez-le et agrandir l'axe z. -Améliorer. -Améliorer. -Améliorer. Le gel et améliorer. [FIN LECTURE VIDÉO] DAVID J. Malan: Set de problème pour 5 est ce qui nous attend là-bas. Donc, nous allons bientôt avoir une meilleure compréhension quand et pourquoi vous ne pouvez et notre ne peut améliorer de cette façon. Mais d'abord, revenons à notre attention à certains des blocs de construction, nous allons doivent être en mesure de raconter cette histoire. Donc, rappelons que nous avons tiré cette image sur Lundi et un peu la semaine dernière. Et cela décrit la disposition des choses dans la mémoire de votre ordinateur lorsque l'exécution de certains programmes. Le segment technologique en haut, rappel, se réfère les zéros et de uns réels qui composent votre programme. Il ya, en dessous, certains initialisé ou données non initialisées, qui généralement se réfère à des choses comme des constantes ou des chaînes ou variables globales qui ont été déclarée à l'avance. Il ya le tas, mais nous reviendrons revenir dans un peu. Et puis il ya la pile. Tout comme une pile de plateaux dans la cafétéria, c'est là que la mémoire devient couches et couches chaque fois vous faites ce que dans un programme? Quelle est l'utilité de pile pour? Ouais? Appel de fonction. Chaque fois que vous appelez une fonction, c'est donné à ruban de mémoire pour son variables locales ou de ses paramètres. Et imagée, nous voyons que les uns avec les fonction successive appelé, lorsque A appels B appelle C appels D, ils se couche sur la pile. Et dans chacune de ces tranches de mémoire est essentiellement une portée unique, pour cette fonction, ce qui, bien sûr, est problématique si vous voulez remettre d'une fonction à une autre Une pièce de données que vous voulez qu'il de muter ou de changer. Alors quelle est notre solution pour permettre aux Une fonction représentée par une pile encadrer pour changer la mémoire à l'intérieur d'un autre cadre de pile? Comment ces deux discours à l'autre? Donc, par le biais de pointeurs ou des adresses, qui, encore une fois, juste décrire où en la mémoire, par l'intermédiaire d'une particulière nombre de morsure, le particulier valeur peut être trouvée. Donc, rappeler la dernière fois aussi, nous avons continué l'histoire et regardé un assez programme buggy. Et ce programme est buggé pour quelques-uns raisons, mais le plus inquiétant est l'un parce qu'il ne parvient pas à vérifier quoi? Ouais, il ne parvient pas à contrôler l'entrée. Désolé? Si c'est plus de 12 caractères. Donc, très intelligemment, en appelant memcopy, qui, comme son nom l'indique, juste copies mémoire de son second argument dans son premier argument. Le troisième argument, très intelligemment, est vérifié pour s'assurer que vous n'avez pas copier plus, dans ce cas, la longueur de barre, le nombre de caractères, dans la destination, ce qui est tableau C. Mais le problème est que ce C si elle n'est pas assez grande pour gérer cela? Vous allez copier le numéro de octets que vous avez été donné. Mais qu'est-ce que vous avez fait plus octets que vous avez la place pour? Eh bien, ce programme très bêtement juste procède aveuglément à prendre ce que ça donné, bonjour barre oblique inverse est 0 grand si la chaîne est courte assez, comme cinq caractères. Mais si c'est effectivement 12 caractères ou 1200 caractères, nous avons vu la dernière fois que vous allez juste complètement écraser la mémoire ne vous appartient pas. Et pire, si vous écrasez qui partie rouge là-bas que nous avons appelé l' adresse de retour - ce n'est que lorsque l'ordinateur automatiquement, pour vous, derrière l' scènes, se range une valeur 32 bits qui rappelle à quelle adresse il se doit retourner quand foo, cette autre fonction, on fait exécuter. C'est une miette de pain de toutes sortes à laquelle il renvoie. Si vous écrasez qui, potentiellement, Si vous êtes le méchant, peut pouvaient potentiellement prendre le relais l'ordinateur de quelqu'un. Et vous aurez très certainement s'écraser dans la plupart des cas. Maintenant, ce problème a été exacerbé seulement comme nous avons commencé à parler de la mémoire la gestion en général. Et malloc, pour l'allocation de mémoire, est un fonction que nous pouvons utiliser pour allouer mémoire lorsque nous ne savons pas à l'avance que nous pourrions avoir besoin d'. Ainsi, par exemple, si je reviens à l'appareil ici. Et j'ouvre de dernière hello2.c de temps, rappeler ce programme ici, qui semblait un petit quelque chose de ce genre, seulement trois lignes - indiquer votre nom, puis le nom de la chaîne, sur la gauche, est égal GetString. Et puis nous avons l'imprimer, le nom de l'utilisateur. Donc, ce fut un programme super simple. Pour être clair, je vais de l'avant et faire bonjour-2. Je vais faire dot slash bonjour-2. Indiquez votre nom - David. Entrée. Bonjour David. Il semble fonctionner OK. Mais qu'est-ce qui se passe réellement sous le capot ici? D'abord nous allons décoller certaines couches. String est juste un synonyme nous avons réalisé pour quoi? Étoiles Char. Donc, nous allons faire un peu plus obscur mais techniquement plus correct que ce est une étoile carbonisation, ce qui signifie que nom, oui, est une variable. Mais ce que les magasins de nom est l'adresse de un char, qui se sent un peu étrange parce que je suis en train de retourner une chaîne. Je suis en train de revenir multiple chars pas un chevalier. Mais bien sûr, vous n'avez besoin que du premier L'adresse de chevalier de se rappeler où l' chaîne entière est parce que pourquoi? Comment déterminez-vous où la fin de la chaîne est de savoir le début? Le zéro de barre oblique inverse. Donc, avec ces deux indices que vous avez compris avant le début et la fin de l' toute chaîne sont, tant qu'ils sont correctement formé avec qui null terminateur, que nul barre oblique inverse. Mais cela appelle GetString. Et il s'avère que GetString tout ce temps a été un peu tricher pour nous. Il a été fait ce travail, pour être sûr, obtenir une chaîne de caractères à partir de l'utilisateur. Mais où est cette mémoire été en venir? Si nous revenons à l'image ici et appliquer la définition d'un juste il ya moment, que la pile est l'endroit où mémoire va quand les fonctions sont appelées, Selon cette logique, lorsque vous appelez GetString, et puis je tape dans D-A-V-I-D Entrée, où est D-A-V-I-D oblique zéro stocké, sur la base de l' histoire que nous nous avons dit jusqu'ici? Il semble être en la pile, non? Lorsque vous appelez obtenir chaîne que vous obtenez un petit coin de mémoire sur la pile. Donc, il va de soi que D-A-V-I-D backslash zéro est stockée y dans la pile. Mais attendez une minute, getString retours cette chaîne, pour ainsi dire, ce qui signifie c'est le plateau de la cafétéria est retiré de la pile. Et nous avons dit la dernière fois que dès qu'un retour de la fonction, et que vous prenez plateau, pour ainsi dire, de la pile, ce qui pouvez-vous prendre sur les restes d' que la mémoire? J'ai en quelque sorte leur redessiné comme des points d'interrogation car ils deviennent effectivement des valeurs inconnues. Ils peuvent être réutilisés lors de certains fonction suivante est appelée. En d'autres termes, si nous nous trouvons à stocker - Je vais faire un dessin rapide ici de la pile. S'il nous arrive d'être dessiner le fond de mon segment de mémoire, et nous dirons que c'est le lieu de mémoire occupé par principale et peut-être arg c et arg v et rien d'autre dans le programme, lorsque GetString est appelé, vraisemblablement GetString obtient un morceau de mémoire ici. Et puis D-A-V-I-D en quelque sorte se retrouve dans cette fonction. Et je vais simplifier. Mais supposons que le D-A-V-I-D backslash zéro. Donc, ce nombre d'octets sont utilisés dans le cadre de GetString. Mais dès le retour getString, nous dit la dernière fois que cette mémoire sur ici tout devient - woops! - tout devient effectivement effacées. Et nous pouvons penser à cela maintenant comme question marques, car qui sait ce qui va devenir de cette mémoire. En effet, je l'appelle très souvent des fonctions autre que GetString. Et dès que je l'appelle un autre fonction de GetString, peut-être pas en ce programme nous avons juste regardé mais à une autre, sûrement un autre fonction pourrait finir par être donné cette prochaine place dans la pile. Donc, il ne peut pas être que les magasins getString D-A-V-I-D sur la pile parce que je perdre immédiatement accès. Mais nous savons qu'ils getString ne retourne quoi? Il ne s'agit pas de revenir à moi six caractères. Qu'est-ce que cela revient vraiment ne nous concluons dernière fois? L'adresse de la première. Donc, d'une certaine manière, lorsque vous avez appelé GetString, c'est allouer un bloc de mémoire pour la chaîne de caractères que le type et les utilisateurs adresse puis retour de celui-ci. Et il s'avère que lorsque vous voulez fonctionner pour allouer de la mémoire dans ce chemin et revenir à la personne qui a appelé cette fonction, l'adresse de l' ce morceau de mémoire, vous devez absolument peut pas le mettre dans la pile à l' bas, parce que fonctionnellement c'est juste va pas devenir la vôtre très rapidement, de sorte que vous pouvez probablement le deviner où nous allons probablement le jeter à la place, la soi-disant tas. Donc, entre le fond de votre mémoire de mise en page et le dessus de votre mémoire de disposition sont tout un tas de segments. La première est la pile, et droit ci-dessus, il est le segment de mémoire. Et le tas est juste un autre morceau de mémoire qui n'est pas utilisé pour des fonctions quand ils sont appelés. Il est utilisé pour la mémoire à long terme, lorsque vous voulez une fonction pour saisir certains mémoire et être capable de s'accrocher à elle sans perdre le contrôle. Maintenant, vous pourriez peut-être immédiatement voir que ce n'est pas nécessairement un design parfait. Comme votre programme alloue de la mémoire sur la pile, ou comme vous l'appelez plus et plus de fonctions, ou que vous allouez mémoire sur le tas avec malloc off comme GetString fait, ce qui clairement semble être inévitable problème? Droit. Comme le fait que ces flèches sont dirigés les uns les autres n'augure rien de bon. Et en effet, nous pourrions très rapidement planter un programme dans un certain nombre de façons. En fait, je pense que nous pourrions avoir fait cette fois accidentellement. Ou sinon, nous allons le faire délibérément maintenant. Permettez-moi d'aller de l'avant et j'écris super-rapide un programme appelé dontdothis.c. Et maintenant, je vais ici et ne forte comprennent stdio.h. Disons déclarer fonction foo prend aucun argument, ce qui est notée aussi bien par vide. Et la seule chose foo va faire est appel foo, ce qui n'est probablement pas le plus intelligent idée, mais tant pis. Ent void main. Maintenant, la seule chose principale va à faire est d'appeler foo ainsi. Et juste pour le plaisir, je vais aller avance ici et dire printf "Bonjour de foo ". OK. Donc, si je n'ai pas fait d'erreurs, Faire dontdothis point slash. Et faisons-le dans une plus grande fenêtre - dot slash, dontdothis. Allez. Uh oh. Apparemment, vous pouvez le faire. Merde. OK. Attendez. Stand by. Avons-nous - Nous n'avons utilisons avec Make. [Soupirs] Je sais, mais je pense que nous juste supprimé cela. Euh, ouais. Merde. Résolvez cette Rob. Quoi? C'est très simple. Oui, nous nous sommes tournés optimisation off. OK, stand bye. Maintenant je me sens mieux. OK. Très bien. Donc, nous allons recompiler - Assurez-vous dontdothis. Vous pourriez avoir à renommer ce à dothis.c dans un instant. Nous y voilà. Je vous remercie. OK. Donc, le fait que j'imprimais quelque chose a été fait juste ralentissant le processus par lequel nous aurait atteint ce point. OK. Ouf! Alors qu'est-ce qui se passe réellement? La raison pour laquelle, soit dit en passant, est faire quoi que ce soit en termes d'entrée et la production tend à être plus lent parce que vous avoir à écrire des caractères à l' écran, il doit défiler. Tant histoire courte, je n'avais en fait arrivé si impatient, nous aurions vu ce résultat final aussi. Maintenant que je me suis conduite de l'impression-ups, on voit tout de suite. Alors pourquoi est-ce qui se passe. Eh bien, l'explication est simple, bien sûr, est que foo ne devrait probablement pas être lui-même appel. Maintenant, en termes généraux, c'est récursion. Et nous avons pensé quelques semaines Il ya récursive est bon. La récursivité est cette façon magique d' vous exprimer superbe succinctement. Et ça marche. Mais il est un élément clé de l'ensemble des les programmes récursifs dont nous avons parlé et regardant à ce jour, qui était qu'ils avaient quoi? Un scénario de base, ce qui était quelque codé en dur cas où ledit, dans certaines situations ne pas appeler foo, ce qui est clairement pas le cas ici. Alors qu'est-ce qui se passe réellement en termes de cette image? Eh bien, quand principal appelle foo, il obtient une tranche de mémoire. Quand foo foo appelle, il devient une tranche de mémoire. Quand foo foo appelle, il obtient une tranche. Il obtient une tranche. Il obtient une tranche. Parce que foo n'est jamais revenir. Nous ne sommes jamais effacer l'un de ceux cadres de la pile. Nous sommes donc souffler dans le tas, pas parler qui sait quoi d'autre, et nous outrepasser les limites de notre dits segments de mémoire. Erreur aller segmentation faux. Donc, la solution existe clairement ne pas le faire. Mais la plus grande implication est que, oui, il est absolument certaine limite, même si elle n'est pas bien défini, quant à la façon de nombreuses fonctions que vous pouvez appeler dans un programme, combien de fois une fonction peut s'appeler. Ainsi, même si nous avons fait prêcher la récursivité que cette chose magique potentiellement une Il ya quelques semaines pour le sigma fonction, et quand nous obtenons les données structures et CS50, vous verrez d'autres applications pour elle, ce n'est pas nécessairement la meilleure chose. Parce que si une fonction s'appelle elle-même, appelle lui-même, même s'il ya une base cas, si vous ne frappez pas ce cas de base pour 1000 appels ou 10.000 appels, par ce moment-là que vous pourriez avoir plus de place sur votre soi-disant pile et appuyez d'autres segments de la mémoire. Il est donc trop une conception compromis entre élégance et entre la robustesse de votre particulier mise en oeuvre. Donc, il ya un autre inconvénient ou autre gotcha à ce que nous avons fait jusqu'ici. Quand j'ai appelé GetString - Permettez-moi de revenir en bonjour-2. Remarquez que je vais appeler GetString, qui est de retour d'une adresse. Et nous revendiquons aujourd'hui cette adresse c'est à partir du tas. Et maintenant, je suis imprimant la chaîne à cette adresse. Mais nous n'avons jamais appelé l' opposé de GetString. Nous n'avons jamais eu à Calll une fonction comme ungetstring, où vous la main arrière cette mémoire. Mais franchement nous avons probablement aurait dû être. Parce que si nous continuons à demander à l'ordinateur pour la mémoire, par l'intermédiaire d'une personne comme GetString mais jamais lui redonner, sûrement cela aussi est lié à conduire à problèmes qui nous manquer de mémoire. Et en fait, nous pouvons regarder pour ces problèmes avec le nouvel outil dont l'usage est un peu cryptique à taper. Mais permettez-moi d'aller de l'avant et les éclaboussures vers le haut sur l'écran dans un instant. Je vais aller de l'avant et d'exécuter Valgrind avec paramètre dont la première commande argument de la ligne est le nom de ce programme bonjour-2. Et malheureusement c'est sortie est atrocement complexe pour aucune bonne raison. Ainsi, nous voyons tout ce désordre. David est l'état mon nom. C'est donc le programme effectivement en cours d'exécution. Et maintenant, nous obtenons cette sortie. Alors Valgrind est similaire dans l'esprit de GDB. Ce n'est pas un débogueur en soi. Mais c'est un contrôleur de mémoire. C'est un programme qui se déroulera votre programmer et vous dire si vous demandiez à un ordinateur pour la mémoire et jamais remis cela arrière, ce qui signifie que vous avez une fuite de mémoire. Et les fuites de mémoire ont tendance à être mauvais. Et vous, c'est aux utilisateurs d'ordinateurs ont probablement ressenti cela, si vous avez un Mac ou un PC. Avez-vous déjà utilisé votre ordinateur pendant tout et pas redémarré dans plusieurs jours, ou si vous avez juste beaucoup de programmes en cours, et ce satané ralentit à une halte de meulage, ou tout au moins c'est super ennuyeux à utiliser, parce que tout juste obtenu super lent. Maintenant, cela peut être n'importe quel nombre de raisons. Il pourrait s'agir d'une boucle infinie, un bug dans le code de quelqu'un, ou, plus simplement, il pourrait signifier que vous utilisez plus mémoire, ou d'essayer d', que votre ordinateur dispose effectivement. Et peut-être il ya un bug dans certains programmes qui continuent à demander pour la mémoire. Navigateurs pour les années étaient connus pour ce, demandant de plus en plus de mémoire mais jamais le remettre. Assurément, si vous avez seulement un nombre fini quantité de mémoire, vous ne pouvez pas demander un nombre infini de fois pour une partie de cette mémoire. Et ce que vous voyez ici, même si à nouveau la sortie de Valgrind est inutilement complexe pour jeter un regard sur Tout d'abord, c'est la partie intéressante. Heap - en cours d'utilisation, à la sortie. Alors, voici la quantité de mémoire est en cours d'utilisation dans le tas à l' fois que mon programme est sorti - apparemment six octets dans un bloc. Donc, je vais saluer mes mains ce qui est un bloc. Pensez que c'est juste un morceau, un plus mot technique pour morceau. Mais six octets - ce sont les six octets étaient encore en cours d'utilisation? Exactement. D-A-V-I-D barre oblique inverse zéro, cinq lettre nom ainsi que la terminaison nulle. Donc, ce programme Valgrind remarqué que je demandé six octets, apparemment, par façon de GetString, mais jamais leur a donné dos. Et en fait, ce ne serait pas si évident si mon programme n'est pas trois lignes, mais c'est 300 lignes. Nous pouvons donc donner une autre commande argument de la ligne de Valgrind pour rendre plus verbeux. C'est un peu gênant de se souvenir. Mais si je le fais - Voyons voir. Fuite - Était-ce une fuite - même si je ne me souviens pas Ainsi, il est hors main. - Fuite chèque équivaut à plein. Yep, merci. - Fuite chèque équivaut à plein. Entrée. Même programme est en cours d'exécution. Tapez David à nouveau. Maintenant, je vois un peu plus en détail. Mais au-dessous le résumé du tas, ce qui est identique à quatre - ah, c'est plutôt agréable. Maintenant Valgrind est actuellement à la recherche un peu plus difficile dans mon code. Et il est dit que, apparemment, malloc à la ligne - nous agrandir. À la ligne - nous ne voyons pas quelle ligne il s'agit. Mais malloc est le premier coupable. Il ya un blog dans malloc. Tout va bien? OK, no. Droite? J'ai appelé getString. GetString appelle apparemment malloc. Alors, quelle ligne de code est apparemment à défaut d'avoir attribué cette mémoire? Supposons que celui qui a écrit malloc a été assez longtemps qu'il est pas de leur faute. Donc, c'est probablement la mienne. getString dans cs50.c - de sorte que c'est une déposer quelque part sur l'ordinateur - en ligne 286 semble être le coupable. Maintenant, supposons que CS50 a été autour de quantité décente de temps, de sorte nous aussi nous sommes infaillibles. Et ce n'est probablement pas dans getString que le bug se trouve, mais plutôt dans bonjour line-2.c 18. Donc, nous allons jeter un coup d'œil à ce que la ligne 18 était. Oh. D'une certaine manière cette ligne n'est pas nécessairement buggy en soi, mais c'est la raison derrière cette fuite de mémoire. Si super simple, ce serait intuitivement être la solution ici? Si nous demandons mémoire, n'ont jamais été lui redonner, et cela semble être un problème, car au fil du temps mon ordinateur pourrait manquer de mémoire, pourrait ralentir vers le bas, de mauvaises choses peuvent arriver, eh bien, quelle est la solution simple et intuitive? Il suffit de lui redonner. Comment pouvez-vous libérer de la mémoire? Eh bien, heureusement, c'est très simple de dire simplement le nom gratuite. Et nous n'avons jamais fait cela auparavant. Mais vous pouvez penser essentiellement de libre comme l'opposé de malloc. libre est à l'opposé de allouer de la mémoire. Alors maintenant, permettez-moi de recompiler. Assurez-bonjour-2. Permettez-moi de le relancer. bonjour-2 David. Donc, il semble fonctionner dans exactement de la même façon. Mais si je reviens à Valgrind et relancez que même commande sur mon nouveau programme compilé, le typage en mon nom comme avant - Nice. Résumé Heap - en usage à la sortie - zéro octets dans les blocs zéro. Et c'est super sympa, tout blocs de tas ont été libérés. Pas de fuites sont possibles. Donc à venir, pas avec l'ensemble du problème 4, mais avec l'ensemble du problème 5, la médecine légale et au-delà, cela aussi va devenir un mesure de la justesse de votre programme, si vous avez ou non ou qui n'ont pas de fuites de mémoire. Mais heureusement, vous pouvez non seulement raisonner à travers eux de manière intuitive, qui est, sans doute, facile pour les petits programmes mais plus difficile pour les grands programmes, Valgrind, pour les grands programmes, peut vous aider à identifier le problème particulier. Mais il ya un autre problème qui pourraient survenir. Permettez-moi d'ouvrir ce fichier ici, qui est, encore une fois, un exemple un peu simple. Mais concentrons-nous sur ce que ce programme fait. C'est ce qu'on appelle memory.c. Nous publierons plus tard aujourd'hui dans la zip du code source d'aujourd'hui. Et remarquez que j'ai une fonction appelée f qui ne prend aucun argument et retourne rien. Dans la ligne 20, je suis apparemment déclarant une pointeur vers un int et de l'appeler x. Je attribution est le retour valeur de malloc. Et juste pour être clair, combien d'octets h Je obtenir probablement de retour de malloc dans cette situation? Probablement 40. Où puisez-vous cette information? Eh bien, si vous vous souvenez que l'int est souvent 4 octets, au moins il est dans l' appareil, 10 fois 4 est évidemment 40. Alors malloc retourne l'adresse d' un bloc de mémoire et à stocker que répondre finalement à x. Donc, pour être clair, ce qui puis qui se passe? Eh bien, permettez-moi de revenir à notre image ici. Permettez-moi de ne pas simplement attirer le fond de mon la mémoire de l'ordinateur, laissez-moi aller de l'avant et tirer l'ensemble du rectangle que représente l'ensemble de ma RAM. Nous dirons que la pile est sur le fond. Et il ya un segment de texte dans les données non initialisées. Mais je vais juste ceux abstrait d'autres choses à l'extérieur comme dot, dot dot. Je vais faire référence à ce que le segment de mémoire dans la partie supérieure. Et puis, au fond de cette image, pour représenter principal, je vais de lui donner une mémoire de tranches sur la pile. Pour f, je vais lui donner une tranche de la mémoire dans la pile. Maintenant, je dois consulter mon le code source à nouveau. Quelles sont les variables locales pour principal? Apparemment rien, si cette tranche est effectivement vide ou même pas aussi grand comme je l'ai dessiné. Mais dans f, j'ai une variable locale, qui est appelé x. Donc, je vais aller de l'avant et donner f un morceau de la mémoire, le qualifiant de x. Et maintenant malloc de 10 fois 4, Alors malloc 40, où est-ce mémoire vient-il? Nous n'avons pas fait un dessin comme ça avant. Mais supposons que c'est effectivement venant ici, donc on, deux, trois, quatre, cinq. Et maintenant j'ai besoin de 40 de ces derniers. Alors je vais juste faire point, point, point de suggérer qu'il ya encore plus de mémoire revenir dans le tas. Maintenant ce qui est l'adresse? Choisissons notre arbitraire traiter comme toujours - Ox123, même si ça va probablement être quelque chose de complètement différent. C'est l'adresse du premier octet mémoire que je demande malloc pour. Donc en bref, une fois la ligne 20 exécute, ce qui est littéralement stocké à l'intérieur de x ici? Ox123. Ox123. Et le bœuf est inintéressant. Cela signifie simplement voici un nombre hexadécimal. Mais ce qui est important est que ce que j'ai magasin en x, qui est une variable locale. Mais son type de données, encore une fois, est une adresse d'un int. Eh bien, je vais stocker Ox123. Mais encore une fois, si c'est un peu trop compliqué inutilement, si je fais défiler en arrière, nous pouvons abstrait cette distance assez raisonnable et juste dire que x est un pointeur vers ce bloc de mémoire. OK. Maintenant, la question à portée de main est la suivante - ligne 21, il s'avère, est bogué. Pourquoi? Désolé? Il n'a pas - dire qu'une fois de plus. Eh bien, ce n'est pas gratuit. C'est donc la deuxième mais. Donc, il ya un autre mais plus particulièrement à la ligne 21. Exactement. Cette simple ligne de code est juste un buffer overflow, un dépassement de mémoire tampon. Un tampon signifie simplement un morceau de mémoire. Mais ce morceau de mémoire est de taille 10, 10 entiers, ce qui signifie, si nous index dans l'aide du sucre syntaxique de notation de tableau, la place entre parenthèses, vous avez accès à x support 0 x 1 x support, Support point, point, point. x support 9 est le plus grand. Donc, si je fais x support 10, où Je vais encore en mémoire? Eh bien, si j'ai 10 int - nous allons réellement tirer toutes d'entre eux ici. C'était donc les cinq premiers. Voici les cinq autres ints. Donc x support 0 est ici. x support 1 est ici. x support 9 est ici. x support 10 est ici, ce qui signifie que je dis, dans la ligne 21, l'ordinateur de mettre l' numéro où? Le numéro 0 où? Eh bien, c'est 0, oui. Mais juste le fait que son 0 est une sorte de coïncidence. Il pourrait être le nombre 50, pour tous nous nous soucions. Mais nous essayons de mettre au point x support 10, qui est où cette interrogation est tiré, qui n'est pas une bonne chose. Ce programme pourrait très bien planter en conséquence. Maintenant, nous allons aller de l'avant et voir si cela est, en effet, ce qui se passe. Faire mémoire, depuis le fichier est appelé memory.c. Allons de l'avant et exploités la mémoire de programme. Nous avons donc eu de la chance, en fait, il semble. Nous avons eu de la chance. Mais nous allons voir si nous courons maintenant Valgrind. À première vue, mon programme pourrait semblent être tout à fait exact. Mais laissez-moi courir Valgrind avec l' - Fuite chèque équivaut à plein sur la mémoire. Et maintenant, quand je lance cette - intéressant. Invalide écrire de taille 4 à la ligne 21 du memory.c. Ligne 21 de memory.c est lequel? Oh, intéressant. Mais attendez. Taille 4, quelle est cette référence? Je n'ai qu'une seule j'écris, mais il est de taille 4. Pourquoi est-il 4? C'est parce que c'est un int, ce qui est, là encore, quatre octets. Alors Valgrind trouvé un bug que j'ai, en regardant mon code, n'est-ce pas. Et peut-être votre TF seraient ou non. Qu'est Mais Valgrind pour sûr constaté que nous avons fait une erreur il ya, même mais nous avons eu de la chance, et l'ordinateur a décidé, hein, je ne vais pas planter juste parce que vous avez touché un octet, un La valeur de la mémoire de l'int que vous n'avez pas propre réalité. Eh bien, quoi d'autre est bogué ici. Adresse - c'est une adresse regard fou en hexadécimal. Cela signifie simplement que quelque part dans le tas est zéro octets après un bloc de taille 40 est affecté. Permettez-moi de faire un zoom arrière ici et voir si c'est un peu plus utile. Intéressant. 40 octets sont définitivement perdues dans le dossier de la perte de 1 1. Encore une fois, plus de mots que est utile ici. Mais sur la base des lignes mises en surbrillance, où dois-je me concentrer probablement mon attention pour un autre bug? On dirait une ligne 20 de memory.c. Donc, si nous revenons à la ligne 20, c'est la celui que vous avez identifié plus tôt. Et ce n'est pas nécessairement buggy. Mais nous avons cette inversé ses effets. Alors, comment puis-je corriger au moins l'une de ces erreurs? Que pouvais-je faire après la ligne 21? Je pourrais le faire sans x, est donc de redonner cette mémoire. Et comment puis-je résoudre ce bug? Je dois absolument aller pas plus loin que 0. Je vais donc essayer et ré-exécuter cette. Désolé, certainement aller pas plus loin que 9. Faire mémoire. Permettez-moi de RERUN Valgrind dans une fenêtre plus grande. Et maintenant, regardez. Nice. Tous les blocs de tas ont été libérés. Pas de fuites sont possibles. Et au-dessus ici, il n'y a aucune mention pas plus de droit valide. Juste pour avoir gourmand, et LET'S voir si une autre démonstration ne va pas comme prévu - J'ai eu la chance il ya un instant. Et le fait que ce n'est peut-être 0 inutilement trompeuse. Disons simplement faire 50, un peu arbitraire nombre, faire mémoire de points mémoire slash - toujours avoir de la chance. Rien n'est s'écraser. Supposons que je viens de faire quelque chose de vraiment stupide, et je fais 100. Permettez-moi refais mémoire, dot mémoire slash - eu de la chance à nouveau. Que diriez-vous de 1000? ints au-delà, à peu près, où je devrais être? Faire mémoire - bon sang. [Rires] OK. Disons plaisante pas plus. Exécutez à nouveau la mémoire. Nous y voilà. Très bien. Donc, apparemment, vous indexez 100.000 ints au-delà où vous auriez dû en mémoire, de mauvaises choses arrivent. Donc, ce n'est évidemment pas , une règle dur rapide. J'étais un peu en utilisant essai et l'erreur d'y arriver. Mais c'est parce que, longue histoire courte, la mémoire de votre ordinateur est également divisé dans ces choses appelées segments. Et parfois, l'ordinateur fait vous a donné un peu plus de mémoire que vous demandez. Mais pour l'efficacité, c'est juste plus facile à obtenir plus de mémoire, mais seulement vous dire que vous obtenez une partie de celui-ci. Et si vous avez de la chance, parfois, Par conséquent, vous pourriez être en mesure de toucher mémoire qui ne vous appartient pas. Vous n'avez aucune garantie que la valeur que vous mettez y aura rester là, parce que l'ordinateur pense toujours que ce n'est pas vôtre, mais ce n'est pas nécessairement aller pour toucher un autre segment de mémoire de l' ordinateur et d'induire une erreur comme celui-là. Très bien. Vous avez des questions, puis sur la mémoire? Très bien. Prenons un coup d'oeil ici, puis, à quelque chose que nous avons entreprise depuis accordée pour un certain temps, ce qui C'est dans ce fichier appelé cs50.h. Il s'agit donc d'un fichier. Ce sont juste un tas des commentaires là-haut. Et vous pourriez avoir regardé cette si vous poussé autour de l'appareil. Mais il s'avère que tout le temps, lorsque nous utilisions chaîne comme une synonyme, le moyen par lequel nous avons déclaré qui était synonyme avec cette mot-clé typedef, pour la définition de type. Et nous sommes essentiellement en disant faisons enchaîner un synonyme pour la star caractères. Ce que le moyen par lequel la pile créé ces roues de formation appelés la chaîne. Maintenant, voici juste un prototype pour getchar. Nous aurions vu avant, mais c'est en effet ce qu'il fait. getchar aucun argument, retourne un chevalier. getDouble ne prend aucun argument, renvoie un double. getFloat ne prend aucun argument, déclarations un flotteur, et ainsi de suite. getint est ici. getlonglong est ici. Et GetString est ici. Et c'est tout. Cette ligne violette est une autre préprocesseur directive en raison de l' hashtag au début de celui-ci. Très bien. Alors maintenant, laissez-moi aller dans cs50.c. Et nous n'allons pas parler trop longtemps sur ce point. Mais pour vous donner un aperçu de ce qui est en cours depuis tout ce temps, laissez-moi aller à - faisons getchar. Alors getchar est principalement commentaires. Mais il semble que cela. Donc, c'est la fonction réelle getchar que nous avons été en prenant pour acquis existe. Et même si nous n'avons pas utiliser celui-ci que, souvent, voire jamais, il est au moins relativement simple. Donc, il vaut la peine d' coup d'oeil sur ici. Alors getchar a une boucle infinie, de façon délibérée, apparemment. Il appelle ensuite - et c'est une sorte de belle réutilisation du code, nous nous écrit. Il appelle GetString. Parce que qu'est-ce que c'est dire d'obtenir un chevalier? Eh bien, vous pourriez aussi bien essayer d'obtenir un ligne entière de texte de l'utilisateur, et puis il suffit de regarder une de ces caractères. Dans la ligne 60, voici un petit peu d'un test de cohérence. Si GetString retourné null, il ne faut pas procéder. Quelque chose s'est mal passé. Maintenant, c'est un peu gênant, mais classique dans C. caractères max probablement représente ce qui vient en fonction de son nom? C'est une constante. C'est comme la valeur numérique de l' gros caractères que vous pouvez représenter avec une bouchée, qui est probablement le nombre 255, qui est le plus grand nombre vous représenter huit bits, à partir de zéro. J'ai donc l'utiliser, dans cette fonction, lorsque la rédaction de ce code, uniquement parce que si quelque chose va mal dans getchar mais son but dans la vie est de retourner une char, vous devez en quelque sorte être en mesure pour signaler à l'utilisateur que quelque chose s'est mal passé. Nous ne pouvons pas retourner null. Il s'avère que nulle est un pointeur. Et encore une fois, a getchar pour retourner un chevalier. Ainsi, la convention, si quelque chose va mal, c'est vous, le programmeur, ou en ce cas, moi avec la bibliothèque, j'ai eu un peu arbitrairement décider si quelque chose va mal, je vais retourner le nombre 255, qui est vraiment signifie que nous ne pouvons pas, l'utilisateur ne peut pas saisir le caractère représenté par l' numéro 255 parce que nous avions une bonne affaire, il en tant que valeur dite de sentinelle représenter un problème. Or, il s'avère que le caractère 255 n'est pas quelque chose que vous pouvez taper sur votre clavier, donc c'est pas une grosse affaire. L'utilisateur ne remarque pas que J'ai volé ce personnage. Mais si jamais vous voyez dans les pages de l'homme sur un système informatique une référence à un tous les bouchons constant comme celui qui dit, en cas d'erreur de cette puissance constante être retourné, c'est tout ce que certains humains n'ont il ya quelques années a été arbitrairement décidé d' retourner cette valeur spéciale et appeler une constante dans le cas quelque chose va mal. Maintenant, la magie se produit ici. Tout d'abord, je suis déclarant en ligne 67 deux caractères, C1 et C2. Et puis, dans la ligne 68, il ya en fait une ligne de code qui n'est pas sans rappeler notre ami printf, étant donné qu'il ne disposer pour cent Cs entre guillemets. Mais remarquez ce qui se passe ici. sscanf signifie balayage de chaîne - signifie numériser un format chaîne, sscanf ergo. Qu'est-ce que ça veut dire? Cela signifie que vous passez à SSCANF une chaîne. Et la ligne est tout les types d'utilisateurs po Vous passez à SSCANF une chaîne de format comme ce qui indique quels sont scanf vous en espérant que l'utilisateur a tapé: Vous passez ensuite dans les adresses des deux segments de mémoire, dans ce cas, parce que j'ai deux espaces réservés. Donc, je vais lui donner l'adresse C1 et C2 de l'adresse. Et rappelez que vous donnez à une fonction du adresse d'une variable, ce qui est l'implication? Qu'est-ce que la fonction peut faire à la suite de lui donner l'adresse d'un variables, par opposition à la variable elle-même? Il peut changer, non? Si vous aviez quelqu'un une carte à un physique adresse, ils peuvent y aller et faire tout ce qu'ils veulent à cette adresse. Même idée ici. Si nous passons à sscanf, l'adresse de deux segments de mémoire, même ces petits petits morceaux de mémoire, C1 et C2, mais nous lui disons l'adresse d'eux, sscanf peut changer. Donc, le but de sscanf dans la vie, si nous lisons la page de manuel, c'est de lire ce que l' utilisateur a tapé dans, espoir pour l'utilisateur d'avoir tapé dans un personnage et peut-être un autre personnage, et quel que soit l'utilisateur dactylographié, le premier personnage passe ici, le second personnage passe ici. Maintenant, en aparté, cela, et vous le feriez savoir que ce à partir de la documentation, le fait que je mets un espace vierge, veut juste dire que je ne m'inquiète pas si l'utilisateur appuie sur la barre d'espace de quelques fois avant qu'il ou elle prend une caractère, je vais ignorer tout espace blanc. Donc, je sais de la documentation. Le fait qu'il y ait un second% c suivi par un espace blanc est en fait délibérée. Je veux être capable de détecter si l'utilisateur foiré ou n'a pas coopéré. J'espère donc que l'utilisateur ne tapée dans un personnage, donc j'espère sscanf qui va seulement de retourner le valeur 1 parce que, encore une fois, si je lis la documentation, le but de sscanf en vie est de retourner le nombre d' les variables qui ont été remplis avec une entrée utilisateur. Je suis passé à deux variables adresses, C1 et C2. J'espère, cependant, que seul un des eux est tué parce que si sscanf renvoie 2, ce qui est sans doute l'implication logique? Que l'utilisateur n'a pas juste me donner une personnage comme je lui ai dit ou elle. Ils ont probablement tapé à moins deux caractères. Donc, si je n'ai pas la place au deuxième % C, j'ai juste eu un, ce qui franchement serait plus intuitive approche, je pense qu'un premier coup d'œil, vous n'allez pas être en mesure de détecter si l'utilisateur vous a donné plus entrée que vous vouliez. Il s'agit donc d'une forme implicite de vérification d'erreur. Mais remarquez ce que je fais ici. Une fois que je suis sûr que l'utilisateur m'a donné une caractère, je libérer la ligne, faire à l'opposé de GetString, qui à son tour utilise malloc, puis je reviens C1, le personnage que je souhaitais le fournies par l'utilisateur et fournie seulement. Ainsi, un rapide entrevu seulement, mais des questions sur getchar? Nous reviendrons sur quelques-uns des autres. Eh bien, permettez-moi d'aller de l'avant et de le faire - Supposons maintenant, juste pour motiver notre discussion en une semaine, plus le temps, cette est un fichier appelé structs.h. Et encore, ce n'est qu'un avant-goût de quelque chose qui nous attend. Mais remarquez que beaucoup ce sont des commentaires. Alors permettez-moi de souligner que le partie la plus intéressante pour l'instant. typedef - il ya encore ce même mot clé. typedef nous utilisons pour déclarer chaîne comme un type de données spécial. Vous pouvez utiliser typedef pour créer tout nouveau les types de données qui existaient pas quand C a été inventé. Par exemple, int vient avec C. caractères livré avec C. Double livré avec C. Mais il n'y a aucune notion d'un étudiant. Et pourtant, il serait très utile d'être capable d'écrire un programme qui stocke dans une variable, le numéro d'identification d'un élève, leur nom et leur maison. En d'autres termes, trois pièces de données, comme un int et un chaîne et une autre chaîne. Avec typedef, ce qui est assez puissant à ce sujet et le mot-clé pour sturct structure, vous, le programmeur en 2013, peut réellement définir votre propre l' les types de données qui n'existaient pas ans il ya, mais qui répondent à vos besoins. Et ici, dans les lignes 13 à 19, nous déclarer un nouveau type de données, comme un int, mais l'appelant étudiant. Et à l'intérieur de cette variable va avoir trois choses - int, string, et une chaîne de caractères. Ainsi, vous pouvez penser à ce qui est vraiment arrivé ici, même si c'est un là d'une simplification pour aujourd'hui, un élève est essentiellement va pour ressembler à ceci. Sa va être un morceau de mémoire avec un identificateur, un nom champ, et un champ de maison. Et nous serons en mesure d'utiliser ces morceaux de mémoire et y accéder comme suit. Si je vais dans struct0.c, voici un relativement longue, mais suite à une motif, du code qui utilise cette nouvelle astuce. Alors d'abord, permettez-moi d'attirer votre attention pour les parties intéressantes là-haut. Forte définit étudiants 3, déclare un constante appelée étudiants et ayants droit arbitrairement le numéro 3, juste j'ai donc trois élèves à l'aide ce programme pour l'instant. Voici venir Main. Et remarquez, comment dois-je déclarer un tableau des étudiants? Eh bien, je viens d'utiliser la même syntaxe. L'étudiant de mot est évidemment de nouveau. Mais étudiant, classe, les élèves de support. Donc, malheureusement, il ya beaucoup de réutilisation des termes ici. Ceci est juste un nombre. Donc, c'est à dire trois. La classe est ce que je veux d'appeler la variable. Je pourrais appeler les étudiants. Mais la classe, ce n'est pas une classe dans un orientée objet Java de type moyen. C'est juste une classe d'élèves. Et du type de chaque élément de données dans ce tableau est étudiant. Donc, c'est un peu différent et de dire quelque chose comme ça, c'est juste - Je veux dire, donnez-moi trois étudiants et d'appeler cette classe de tableau. Très bien. Maintenant, voici un quatre boucle. Familier de ce gars - itération de zéro à un maximum de trois. Et voici le nouveau morceau de syntaxe. Le programme va me demandera, l'homme, pour lui donner un étudiant ID, qui est un entier. Et voici la syntaxe avec lequel vous pouvez stocker quelque chose dans le domaine ID à classe Emplacement du support I. Ainsi, cette syntaxe n'est pas nouvelle. Cela signifie simplement me donner la huitième élève de la classe. Mais ce symbole est nouveau. Jusqu'à maintenant, nous avons ne pouvons pas utilisé dot, au moins dans le code comme ceci. Cela signifie aller vers la structure appelée un étudiant et mettre quelque chose là-bas. De même, dans cette ligne suivante, 31, rendez-vous de l'avant et mettre ce que l'utilisateur tape pour un nom ici et ce qu'ils font pour maison, la même chose, aller de l'avant et mettre dans. maison. Alors, qu'est-ce que ce programme en fin de compte faire? Vous pouvez voir un petit teaser là. Permettez-moi d'aller de l'avant et ne fais struct 0 dot slash struct 0, le numéro d'identification de l'élève 1, dire David Mather, étudiant ID 2. Rob Kirkland, étudiant ID 3. Lauren Leverit - et la seule chose que ce programme a fait, qui est juste totalement arbitraire, est Je voulais faire quelque chose avec ces données, maintenant que je nous avez appris à utiliser des structures, c'est que je viens d'avoir cette boucle supplémentaire ici. Je itérer sur l'ensemble des étudiants. J'ai utilisé notre ami, peut-être maintenant familier, comparaison de chaîne, stircomp à chèque est la maison de 8 étudiants égale à Mather? Et si c'est le cas, vous n'avez qu'à imprimer quelque chose arbitrairement comme, oui, c'est vrai. Mais encore une fois, juste me donner des opportunités d'utiliser et de réutiliser et réutiliser cette nouvelle notation de la dot. Alors, qui se soucie, non? Venir avec un programme de l'étudiant est quelque peu arbitraire, mais il s'avère que nous pouvons faire des choses utiles avec C'est, par exemple comme suit. Il s'agit d'une structure beaucoup plus complexe en C. Il a une douzaine ou plus de champs, quelque peu énigmatique nommé. Mais si vous avez déjà entendu parler d'un graphique format de fichier appelé bitmap, BMP, il s'avère que le format de fichier bitmap à peu près ressembler que cela. C'est un petit visage souriant stupide. C'est une petite image que j'ai zoomé sur assez grand pour que je puisse voir chaque des points individuels ou pixels. Maintenant, il s'avère que nous pouvons représenter une point noir avec, par exemple, le numéro 0. Et un point blanc avec le numéro 1. Donc, en d'autres termes, si vous voulez dessiner un Smiley face et à sauver cette image dans un ordinateur, il suffit de stocker des zéros et ceux qui ressemblent à celui-ci, le cas échéant, encore une fois, ceux qui sont blancs et les zéros sont noirs. Et en même temps, si vous avez effectivement un cerceau de uns et de zéros, vous disposez d'un grille de pixels, et si vous posez les, vous disposez d'un mignon petit visage souriant. Maintenant, le format de fichier bitmap, BMP, est efficacement que sous le capot, mais avec plus de pixels sot que vous peut effectivement représenter les couleurs. Mais quand vous avez plus sophistiqué formats de fichiers tels que BMP et JPEG et GIF avec qui vous connaissez peut-être, ceux fichiers sur disque en général pas seulement avoir zéros et de uns pour les pixels, mais ils ont des métadonnées ainsi - méta dans le sens qui n'est pas vraiment données, mais il est utile d'avoir. Ainsi, ces champs sont ici ce qui implique, et Nous verrons cela plus en détail dans P-set 5, qu'avant que les zéros et les uns que représenter les pixels d'une image, il ya un tas de métadonnées comme la taille de l'image et l' largeur de l'image. Et notez que je suis plumer hors certains choses arbitraires ici - largeur et hauteur. nombre de bits et d'autres choses. Donc, il ya certaines métadonnées dans un fichier. Mais par la compréhension de la façon dont les fichiers sont fixées de cette façon, vous pouvez réellement puis manipuler des images, récupérer des images à partir du disque, redimensionner les images. Mais vous ne pouvez pas nécessairement améliorer. J'avais besoin d'une photo. Je suis donc retourné à RJ ici, qui vous avez vu sur l'écran il ya un certain temps. Et si j'ouvre Keynote ici, c'est ce qui se passe si vous essayez d'effectuer un zoom avant et améliorer RJ. Il a pas mieux faire vraiment. Maintenant Keynote est une sorte de flou un peu, juste pour dissimuler le fait que RJ n'obtient pas particulièrement améliorée lorsque vous zoomez po Et si faire de cette façon, voir les places? Oui, vous pouvez certainement voir les carrés sur un projecteur. C'est ce que vous obtenez lorsque vous améliorer. Mais pour comprendre comment notre RJ ou l' Smiley face est mise en œuvre va nous permettre réellement écrire du code qui manipule ces choses. Et j'ai pensé que je finirais sur cette note, avec 55 secondes d'une améliorent c'est, J'ose, disons plutôt trompeur. [LECTURE VIDEO] -Il ment. À propos de quoi, je ne sais pas. -Alors, que savons-nous? -C'est à 9:15 Ray Santoya était à l'ATM. -Donc la question est ce que faisait-il à 09h16? -Tirer le neuf millimètres à quelque chose. Peut-être qu'il a vu le sniper. -Or a été de travailler avec lui. -Attendez. Remonter d'un. -Que voyez-vous? -Apporter son visage vers le haut, en plein écran. -Ses lunettes. -Il ya une réflexion. -C'est l'équipe de baseball Neuvitas. C'est leur logo. -Et il parle à celui qui est porter cette veste. [FIN LECTURE VIDÉO] DAVID J. Malan: Ce sera être réglé de problème 5. Nous vous verrons la semaine prochaine. INTERVENANT: À la prochaine CS50. [Grillons] [Jouer de la musique]