[Jouer de la musique] DAVID J. Malan: Cela ressemble un séminaire de première année aujourd'hui. D'ACCORD. Donc très pluvieux sur. Cette tendance à se produire le mercredi, mais d'autant plus l'occasion Pour des questions aujourd'hui. Donc, nous allons commencer effectivement avec le film dans un instant. Mais nous allons commencer pompeusement comme toujours. Ceci est CS50, et cela est la fin de la semaine 4. Donc, si vous avez déjà regardé TV ou un film dans lequel des il ya certains experts informatiques et la police, ou le FBI, ou une agence est d'essayer de prendre un peu adversaire, eh bien, vous avez probablement entendu l'expression "améliorer" lequel que technicien en quelque sorte zooms par magie dans l'infini loin pour voir les criminels identité ou le numéro de la plaque d'immatriculation même dans le miroitement d'un miroir ou l'éclat de l'œil de quelqu'un. Donc, en effet, nous allons jeter un oeil à quelques telles scènes de Hollywood. [LECTURE VIDÉO] -OK, Maintenant nous allons obtenir un bon oeil à vous. -hold Il. Exécutez ce retour. -Attendez une minute. Aller à droite. -Il, Geler cela. -Plein écran. -OK, Geler cela. -Serrez Là-dessus, allez-vous? En ce que sur -vector gars par la roue arrière. -Zoom En droit ici à cet endroit. -Avec Le bon équipement, l'image pourrait être élargie et aiguisé. -Qu'est ce que c'est? -C'est Un programme d'amélioration. -Peut-On clair que jusqu'à tout? -Je ne sais pas. Disons améliorer. -Améliorez Section A6. -I Amélioré le détail, et-- Je pense qu'il ya assez pour améliorer, relâchez-le pour mon écran. -I Amélioré le reflet dans les yeux. -LET Est géré par cette amélioration vidéo. -Edgar, Pouvez-vous améliorer ce? -Attendre. -J'ai Travaillé sur cette réflexion. La réflexion de -Quelqu. -Réflexion. -Il Ya une réflexion du visage de l'homme. -La Réflexion. -Il Ya une réflexion. Dans -Zoom sur le miroir. -Vous Pouvez voir un reflet. -Peut Vous améliorez l'image à partir d'ici? -Peut Vous l'améliorer ici? -Peut-Vous améliorer? Pouvez-vous améliorer? -Peut-On améliorer ce? -Peut-Vous améliorer? -hold Sur une seconde, je vais améliorer. -Zoom Dans la porte. -Times 10. -Zoom. -Emménager. -Plus. Attends, arrête. -Arrêtez. -PAUSE Il. Nous -rotate 75 degrés autour de la verticale, s'il vous plaît. -Arrêtez. Retour à la partie sur la porte, à nouveau. -Got Un amplificateur d'image qui peut bitmap? Hé, peut-être nous pouvons utiliser la Pradeep Méthode Sen de voir dans les fenêtres. -Ce Logiciel est l'état de l'art. -La Valeur propre est éteint. -Avec Le droit combinaison de algorithm-- Pris l'élimination de -Il algorithmes au niveau suivant, et je peux les utiliser pour améliorer cette photo. -lock Sur et agrandir l'axe z. -Améliorez. -Améliorez. -Améliorez. -Freeze Et améliorer. [FIN LECTURE] DAVID J. Malan: Très bien, alors tous ceux qui sont en fait des mots. Ils sont juste enchaînés dans un manière qui est pas réellement sensible. Et, en fait, CS50 et cours comme il tend à ruiner beaucoup de télévision et des films pour toi. Parce que quand ces experts en informatique sont débiter termes et dire les choses de fantaisie comme vecteurs propres, et l'axe z, et un nombre quelconque d'autres effectivement termes plus techniques, ils sont vraiment juste enfiler mots ensemble trop souvent. Est-ce que l'un de nos espoirs est que, comme un effet secondaire de suivre des cours comme ce sera, plus de gens dans le monde être effectivement en mesure de peser et juste très légèrement influencer le qualité et la précision de ces films? En fait, nous allons jeter un oeil à la réalité. Donc, voici la photo de personnel Marie, l'un de nos compagnons d'enseignement. Et si elle est soupçonné de quelque chose. Et pourtant, il ya une lueur d' certains éléments de preuve dans les yeux, ou dans la réflexion de ses lunettes. Eh bien, si nous faisons exactement comme les films proposer, dans laquelle on zoome et «améliorer», cela est la quantité d'informations est dans le visage de Marie lorsque vous capturez une image avec la résolution d'origine. Et, en fait, vous pouvez voir ces points. Et ce sont eux qui sont appelés pixels, P-I-X-E-L-S, qui est juste un carré généralement qui est un point qui compose une image. Et retour dans la journée, et effectivement, même aujourd'hui avec certains des téléviseurs LED d'aujourd'hui ou les téléviseurs LCD, si vous avez l'un dans votre chambre ou à la maison, si vous montez super proche de lui, et surtout si elle est une télévision un peu plus âgés, vous pouvez probablement même voir ces points et que est ce que composer une image. Et il n'y a plus informations que cela. Nous pourrions «améliorer», dans le sens de arrondir les angles et une sorte de inférer sorte de, en quelque sorte ce que couleur doit être à côté de l'œil de Mary de sorte qu'il est pas en fait si pixélisé. Mais si je continue zoom avant, il est le méchant dans son oeil. Comme cela est d'autant informations dont nous disposons. Vous ne pouvez pas créer informations à partir de rien. Il ya seulement un ensemble fini nombre de bits là. Donc, dans le problème Set 4, où vous avez l'occasion à jouer avec ce genre de monde. Dans problème Set 4, vous pourrez explorer la monde du graphisme, et la médecine légale, et effectivement écrire du code qui récupère des images perdues. Vous allez écrire du code qui manipule des images existantes et finalement comprendre ce qui est passe sous le capot. Et, il se trouve, il est effectivement pas si compliqué que ça. Par exemple, si nous voulions représenter un visage souriant où avec ces pixels noirs, ou ces points noirs, Eh bien, nous ne pouvions tout simplement représenter comme vraiment un bitmap. Et si vous aviez déjà entendu dire que bitmap d'expression, peut-être il commence maintenant à faire un peu plus de sens aujourd'hui. Nous savons déjà ce qui est un peu. Il est 0 ou 1. Et une carte est juste quelque chose comme un morceau de papier qui vous donne les directions et a peut-être une grille de coordonnées x et. Donc, voici une image bitmap. Il est une carte de bits grâce à quoi un 1 est apparemment va représenter un pixel blanc, et un 0 va représenter un pixel noir. Mais nous pourrions certainement retourner autour. Il ne compte pas vraiment si Tant que nous sommes cohérents. Et voici comment, à l'intérieur binary-- de la mémoire d'un ordinateur, ou même à l'intérieur d'un fichier sur votre disque drive-- pourriez-vous stocker le plus simple des images de visages souriants. Mais que sommes-nous, bien sûr, manque dans cette image? Couleur, non? Il est une prochaine étape évidente ou amélioration pour améliorer la couleur. Donc, malheureusement avec un seul bits, 0 ou 1, on pourrait représenter la couleur. Cela pourrait être rouge, ou bleu, ou noir, ou blanc, ou vert, ou rose, ou des paires de couleurs. Mais pour des raisons de simplicité, nous allons simplement supposer noir et blanc. Alors, que devons-nous logiquement si nous vouloir mettre en œuvre couleur dans une image? Qu'avons nous à faire? Comme si le facteur limitant ici est que, avec un peu vous pouvez seulement représentent deux états, 0 ou 1, blanc ou noir, que voulez-vous faire? Audience: plus de données. DAVID J. Malan: plus de bits, ouais plus de données, plus de bits. Et, en effet, que est exactement comment images couleurs sont représentées. Plutôt que d'utiliser un seul bit, un 0 ou 1 pour chaque pixel, chaque point, vous utilisez simplement multiple. Peut-être utiliser 8, peut-être, plus communément utiliser 24, et en effet, dans le problème Set 4, allez-vous jouer avec un fichier format qui utilise typiquement 24 bits. Mais la plupart d'entre vous sont sans doute familier avec les fichiers JPEG. Si vous avez déjà pris une photo de votre téléphone, ou téléchargé ou vu quelque chose sur Facebook, Flickr ou, tout nombre des sites web à base de photos, vous avez probablement vu une image JPEG avant. Et il se trouve, cela est le fichier format que nous allons utiliser dans PSet 4, par lequel vous allez avoir à récupérer des images que je l'ai accidentellement supprimé à partir d'un corrompu carte de mémoire dans l'appareil, si vous voulez. Et il se trouve que, même si JPEG est assez sophisticated-- il est beaucoup plus sophistiqué que les points noirs et blancs nous avons vu il ya un instant, parce qu'il ya algorithmes de fantaisie qui fait sont utilisés pour compresser un fichier JPEG, afin que vous pouvez avoir une très belle, qualité d'image, mais en utilisant relativement peu de bits. Et nous y reviendrons compression avant longtemps. Il se trouve que la première trois octets dans un image-- JPEG peu importe ce que vous avez pris une photo de-- sont les valeurs 255, 216, 255. En d'autres termes, si vous venez de voir ce modèle de bits, ici représenté comme trois octets ou 24 bits au total, avec une forte probabilité, vous pouvez en déduire que vous cherchez les choses de cette trois premiers octets d'un JPEG. Et ceci est ce qui est connu que la signature d'un JPEG. Un grand nombre de formats de fichiers là-bas ont tendance à commencer avec certains modèles de 0 et de 1, afin que Windows et Mac OS et iOS, et de savoir ce que les applications du type de fichier sont, en plus du fichier que l'on appelle l'extension que beaucoup de dossiers ont. Si vous avez .jpg, qui est un autre indice à l'ordinateur. Donc, nous allons maintenant examiner cette un peu plus technique. Nous savons la décimale système est de 0 à 9. Nous savons binaire est 0 et 1. Et si vous repensez à PSet 0, nous avions vous luttez avec, pour un peu, quelque chose appelé hexadécimal, où vous avez 16 chiffres, au lieu de 10 ou au lieu de deux. Et ces chiffres, par convention, sont 0 à 9, puis une à f, où f représente ce nombre décimal, tout comme un bon sens rapide vérifier? Donc, 15. Et une doit représenter 10, juste en nature de l'ordre que je vous ai donné. Il est juste une convention arbitraire, mais il est tout à fait standard. Donc, si nous regardons ce modèle trois bytes-- de laisser il suffit de commencer à regarder dans d'une manière compatible avec la façon dont d'informaticiens en général regarder et de réfléchir sur les fichiers. Vous pouvez certainement penser fichiers dans des 0 et des 1, et décimal, mais en réalité, nous avons tendance à utiliser binaire ou plus généralement hexadecimal-- retour de PSet 0. Alors permettez-moi propose que 255, 216, et 255 sont seulement ces schémas de 0 et de 1. Et vous pouvez le vérifier si vous vouloir faire le calcul de la Semaine 0. Mais, pour l'instant, simplement supposer que tel est bien correcte. Je viens réécrit trois virgule numéros que trois valeurs binaires. Maintenant, ce que je vais faire est il suffit d'ajouter un peu d'espace blanc, juste pour l'amour de la lisibilité. Et remarquez, je vais juste faire avancer les choses en dehors. Donc, avant, après, avant, après. Je ne suis rien d'autre intéressant faire que juste répandre les choses de telle sorte que l'avis de chaque ensemble de huit bits est maintenant deux ensembles de quatre bits. Ceci est utile car hexadécimal est particulièrement à la mode parce que chaque chiffre hexadécimal de 0 à f, ou plus précisément de 0 à 15, peuvent être représentés avec exactement quatre bits. En d'autres termes, si vous en hexadécimal veut représenter un 0, il est juste 0000, quatre zéros. Et si vous voulez représenter 15, il est 1111, qui est de quatre bits. Et si vous faites le calcul, si cela est le lieu de ceux, cet endroit est de plus de 16, que ça va donner vous-- plutôt que ça va to-- désolé, en binaire, cela va vous donner 15, les place, Twos endroit, quatre ou huit lieu. Donc, je vous propose que ce un ensemble de quatre bits sur la gauche est ce que nous allons appeler f. Il est le plus grand nombre que vous peut représenter avec quatre bits. Et nous savons déjà hexadécimal, f est la plus grande chiffres en hexadécimal. Nous avons une autre f il, deux de plus là-bas. Et pour l'instant, il suffit de prendre sur la foi que je l'ai fait le droit de maths et que la moitié gauche de ces bits, 1101, est la même chose que d en hexadécimal. Et la main droite, 1000, est à seulement 8. Et celui-là est facile à voir, non? Le 8 represents-- est juste dessous de cet endroit huit. Nous avons donc l'un dans la colonne de huit et rien dans les pattes, deux ou petits. Alors maintenant, plus classiquement, les humains ont tendance pour écrire des chiffres hexadécimaux de ce genre, vous squish juste leur ensemble, et puis vous les préfixe 0x. Cela signifie rien d'autre que un indice visuel à un human-- voici un value-- hexadécimal parce il pourrait ne pas en être autrement évidente. Ce qui veut dire, en définitive, le modèle de zéros et de uns, ou le modèle de hexadécimal chiffres équivalente que vous êtes va commencer à chercher dans le problème Set 4 est this-- et le problème Set 4 spec sera marcher vous à travers ce dans plus detail-- mais comme une sorte de réaliser des arcanes comme ce pourrait ressembler à première vue, vous allez commencer à voir ce lot. Et en fait, même dans GDB, la débogueur, nous avons introduit le lundi et Dan introduit dans PSet 3, va vous montrer souvent des valeurs hexadécimaux juste parce qu'ils ont tendance à être plus conventionnelle que décimale ou binaire dans le monde de l'informatique. Maintenant, nous allons mettre cela en contexte. Beaucoup d'entre vous souvenez peut-être de cette image ici, qui venait de quoi? Vista, donc même plus tôt que que Windows XP a fait ce premier. Alors ceci est un beau paysage. Et en fait, si vous fouillez online-- Je pense qu'il est un article de Wikipedia, dans laquelle quelqu'un est allé très étonnamment sur trouvé cet endroit dans le monde mis en place sa caméra dans précisément le droit place-- et cela apparaît aujourd'hui mais like-- il est exactement le même réglage. Cette image, cependant, est dans un fichier format appelé bitmap, b-m-p. Et nous allons prendre un super- rapide coup d'œil à ce que cela signifie. Mais bitmap est juste une façon différente de images représentant encore l'aide de pixels à 0 et de 1, en fin de compte. Mais au coup d'œil rapide, il a une signature plus intéressant au début du fichier. Il ne suffit pas de trois octets, plutôt il est tout un tas de modèles d'octets qui ont prédéterminée sens. Par exemple, quelque part dans le quelques premiers octets d'une image bitmap va être la taille de la l'image, la largeur de l'image, la hauteur de l'image, de sorte que métadonnées utiles, si vous voulez. Informations pratiques que Photoshop ou tout programme graphique vous utilisez pourrait réellement se soucier. Donc plus à ce sujet dans Problème Set 4, mais cette est seulement pour dire que à la fin de la journée tous les formats de fichiers que vous avez utilisé pour les fichiers Microsoft Word années--, Les fichiers Numbers, fichiers Excel, un certain nombre de formats de fichiers qui peut avoir une certaine extension de fichier connu sont seulement 0 et 1 sous le capot. Et les humains ont décidé ce sont les conventions, quels sont les modèles de 0 et de 1 représentent un fichier Word par rapport à un fichier Excel, par rapport à un certain nombre d'autres formats de fichiers. Donc, en PSet 4, vous aurez une possibilité de jouer avec cela. Mais qu'est-ce que cela signifie d'avoir une structure. Ceci est en fait une belle transition maintenant en C, qui ne dispose que d'un couple caractéristiques supplémentaires que de nous avons pas regardé encore. Il est un joli petit langage et l'un des les fonctionnalités intéressantes au sujet de C est une struct. Par exemple, si vous voulu qu'elle représente: nous allons dites-vous voulu avoir une variable qui représente un étudiant dans un programme. Peut-être que vous écriviez un cours programme d'enregistrement, ou noyau achats outil, ou quelque chose comme ça. Qu'est-ce sont des morceaux de données relatives à un étudiant qui viennent à l'esprit? Comme un étudiant est représenté avec quelles valeurs? Ouais? Vous avez un nom en tant qu'étudiant. Quoi d'autre ne possède un étudiant typique? AUDIENCE: [inaudible] DAVID J. Malan: Alors, désolé. AUDIENCE: Age. DAVID J. Malan: Un âge ou anniversaire équivalente, yep. Quoi d'autre? PUBLIC: numéro d'identification? DAVID J. Malan: Donc, un numéro d'identification, peut-être un numéro de téléphone, peut-être un dortoir, ou une maison, ou au collège, ou quelque chose comme ça. Un nombre quelconque d'éléments de données qui vous pourriez avoir dans votre liste de contacts est ce qui pourrait définir un étudiant. Donc, si nous voulions faire cela, dans le code, nous pourrions faire quelque chose de simple comme ça. Nous pourrions avoir un programme de telle sorte que a disons, int main (void). Et si je veux représenter un étudiant, je pourrais avoir, par exemple, une chaîne appelée nom pour cet étudiant, une chaîne appelée dortoir pour cet étudiant, peut-être un int appelé ID pour cet étudiant. Et parce que je suis l'aide de ficelle, je besoin de revenir en arrière et mettre en place CS50.h. Peut-être que je vais avoir besoin de stdio.h. Alors permettez-moi de faire ces préventivement et je suis va appeler cette student.c pour l'instant et sauver ce. Et maintenant, je peux faire quelque chose avec ces variables. Et nous allons juste pour écrire que comme un commentaire dans le code de pseudo, parce qu'il est pas intéressant ce que nous faisons pour le moment. OK, donc ce est un programme qui stocke en quelque sorte un étudiant. Qu'est-ce que je veux faire si je vouloir stocker deux étudiants? Donc, mon premier instinct va être tout droit, attendez une minute, si je dois un autre étudiant Pourquoi je ne just do nom de la chaîne 2, chaîne dortoir 2, int ID2. Et nous avons fait parti dans cette voie avant et ce qui était notre solution à ce qui semble à être une sorte de pâte de copie hackish travail ici? PUBLIC: Un tableau. DAVID J. Malan: Ouais, nous pourrions utiliser un tableau. Droite très rapidement devient difficile à manier. Vous devez trier de façon arbitraire commencer à nommer toutes ces variables. Et vous, l'humain, devez garder piste correspondant OK de NOM2 avec dorm2 correspond à id2. Il devient tout simplement un gâchis. Donc, il est beaucoup plus facile, rappeler à partir il ya quelques semaines, juste avoir à noms appelés à cordes et peut-être nous donner trois de ceux-ci. Et puis peut-être que nous avons dortoirs à cordes et ont trois d'entre eux, ou avec une constante, int identifiants et ont trois de ceux-ci. Mais même maintenant cela se sent un peu bâclé, à droite. Nous parlons d'étudiants et encore Je suis vraiment insister sur le faible niveau détails d'implémentation. L'étudiant est un nom et un dortoir et ID. Pourquoi ne puis-je déclarer une variable appelé étudiant et l'appeler l'art. Et si je veux un autre étudiant, pourquoi ne pas tout simplement l'appelle t. Ou si je veux tout un tas des étudiants, pourquoi fais-je pas simplement Je dois dire que toute une classe de étudiants, et il est trois d'entre eux. En d'autres termes, pourquoi je ne peux pas venir avec mon propre type de données, appelé Les étudiants, qui est de l'intérieur un nom, est une pièce d'identité, est un dortoir, est un nombre quelconque d'autres domaines. Et il se trouve que vous peut faire exactement cela. Donc C dispose de cette fonctionnalité appelée struct. Voilà un dispositif de langue nous permet de faire exactement cela. Je vais aller de l'avant et d'ouvrir structs.h où nous allons voir le la définition suivante d'un étudiant. Il se trouve - et celui-ci est encore plus simple que celui impliquant un ID il y a un moment. Si vous voulez venir avec votre type de données maison, et en plus de int, et l'omble chevalier et flotter et tous ces autres qui existent, vous pouvez le faire par lettre écrit typedef struct, puis quelques accolades, l'intérieur de laquelle vous énumérer les variables que vous voulez associer à cette nouvelle données personnalisées taper comme un nom et un dortoir, et puis après les accolades vous donnez un nom au nouveau type de données. Ainsi, par exemple, étudiant. Et ce qui est bon à ce sujet maintenant est que si nous regardons le code correspondant, la convention, première de tous, est de mettre cette dans un fichier appelé quelque chose dot h, un fichier d'en-tête, que nous avons pas commencé à nous d'utiliser trop. Mais nous allons commencer en utilisant un peu maintenant. Et ce que nous pouvons faire avec cela, en fin de compte, dans ces quelques lignes de code est déclarer exactement cela type de données, un étudiant. Et maintenant, nous allons l'utiliser. Je vais y aller maintenant en un fichier appelé structs1.c. Et nous allons jeter un oeil à un quelques caractéristiques ici. Donc le truc ici est la plupart du temps familier, et nous allons revenir à ce qui est pas familiers dans un instant. Bien sûr, cela est y compris le mien fichier en-tête, ce qui est nouveau aussi, sauf pour PSet 3 où, rappel, nous avons helpers.h. Donc, vous pourriez rappeler helpers.h #include. Pourquoi si je utilise citations au lieu de chevrons? Quand dois-je choisir entre les deux? Presque toujours il me semble d'utiliser des chevrons. Et puis, tout d'un coup sur ligne six ans, je suis en utilisant des guillemets doubles. Pourquoi pourrait-il être? Ouais? AUDIENCE: [inaudible] DAVID J. Malan: Voilà une réelle, quoi? AUDIENCE: qui est dans votre IDE. DAVID J. Malan: Ouais, qui est dans mon IDE réelle. Et il ne faut pas insister sur les IDE, parce qui est juste un outil que je suis en utilisant. Voilà à mon actuelle répertoire, spécifiquement. Donc structs.h est mon propre fichier pas installé dans l'IDE, dans le système d'exploitation lui-même, plutôt il est dans mon répertoire courant. Donc, la convention est si vous voulez d'inclure votre propre fichier d'en-tête, il suffit d'utiliser des guillemets. Comment appelons-nous cette chose dans la ligne 8, de manière générale? C'est quoi? quelque chose #define. Cela représente constantes, non? Si vous voulez avoir un valeur dans votre programme que vous utilisez un ensemble tas de fois, il est bonne convention à tenir dehors, déclarer, avec le symbole de hachage définir, puis, par convention, dans tous les majuscules word-- si elle est pas strictement nécessaire, mais il est convention humaine de capitaliser constantes de sorte qu'ils sautent à l'espace et vous visually-- alors la valeur que vous voulez être équivalent du nom de cette constante. Aucune virgule, mais vous simplement suivre ce schéma là. Alors qu'est-ce que je fais dans ce code réel. Donc, nous allons jeter un oeil à le programme principal ici. Dans la ligne 12, parce que je ont inclus structs.h, Je dois maintenant magie à mon disposition un nouveau type de données. Je ne dois pas seulement l'accès à l'int, et char, et le flotteur, et la chaîne, et bleu et d'autres. Je dois maintenant accès à un type de données de l'étudiant. Donc, à la ligne 12, je suis combinant deux ideas-- un type de données personnalisé et deux, utilisant un tableau. Et donc dans ce programme si Je veux soutenir effectivement trois élèves différents dans mon programme, je peut dire simplement me donner une variable appelés étudiants, dont chacun est des étudiants de type, qui est mon type de données personnalisé. Et, en particulier, donne-moi trois de ceux dans mon tableau. Alors maintenant, que faisons-nous dans ce programme? Voici juste une boucle itération 0-3, parce que ce quelle est la valeur des étudiants est. Je suis juste invitant l'utilisateur me donner le nom de l'étudiant. Et puis dans la ligne 17, nous avoir une ligne plus souvent familier. Nous avons notre vieil ami GetString sur la droite. Et ce morceau de syntaxe est apparemment nouvelle, si vous ne l'avez jamais programmé en C avant, et n'a jamais utilisé les structs? Ouais? AUDIENCE: Le .name. DAVID J. Malan: Le .name. Mais ce ne sont pas trop d'un saut, parce que maintenant les étudiants Patte I vous donne l'étudiant i-ème. Et si vous voulez plonger à l'intérieur de cette structure, il suffit d'utiliser une seule période et puis le nom de la variable à l'intérieur, ou la propriété à l'intérieur qui vous voulez avoir accès à. De même, puis, si je puis l'invite utilisateur, donne-moi le dortoir de l'étudiant, vous pouvez stocker de façon similaire que chaîne dans la variable de dortoir à l'intérieur de cette structure de l'étudiant. Et maintenant, les choses deviennent un peu de fantaisie. Et cela va se pencher au peut-être beaucoup assez rapidement. Mais vous verrez ce beaucoup plus dans PSet 4, afin de laisser tout regard à lui maintenant. Il se trouve que dans la ligne 23 par le biais 38, que pensez-vous que je peut faire? Je l'ai enlevé les commentaires pour aujourd'hui, mais la version du code en ligne pour référence a tous les commentaires. Que dois-je semblent faire? AUDIENCE: Sauvegarde du fichier avec toutes les informations que l'utilisateur a entré. DAVID J. Malan: Ouais, exactement, cela est une nouvelle façon que nous voyons deux, une autre caractéristique de C, par lequel je peux créer mes propres fichiers. Jusqu'à présent, presque tous les programmes Vous avez écrit est apatride. Dès qu'il a fait courir, ça y est. Il n'y a pas de mémoire ou souvenir. Il n'y a pas fichier enregistré. Mais si vous ne voulez sauver entrée qui a passé, comme dans un jeu ou un programme comme ça, il se trouve que nous pouvons le faire. Et vous verrez cela plus dans PSet 4 et à la section. Mais cette ligne 23 essentiellement crée un fichier appelé students.csv. Et vous pourriez avoir vu cela avant. Même si vous ne l'avez jamais étudié CS avant, CSV est des variables séparées par des virgules. Il est comme un homme très pauvre de version d'un fichier Excel, ce qui signifie qu'il peut être ouvert dans Excel et en chiffres d'Apple, et il comporte des rangées et des colonnes. Mais il est pas un propriétaire format comme Microsoft ou Apple. Il est juste virgules séparant la valeurs que nous verrons dans un instant. Et il suffit de prendre une supposition. Dans la ligne 23, à la très fin, mon second argument à cette nouvelle fonction appelée f ouverte pour le fichier ouvert est w. Ce qui pourrait désigner w? Ouais? PUBLIC: Il vous permet d'écrire dans le fichier? DAVID J. Malan: Il permet de vous écrivez dans le fichier. Donc, il ya un couple de variantes que nous pouvons brancher ici. Mais si vous voulez juste lire le fichier, qui est de regarder ce et le lire dans la mémoire, vous il suffit d'utiliser entre guillemets "r". Si vous voulez écrire à la fichier, vous utilisez entre guillemets "w". Il ya également ajouter et un couple d'autres choses si vous souhaitez modifier des fichiers existants. Maintenant, nous allons continuer à voir cette chose, alors nous reviendrons à la ligne 24. NULL, il se trouve, est une valeur spéciale qui peut être retourné par certaines fonctions si quelque chose est allé wrong-- si ne pas le fichier existe, si vous avez plus de mémoire, ou un tas d'autres erreurs. Mais pour l'instant, supposons simplement que cette est la vérification d'erreur juste conventionnelle. Ici, à la ligne 26, je suis itération 0-3 sur tous mes étudiants. Et cela est une sorte de tri d'une nouvelle fonction, fprintf, mais juste prendre une proposition. Si printf est juste Imprimer une chaîne formatée, ce qui ne signifie probablement fprintf? AUDIENCE: Imprimer dans un fichier. DAVID J. Malan: Imprimer une chaîne formatée dans un fichier. Voilà ce que l'supplémentaires des moyens de f est un fichier. Et le nouveau premier argument doit être la variable qui représente votre fichier. Ensuite, nous avons juste un format chaîne comme printf. Et même si cette la syntaxe est nouveau, ce juste des moyens de brancher le nom de l'étudiant, plug-in de la résidence étudiante, puis avec fclose, fermez le fichier. Et puis lastly-- cela est nouveau et nous reviendrons à cette avant long-- Je libérant l'étudiant pour des raisons qui est arrivé là-haut. Mais nous reviendrons à celle d'avant long-- qui est à cause de la façon dont est GetString travailler effectivement sous le capot. Donc, nous allons jeter un coup d'oeil ici. Si je tape ls dans mon répertoire, remarque que je ne fais pas avoir un fichier appelé students.csv, tout simplement pas là, ne pas exister. Donc, si je compile maintenant ce programme, faire structs-1,. / structs-1, et je vais aller de l'avant et tapez Andi, qui vit à Berkeley à Yale. Nous allons avoir Rob qui vit en Thayer ces jours. Et nous allons venir avec où est, je pense, Maria est à Mather, si je me suis souvenu correctement. Donc, rien ne semble se produire. Mais si je tape ls maintenant, il est students.csv. Allons de l'avant et students.csv ouverte. Ceci est encore une très format de fichier léger. Mais je suis tout simplement adopté une convention que je ai deux lignes et de colonnes ici. La première colonne est premiers noms des personnes. La deuxième colonne est l'élève de dortoir, ou au collège, ou une maison, ou autres joyeusetés. Et maintenant, je suis sauvé cette de façon permanente dans un fichier. Donc, il est pas tout à fait intéressant. Mais ceci est juste un tremplin maintenant d'être capable de persister informations de façon permanente. Voyons donc maintenant ce que nous pouvons faire de ces et d'autres caractéristiques. Mais d'abord, des questions? Ce fut beaucoup, et qui a été rapide. Mais vous verrez beaucoup plus PSet 4, ainsi. Ouais? Public: Y at-il un moyen de continuer à ajouter des noms à ce fichier? DAVID J. Malan: Bonne question. Y at-il un moyen de continuer d'ajouter des noms à ce fichier? Oui. Et, en fait, si vous finissez jusqu'à la réouverture du dossier, vous devez utiliser devis Ils ont dit «un» pour l'ajout, qui vient ajouter une nouvelle ligne, un nouvelle ligne encore et encore, exactement. Bonne question. D'autres questions? Ouais? Public: Si vous avez exécuté le programme à nouveau en ce moment, serait-il continuer à ajouter des noms à la fichier ou serait-il ouvrir un nouveau fichier? DAVID J. Malan: Ah, bonne question. Si vous avez exécuté le programme à nouveau droit maintenant, peut-être tapé dans de nouveaux noms, serait-il ajouter au fichier ou écraser le fichier? Celui-ci, parce que je suis ne pas utiliser le mode append. Et parce que je suis aveuglément ouvrir le fichier pour l'écriture, il va juste pour écraser le fichier. Donc, je voudrais en effet besoin de faire est de joindre, si je veux avoir fait un long terme base de données. Maintenant CSV est utile, franchement, même car, comme si vous êtes writing-- et nous finirons par voir cette plus tard dans le semestre lorsque nous utilisons CSVs à d'autres fins. Si vous souhaitez stocker toutes les personnes qui se sont inscrits pour un événement, ou signé pour votre étudiant groupe, ou quelque chose comme ça, stocker les données dans ce genre le format est super pratique. Parce que littéralement, si je étaient pour télécharger ce fichier. Je pourrais double-- et nous allons effectivement essayer cette si je dois Excel ou Numbers ici. Je vais clic-droit ou Ctrl-clic mon dossier. Oups. Faites un clic droit ou Ctrl-clic mon dossier. Allons, ma souris ne coopère pas. Download-- je vais télécharger tous les fichiers ici si juste pour que je peux saisir celui-ci. Et nous allons voir si cela fonctionne students.csv-- première fois Je ai activé. Maintenant, ils veulent voir mes contacts. Maintenant, je dois enregistrer. Voyez comment il est facile à utiliser CSV? Oui, le garder à jour. OK, maintenant nous sommes prêts pour la classe. OK, oh, ce qui est nouveau? OK, fermez. Ce fut magique. OK, maintenant, nous devons mettre à jour. Et maintenant, il a oublié ce fichier I ouvert à l'origine, mais ce qu'il y A-- nous allons. OK, alors maintenant nous avons un fichier Excel. Merci. OK, donc ce que je faisais était la partie facile. Bien sûr, je pourrais avoir pré-installé Excel ou Numbers, ou quel que soit le programme. Mais cela est agréable, parce maintenant je peux manipuler les données dans un format standard. Le contexte Alors maintenant, laissez- passer à l'endroit où nous nous sommes quittés la dernière fois, qui devait commencer à décoller les roues de formation. Mais d'abord, vous ne l'avez pas voir ce déjeuner tôt est de nouveau qui se passe ici à feu et à Ice à Cambridge, Sitar à New Haven. Inscrivez-vous sur le site CS50s ASAP à rejoindre les étudiants et le personnel CS50. Nous avons donc pris des roues de formation hors le lundi comme follows-- chaîne a été déclarée dans CS50s bibliothèque pendant un certain temps. Et il est bon, car elle permet nous parlons des variables comme étant mots et des phrases complètes et plus encore. Mais il se trouve chaîne ne existe pas. Cela est juste un synonyme, ou un alias, que nous avons créé quelque chose qui est en fait un peu plus technique appelle un char *. Et en effet, nous avons vu un exemple d'un programme le lundi qui ne se comportent pas tout à fait ce que nous attendions. Ce fut le fichier, comparez-0. Et rappelons que compare-0, si Je recompile le programme de lundi et exécutez-le comparer 0 et tapez maman dans minuscules, et maman en minuscules nouveau. Le programme insisté pour que je taper des choses différentes, même si maman, tout en minuscules, est identique visuellement. Alors quelle est la réponse courte pourquoi l'ordinateur pense ces deux chaînes sont différentes? Ouais? AUDIENCE: [inaudible] DAVID J. Malan: Droit. Alors, maman, la première fois Je tape dedans, est d'être stocké quelque part dans mon ordinateur de mémoire mais dans un emplacement différent que la deuxième fois que je tape dans maman. Maintenant, il pourrait certainement être optimisé. L'ordinateur peut être intelligent et réaliser ces deux chaînes, hey, ils sont identiques. Permettez-moi de ne pas redondante stocker. Mais les ordinateurs ne font pas cela l'optimisation, sauf si vous leur dire de. Donc, par défaut, ils sont tout va finir à deux endroits différents dans la mémoire. Et pour être plus clair, quand nous avons comparé les deux chaînes, Le premier a été appelé S, la seconde a été appelé t, ce qui a été spécifiquement je comparer ici sur la ligne 13? Ouais. PUBLIC: Il est l'endroit dans la mémoire la variable qui pointera vers. DAVID J. Malan: Exactement, je était comparant la place dans la mémoire que ces variables souligné. Donc spécifiquement, si maman était à nombre d'octets 1 et 2, et 3, et 4-- souviens parce que la barre oblique inverse 0 doit être tout le chemin à la fin. Et l'autre instance de maman, m-o-m, était à l'adresse 10, 11, 12, et 13. Je comparais 1, cette adresse, cet emplacement en mémoire, contre 10, ce qui est évidemment pas les mêmes. 1 est pas 10. Donc, ce qui est agréable dans il est assez simple. Mais il est problématique dans la mesure où nous ne pouvons pas sembler pour comparer des chaînes. Donc fundamentally-- et à ce faible niveau, si vous vouliez mettre en œuvre un programme pour comparer deux mots distincts que le l'utilisateur a tapé dans la qualité, ils font la queue pour les ombles char, simplement en termes généraux, qu'est-ce que nous devons faire, apparemment? Il ne suffit pas juste regarder ces deux adresses. Que devons-nous faire? Ouais? AUDIENCE: Itération la chaîne [inaudible]. DAVID J. Malan: Ouais, nous allons parcourir la chaîne. Nous allons utiliser une boucle for, une boucle while, ou tout ce que vous êtes plus à l'aise. Et si nous avons deux chaînes quelque part en mémoire, regardons chacun de premier caractère, chaque seconde est caractère, puis troisième et quatrième, et le cinquième, jusqu'à ce que nous a frappé quelle valeur sentinelle spéciale? AUDIENCE: [inaudible] DAVID J. Malan: Ouais, la barre oblique inverse zéro, à quel point dans les deux cordes nous pouvons décider que voilà. Avons-nous identifié tous les personnages? Si non, return false. Si oui, retourner vrai. Et pour que est exactement ce que cette version du programme comparer-1.c fait. Elle est identique à ce que l'on regardé lundi sauf que je l'ai débarrassé du mot string-- si qui n'a pas impact-- fonctionnelle tout Je fais maintenant est de retirer des roues de formation visuels, mais pour voir clairement que s et t sont des adresses. Et qui est ce que l'étoile, l'astérisque, représente est une adresse, autrement connu techniquement plus comme un pointeur. Alors, quand je déclare sur s ligne 9 et dire char * s, cela ne signifie pas me donner une chaîne. Cela signifie que me donner une variable dont la but dans la vie est de stocker une adresse. Parce que je suis sur le point de mettre la adresse d'une chaîne en elle. Et en effet, GetString, soit clair, ne retourne pas une chaîne. Il ne renvoie pas maman barre oblique inverse zéro, en soi. Ce qui ne GetString spécifiquement et de revenir précisément? AUDIENCE: [inaudible] DAVID J. Malan: Une adresse, la l'adresse du premier caractère dans une chaîne de caractères qu'il a obtenu. Et maintenant nous voyons un mot clé spécial à nouveau. Et, je faisais allusion tout à l'heure. Cela va être bon convention que nous verrons encore et encore maintenant. Je vérifie pour vous assurer que s est pas nulle et t est pas nul. Parce que la base de mon vraiment mention rapide plus tôt, ce qui pourrait signifier si GetString retourne pas une adresse, mais N-U-L-L, ce qui est nouveau, une valeur particulière? AUDIENCE: Erreur. DAVID J. Malan: Il ya une erreur. Quelque chose a mal tourné. Et ce qui généralement qui pourrait se produire, en particulier avec strings-- qui pourrait être de longueur inconnue dans advance-- peut-être les ordinateurs » de mémoire, peut-être vous avez tapé dans un tel à long mot ou une phrase ou collé une énorme essai il ya juste pas assez de mémoire. Et donc GetString ne peut pas revenir l'adresse de la chose, si elle retourne juste rien. Et il dit qu'une erreur est arrivé en retournant la valeur spéciale NULL. Il est l'adresse zéro, pour ainsi dire. Maintenant, il se trouve C est livré avec un fonction qui fait que itération. Nous ne devons pas mettre en œuvre ce avec une boucle ou une boucle while nous-mêmes. Nous pouvons utiliser une fonction, appelé succinctement, remuer échantillon, ou la chaîne de comparer, dont but dans la vie est de faire exactement cela. Vous lui donnez deux pointeurs, deux adresses, et il ira à ces adresses et ensuite comparer lettre pour lettre pour lettre pour la qualité, arrêter que lorsque ce qui est vrai? Lorsque intuitivement devrait remuer maquette arrêt de son itération, juste pour être clair? Quand il frappe une barre oblique inverse 0 dans les deux ficelle, à quel point elle peut décider a tout assorti, ou a t-il eu une différence? Donc, si nous courons cela maintenant et essayer notre petit jeu de capitalisation, alors assurez-1 comparer, ./compare-1, et taper en minuscules maman deux fois. Maintenant, il est la même chose. Et si je le fais à nouveau avec minuscules et alors peut-être en majuscules. Maintenant, il distingue bien entre majuscules et minuscules. Donc, pas si difficile ou magique, mais il ne explique maintenant ce qui se passe sous le capot. Alors que pouvons-nous extraire de ce genre de leçon? Donc, nous allons jeter un oeil à ce. Je vais aller de l'avant et écrire une programme rapide ici appelé copie-0. Et maintenant, nous allons aller de l'avant et fait Faisons this-- avec copie-0, jetez un oeil à ce que je suis arrivé ici. Je dis d'abord l'utilisateur, dire quelque chose. Puis-je obtenir une chaîne et je stocké dans s. Puis-je vérifier si s est égal à est égal à NULL, il suffit de retourner 1. Donc, ceci est juste un contrôle d'erreur standard. Rien d'intéressant est arrivé. Et en fait, si nous nous débarrassons de l'erreur vérifier, cela ressemble Code semaine 1 en ce moment. Mais je l'ai commencé à obtenir un peu mieux à ce sujet. Or, dans la ligne 16, il ya une semaine, peut-être Il ya même un jour de quelques minutes ou, vous pourriez dire la ligne 16 est la création d'une variable appelée t et la copie s en elle. Et voilà une parfaite livraison raisonnable. Mais être plus précis maintenant. Qu'est-ce qui se passe dans la ligne 16? Qu'est-ce qui se copié de droite à gauche? Ouais? Public: Est-t obtient une adresse de s? DAVID J. Malan: Exactement, t est d'obtenir l'adresse de l'art. Donc, pour être clair maintenant, si je vais Retour à cet exemple plus tôt et je tirerai la chose que je l'ai tapé. Et ce que je l'ai tapé in-- voici s, et ici est ce que je l'ai tapé dans quelque part dans mémoire, maman, puis une barre oblique inverse 0 qui est ajouté pour moi. Ce que je stockées ici, rappeler, cette situation est à 1, 2, 3, 4, ceci est ce qui est actuellement à l'art. Donc, si sur la ligne 16, je dis me donner une autre variable appelée t et magasin dans à la valeur de s, ce qui est stockée ici ne sera pas maman mais plutôt juste le numéro 1. Donc, si nous regardons de l'avant dans ce programme maintenant, ce qui va se passer? Donc, notez qu'il ya cette fonction vous pourriez ont utilisé ce il ya quelque temps pour César, ou Vigenère, ou peut-être pas du tout. Je revendique mon printf, je suis va tirer la copie t. D'abord dans la ligne 19, la santé mentale rapide vérifier, chèques strlen la longueur de t. Parce que je ne veux pas essayer de tirer quelque chose de si il n'y a pas de chaîne il. Si l'utilisateur vient de frapper Entrez, il n'y a rien à tirer. Donc, je ne veux pas faire la ligne 21. Donc, la ligne 21 est en capitalisant lettre qui, apparemment, en t? AUDIENCE: m? DAVID J. Malan: Il semble comme il est la copie lequel? AUDIENCE: m. DAVID J. Malan: Euh, m. OK, donc la première m, parce que je suis un avis passant à ToUpper, qui si vous avez jamais vu, il est juste une fonction capitaliser à son entrée. t support zéro signifie donner moi le caractère zéro de t. Et Alors, comment cela changement d'image, pour être clair? Ce qui doit être réécrit ou modifié par rapport à s et t et maman zéro barre oblique inverse. AUDIENCE: [inaudible] DAVID J. Malan: Ouais, donc celui-là tout simplement a besoin d'obtenir changé to-- fixer this-- a besoin d'obtenir changé à un M majuscule. Mais maintenant, regardez plus tard dans la programme, si je imprimer s et t que je nettoie ici, de regarder ce qui est va se passer imprimer s et t. Donc, assurez-copie-0, ./copy-0. Laissez-moi aller de l'avant et tape dans MOM en minuscules. Remarquez l'original et la copie ont été capitalisés. Pourquoi? Eh bien, s et t sont tous deux pointent vers, si vous voulez, le même bloc de mémoire. Et franchement, cela devient uninteresting-- vraiment le fait que nous utilisons l'adresse zéro ici. Je veux dire, je ne me soucie pas vraiment où truc est dans la mémoire. Désolé je effacer un peu trop. Mais je ne me soucie pas vraiment où les choses sont en mémoire. Et donc, en effet ce que les programmeurs ont tendance à penser est que lorsque vous parlez une adresse ou un pointeur, qui se soucie où il est dans la mémoire. Je ne me soucie pas si il est au octet ou un milliard. Je me soucie simplement que cette variable est efficacement pointant à ce morceau de mémoire. Et donc, désormais, plutôt que de chicane sur des adresses mémoire arbitraires, nous allons il suffit de commencer à tirer des pointeurs en tant que pointeurs, comme des flèches. Donc, ce que S et T sont vraiment, selon ce programme, en raison de la façon dont je créé t, il est à seulement deux variables distinctes pointant dans le même bloc de mémoire. Et nous ne nous soucions pas où ils sont. Donc, nous pouvons abstraire ce détail. Alors, comment puis-je résoudre ce problème? Si je veux écrire une version de la copie programme qui en fait des copies de la chaîne et capitalise seulement le copie, juste intuitivement, ce que ça doit être un ingrédient à notre solution? AUDIENCE: [inaudible] DAVID J. Malan: Nous avons besoin de quoi? AUDIENCE: Chunk de mémoire. DAVID J. Malan: Nous devons une autre partie de la mémoire, non? Nous ne savons pas comment faire encore, nécessairement. Mais je sorte de besoin que cela se produise de manière que la mère d'origine en minuscules se retrouve dans ce morceau de mémoire supplémentaire. Et puis quand je change la copie, je ne veulent pas changer cette copie ici. Je veux la place de ne changer que ce copie de sorte que l'original est inchangé. Donc, nous allons voir comment nous pourrions le faire. Dans copie-1, qui a déjà été dépouillé de commentaire, mais est commenté en ligne. Nous faisons plutôt le following-- ces lignes sont identiques, me faire une chaîne et l'appeler l'art. Mais maintenant, regardons un de nos plus complexe mais le dernier de la complexité pendant un certain temps, la ligne 16 fait exactement cela. Donc, si votre confortable avec la image nous vient drew-- me donner un nouveau bloc de mémoire, copier tout en elle, nous allons voir comment nous traduisons que le code. Donc, la ligne 16, sur le côté gauche, char * t me donne cette boîte ici. Voilà tout ce qu'il fait. Sur le côté droit, m alloc ou malloc, est l'allocation de mémoire, super chic, une manière cryptique de dire simplement me donner un morceau de la mémoire. Combien de mémoire avons-nous besoin? Eh bien, est une sorte de grande expression. Mais voyons ce qu'il dit ici. Donc, cela, bien sûr, est de donner moi la longueur de la chaîne de l'art. Alors, maman, il devrait être quoi? Alors que trois, non? maman est trois caractères. Vous ne comptez pas le barre oblique inverse zéro lorsque vous parler de la longueur d'une chaîne il est en fait, les lettres visibles humaines. Alors maman, donc cela me donne 3. Mais attendez une minute, je suis maintenant en ajoutant 1. Pourquoi dois-je veux vraiment allouer 4 octets et pas seulement 3? Ouais? Public: Pour la valeur sentinelle? DAVID J. Malan: Exactement, pour cette valeur de sentinelle. Pour la barre oblique inverse zéro, Je dois 4 octets au total. Donc, je dois la longueur de la chaîne plus 1. Et puis, juste pour faire bonne measure-- même si sur ce système, il va toujours être 1-- je dis multiplier par la taille d'un caractère. Turns out est sizeof un opérateur en C qui vous le dit tout nombre d'octets qui est requise pour un certain type de données. Il ne fonctionne pas pour les tableaux, généralement, parfois il le fait. Mais dans le cas général, non. Mais il me dire combien d'octets un Char, qui se révèle est toujours 1. Donc, cela est comme la multiplication par 1. Si super cryptique ligne à la recherche de code. Mais tout ce qu'il fait est donne moi un morceau de la mémoire. Mais ça semble être la copie rien dans cette mémoire? Pas encore. Et que dois-je sur la ligne 22, et 23, 24, 25, eh bien, je fais simplement ce. Et cela est une sorte de vieux trucs de l'école maintenant. Cela ressemble PSet 2, où vous êtes juste faire avancer les choses autour dans la mémoire, ou plutôt dans les chaînes. Donc, je suis itération de 0 à la longueur de la chaîne s. Et je copie le caractère i-ème à s dans le personnage de i-ième t. Et parce que je, le programmeur, fait Assurez-vous d'allouer exactement autant d'octets comme je l'ai besoin, il est parfait one-to-one relation. Et je copie maman dans minuscules vers le nouveau. Et puis enfin, je fais cette ligne. Et donc l'effet est seulement de capitaliser ce t ici. Il ya donc beaucoup à absorber, mais si vous considérez juste ce qui se passe réellement sur sous le capot est tout simplement le déplacement de ces octets environ, tout ce qui qui est nécessaire pour résoudre ce problème est juste pour nous donner à ce morceau de mémoire. Maintenant, au risque de écrasante, permettez-moi de vous montrer un autre exemple qui est presque identiques, sauf pour celui-ci ligne de code. Donc ceci est la version pirate de ce programme, si vous voulez. Mais disons simplement distiller dans ce qui se passe. Ligne 24 utilisé pour être ce t Obtient support i s i support. Maintenant, je vais changer cela l'étoile beaucoup plus cryptique t plus 1 égale étoiles s plus 1. Donc ce qui se passe et pourquoi avons-nous un caractère étoile? Nous avons vu l'étoile avant, et il est utilisé différemment ici. Nous avons vu précédemment char *, maintenant que je vois Une étoile au début, et ce est OK. Parce que il se trouve nous peut déduire de tout genre première de celles principes ce qui se passe. Donc, juste pour être clair, ce qui est s? La semaine dernière, il était une chaîne. Cela ne suffit pas plus. Qu'est-ce que s, spécifiquement? AUDIENCE: [inaudible] DAVID J. Malan: Il est un pointeur. Il est l'adresse du premier caractère que nous avons tapé dans. OK, ce qui est t? AUDIENCE: [inaudible] DAVID J. Malan: Le l'adresse du premier octet en t, ce morceau de mémoire réaffecté. Donc, il se trouve que lorsque nous itérer de 0 sur un maximum de la chaîne length-- tout d'abord, i commence à 0, parce de cette ancienne école pour la boucle chose. Donc, pour simplifier les choses, nous allons supposer que la première ligne de code est vraiment juste ce, à droite. Si i est nul, ajoutant zéro à quelque chose sans doute ne va pas avoir un effet. Alors, quelle est cette parole? Il se trouve que la star opérateur dans ce contexte est le déréférencement l'opérateur, qui est juste une façon élégante de dire aller à l'adresse suivante. Donc, si s est l'adresse de la première personnage dans ce bloc de mémoire, * les moyens de s'y rendre. Et parce que nous avons tiré l'image de cette manière, vous pouvez adopter le suivant le modèle mental. Si cela est s, et vous dites * s * s, un peu comme Chutes and Ladders, si vous vous souvenez du jeu de l'enfance, est comme suivre cette flèche et aller à l'adresse. * t est la même chose. Donc, commencer ici, aller à son morceau. Je ne peux pas dessiner sur cet écran de cette façon. * t signifie d'aller ici. Et puis, la boucle est juste dire déplacer ce personnage ici, déplacer ce personnage ici, déplacer ce personnage ici. Mais comment puis-je faire incrémentation? Je dois défaire ce que je viens de supprimer. Ceci est ce qui est généralement appelé l'arithmétique des pointeurs, qui signifie mathématiques avec des adresses. Si, dans cette boucle, Je continue à incrémenter i, et s est une adresse et t est un adresse, si je continue simplement d'ajouter 1, qui signifie simplement continuer à avancer, et transmettre, et de transmettre dans la mémoire. Il est comme Oxford Street, le rue que le bâtiment CS est activée. Les bâtiments CS est à 33 Oxford Street. Donc, si vous aviez à faire 33 Oxford Street plus 1, qui vous amène à 34 Oxford Street, puis 35 Oxford Street, puis 36 Oxford Street, quels qu'ils bâtiments sont en fait - si elles existent. Et donc, voilà tout ce que nous faisons ici avec l'arithmétique des pointeurs. Donc, il est un moyen super arcanes de nous exprimer. Mais tout ce qui se passe sous le capot est juste après ces adresses, comme suivre une carte, si vous voulez, ou des flèches comme suit nous avons dessiné sur l'écran. OK, beaucoup de choses à digérer. Toute question sur la syntaxe, les concepts, pointeurs, malloc, ou analogues. Ouais, ici en premier. AUDIENCE: Alors, où que dit * t égal toupper * t, est ce que cela va capitaliser toutes les lettres ou just-- DAVID J. Malan: Ah, très bonne question. Donc, dans cette ligne ici, 31, est ce que cela va capitaliser la première lettre ou l'ensemble des lettres. Donc, nous allons répondre qu'en allant revenir aux principes premiers. Et les premiers principes ici je veux dire juste aller aux définitions de base de ce qui est impliqué. Donc toupper est une fonction qui capitalise char. C'est tout. * t signifie aller à la first-- aller à l'adresse en t. Donc, dans l'image, si tel est le morceau de la mémoire, nous avons alloué avec malloc, et cela est t, * t signifie aller ici. Pendant ce temps, vous êtes de passage cette valeur, minuscules m à toupper, vous obtenez de retour M majuscule, où allez-vous mettre? Vous mettre dans le même emplacement. Et ainsi que par la logique de celles définitions de base, il est seulement capitalisant la première lettre à moins que vous itérer avec i ou d'un pour la boucle ou une boucle while, ça ne va pas à faire autre chose que vous lui demandez. Bonne question. Ouais? Public: Pourquoi avez-vous utilisé déréférencer méthode plutôt qu'une le tableau? DAVID J. Malan: Ah, bonne question. Pourquoi voudriez-vous utiliser le déréférencement Procédé selon au lieu de la méthode de la matrice? Aucune raison particulière, pour être honnête. Et, de fait, pour ce genre d'exemple, à droite, Je suis juste en faisant valoir le faire programme plus compliqué, plus les yeux sont des vitrages plus, les gens sont vérifiant parce que cela semble super arcanes, mais même si elle fait la même chose. Et, franchement, cela est un solution inutilement complexe visuellement au problème. Il est toujours bon design, cinq sur cinq pour la conception, que ce soit dans le support la notation ou la notation de pointeur. Mais-- surtout quand nous obtenons plus tard dans le cours de PSet 5 lorsque nous mettons en œuvre ce dictionnaire que Je l'ai mentionné un couple de times-- nous allons effectivement soucions de la adresses de mémoire de bas niveau que nous comprenons vraiment ce qui se passe. Mais, pour l'instant, il se trouve que cette ligne de code entre crochets carrés ici ne existent pas vraiment. Ils sont ce qu'on appelle sucre syntaxique, qui est juste une façon étrangement fraîche de dire la compilateur convertit entre crochets pour être que l'expression mathématique. Donc, il est une convention humaine pour être en mesure d'écrire simplement ces supports très conviviale. Mais ce que le compilateur, clang, fait vraiment tout moment vous écrivez ce qui est mis en évidence dans la ligne 24, sous le capot, il est vraiment convertir en ce produit. Il est juste plus agréable comme un être humain à lire et à écrire du code comme la ligne 24. Mais finalement, ceux roues de formation trop se détachent quand on est propre confort devient plus fort. Très bien, alors rappeler ensuite que cette était le genre de gros problème nous avons couru dans. Et voilà ce qui a déclenché cet ensemble putain de conversation sur des pointeurs, et adresses, et les choses de la copie. Il était parce que nous trébucher ce stupide, question stupide, lequel Je implémenté logically-- avec Lauren ici sur la démo et le jus d'orange dans le milk-- une faute fonction algorithmique correcte pour échanger deux variables ' valeurs, mais la chose sacrément n'a eu aucune persistante, ou permanente, l'effet sur mon code. Et pourquoi était-ce? En un mot, pourquoi est-ce la mise en œuvre des swaps logiquement correct, mais n'a pas d'impact sur les variables qui lui sont transmis, comme x et y pour principale? Quel était l'essentiel de la question? Ouais? AUDIENCE: Parce que la variable fait des copies de la variable dans la passe grâce à la fonction. DAVID J. Malan: Exactement, quand vous passez variables dans une fonction, ou des arguments dans une fonction, ils sont adoptée par exemplaire, qui signifie que vous obtenez un produit identique à la recherche motif de bits pour x et y, appelé ici a et b. Et vous pouvez faire quelque chose vous voulez avec ces copies, mais ils vont avoir pas effet sur la fonction d'appel. Et, en fait, nous avons établi que image sur l'écran, le rappel la dernière fois, de sorte que si vous vraiment penser à ce qui est passe sous le hood-- si ceci est la mémoire de votre ordinateur, et ici-bas est le morceau de mémoire étant utilisée pour principale, tel est le morceau de mémoire étant utilisée pour la pagination, et même si principale a deux variables x et y, échange pourrait avoir la recherche identiques les valeurs, qui sont tous deux 1 et 2, mais ils sont complètement différents morceaux de mémoire. Nous avons donc besoin d'une solution à cela. Et franchement, il semblerait que nous maintenant avoir une solution à ce problème, à droite. Si nous avons maintenant la capacité de manipuler les choses par le biais d'adresses et, en quelque sorte Chutes and Ladders le style, suivez ces flèches et aller partout où nous voulons en mémoire, on ne pourrait pas résoudre ce problème en passant de principale pour échanger pas les valeurs que nous voulons swap, mais juste intuitivement que pourrions-nous passer d'échanger la place? [Interposition VOIX] DAVID J. Malan: Pourquoi ne pas simplement il passe les adresses, non? Pourquoi ne nous donnons pas un échange carte au trésor, si vous voulez, qu'elle conduit à la valeurs réelles x et y. Let swap, réellement changer ces bits d'origine, plutôt que juste de passage des copies des bits. Et donc, en fait, que est ce qui est va être la solution. Cette version est ici clairement mauvais et imparfait. Et maintenant, à première vue, il semble juste comme nous avons ajouté un tas d'étoiles au hasard et traversé nos doigts qu'il serait compiler. Mais, il serait maintenant compiler. Mais voyons ce que ces choses signifient. Et malheureusement, les auteurs de, C aurait pu choisir un autre symbole pour faire cela un peu plus claire, mais l'opérateur étoiles a une signification différente dans deux contextes différents. Et nous avons vu à la fois, mais nous allons distinguer. Donc, au sommet il, quand je l'ai changé A et B d'être l'INT dans le mauvais Version int étoiles, a et b, précédemment, sont des nombres entiers. Quels sont a et b maintenant le bon, version verte? Ils sont adresses. Adresses de ce que, pour être clair? Adresses des nombres entiers. Donc, le fait que je suis disant moyens int étoiles ceci est l'adresse de un nombre entier, en particulier. Donc remarquerez maintenant dans les lignes de code, quelque chose d'autre a changé aussi. tmp reste le même, parce que il est juste l'entier temporaire, pas de magie de mémoire il. Mais maintenant besoin d'une étoile. Et, en fait, chaque autre mention de a et b, notez que tout ce qui est changer du rouge au vert est que je suis le préfixe ces variables avec des étoiles. Parce que je ne veux pas copier a et b. Parce que si je copie simplement A et B et d'échange A et B, ce que je suis réellement permutation? Juste adresses, je veux échanger ce qui est en ces adresses. Je veux aller là-bas. Et si l'opérateur étoiles à l'intérieur de ma fonction, pas à l'intérieur de la liste des paramètres, signifie que vous allez à ces adresses et effectivement changer ces valeurs. Alors qu'est-ce que l'image ressemblent maintenant à la place. Eh bien, si je passe à la place en pour A et B et non une 2-- En fait, je dois ajouter un autre définition ici. Alors que ce morceau supposer de la mémoire est à l'emplacement 10. Ceci est à l'emplacement 11, mais cette est un peu d'une simplification, Je dois maintenant deux choix font je passe x et y ou dois-je passer leurs adresses? Si je passe leurs adresses comme ça, je viens maintenant besoin de mettre en œuvre swap par le code vert de sorte que quand il voit un et quand il b voit, il ne se copie pas a et b et déplacer le lait et le jus d'orange. Le lait et jus d'orange métaphore brise maintenant en baisse, parce que ce sont des tasses Cartes de liquides et non. Nous avons plutôt besoin d'aller à traiter 10 et nous besoin d'aller à traiter 11, et puis effectuer cette logique de permutation. Ainsi, la logique est la même, mais nous avons besoin d'une manière légèrement différente d'accéder à ces variables. Et à la fin, ce que le programme doit ressembler à ceci. Dans swap.c littéralement copié et collé la version verte. Mais je dois faire un changement. Il ne suffit pas simplement de changer swap. Quelle autre ligne de code dois-je changer? Ouais? AUDIENCE: Lorsqu'il prend les arguments. DAVID J. Malan: Où il tire son argument. Donc, si je fais défiler jusqu'à principale, je ne peut pas simplement passer en x et y, et, je vous le promets, la dernière morceau de nouvelle syntaxe aujourd'hui. Je dois passer au pas x et mais l'adresse y de x et y. Et il se trouve, le symbole que les auteurs de C choisi est si vous utilisez une esperluette ici, de ne pas être confondu avec l'esperluette au niveau du bit, si vous utilisez une esperluette ici et ici une esperluette, Ces chiffres pour vous, Quelle est l'adresse de x, il est peut être 10, quelle est la Adresse de y, il est peut être 11, et passe dans ceux à la place. Il ya donc beaucoup d'absorber à la fois. Mais voyons maintenant rapidement nos quatre minutes restantes où les choses peuvent mal tourner. Et en passant, fait Je pris cette photo, TF a pris cette photo il ya un an ou deux. Voilà donc le coin arrière Eliot Dining Hall. Les pointeurs sont peut-être le plus difficile sujet que nous couvrons dans CS50. Donc, si vous vous inquiétez de la sorte de la pente est comme peut-être il est plus d'un bâton de hockey comme ça, réaliser nous sommes en quelque sorte presque un pic en termes de la complexité conceptuelle. Et je soulève cette photo, parce que je jure à Dieu, à l'automne 1996, quand je prenais CS50 avec mon enseignement compatriote, Nishat Mehta, il m'a fait asseoir dans le coin de la Eliot D. Hall pendant le déjeuner, ou le dîner, ou quelque chose à essayer me aider à comprendre les pointeurs. Et ceci est où je me trouvais semaines après il a été introduit dans la leçon quand Je comprenais enfin pointeurs. Et je suis plein d'espoir que cette seront cliquez beaucoup plus tôt pour vous. Mais réaliser ce absolument parmi les sujets plus sophistiqués nous avons examiné. Mais il est parmi les plus puissants. Et quand vous arrivez, il est vraiment tout aller juste pour venir finalement ensemble. Donc, rassurez-vous, il ne le fait pas besoin de tous les puits aujourd'hui. Alors, voici le dernier programme nous allons regarder. Et nous allons finir avec un rapides trois minutes de pâte à modeler faite par notre ami, Nick Parlante. Voici un programme, que sur les deux haut lignes déclare une variable x et y. Les deux qui sont des adresses d'entiers, les pointeurs AKA. Nous attribuons ensuite assez mémoire pour stocker un int et stocker l'adresse de cette mémoire dans x. Ainsi, il est encore plus simple que l'exemple avant. Donnez-moi quatre octets de mémoire, qui est la taille d'un int, et de mettre cette adresse en x. Cette ligne signifie ici aller à l'adresse dans x et de mettre le sens de la vie, le nombre 42 il. Mais cette ligne me préoccupe. STAR y signifie aller à l'adresse en y, et de mettre le mauvais numéro 13 il. Pourquoi est-il dangereux, à ce stade bien que dans les story-- dit rapidement dans nos minutes déclin ici-- pourquoi est-il mauvais pour moi de dire, aller à l'adresse de y? AUDIENCE: Vous ne l'avez pas [inaudible]. DAVID J. Malan: Je ne ai pas mettre quelque chose en y. Alors, quelle est la valeur de y, à ce point dans l'histoire? Nous avons aucune idée. Il est une valeur d'ordures et ni ne sait Binky. Si nous pouvions terminer sur cette note. [LECTURE VIDÉO] -Hé, Binky, réveillez-vous. Il est temps pour le plaisir pointeur. -Qu'est ce que c'est? En savoir plus sur les pointeurs? Oh, Goody. -Eh Bien, pour commencer, je suppose que nous sommes allez avoir besoin de quelques pointeurs. -D'ACCORD. Ce code attribue deux pointeurs qui peut pointer vers entiers. -OK, Je vois bien la deux pointeurs, mais ils ne semblent pas être pointant à rien. -C'est vrai. Pointeurs Initialement ne pointe pas sur quoi que ce soit. Les choses qu'ils pointent vers sont appelé pointees et leur mise en place est une étape séparée. Oh, droite, droite. Je le savais. Les pointees sont séparés. Alors, comment voulez vous allouez un pointée? -Ok, Eh bien, ce Code alloue un nouveau pointée entier, et cette partie ensembles x pour pointer vers elle. -Hé, Qui semble mieux. Donc, en faire quelque chose. -OK, Je vais déréférence le pointeur à x enregistrer le numéro 42 dans sa pointée. Pour cette astuce, je vais avoir besoin de ma baguette magique de déréférencement. -Votre Baguette magique de déréférencement? Euh, ce qui est très bien. -C'est Ce que le code ressemble. Je vais simplement mettre en place le nombre et-- [POP SOUND] Hé, regardez là, il va. Donc, faire un déréférencement x suit la flèche pour accéder à sa pointée. Dans ce cas, pour stocker 42 là-dedans. Hey, essayez de l'utiliser pour stocker le nombre 13 à travers l'autre pointeur, y. -D'ACCORD. Je vais juste aller sur ici pour y, et obtenir le nombre 13 mise en place. Et puis prendre la baguette de déréférencement et just-- [Buzzer] Oh, hey cela ne fonctionne pas. Dire, euh, Binky, je ne sais pas penser déréférencement y est une bonne idée, parce que la mise en le pointée est une étape séparée. Et je ne pense pas que nous ayons jamais fait. -Hmm, Bon point. -Oui, Nous avons attribué le pointeur, y, mais nous ne fixons pour pointer vers un pointée. -Hmm, Très observateur. Hé, vous êtes à la recherche bonne là, Binky. Pouvez-vous résoudre ce problème afin que les points y à la même pointée comme x. -sure, Je utiliser ma baguette magique d'affectation du pointeur. -Est-Ce que cela va être un problème, comme avant? Non, cela ne touche pas les pointees. Il change juste un pointeur pour pointer vers le même chose-- [Claquement] --en l'autre. -Oh je vois. Maintenant y pointe vers le même endroit que x. Alors, attendez, maintenant y est fixé. Il dispose d'un pointée. Ainsi, vous pouvez essayer de la baguette de déréférencement à nouveau d'envoyer le 13 plus. Oh, OK, voilà. Hé, regardez ça. Maintenant déréférencement travaux sur y. Et parce que les pointeurs partagent que l'on pointée, ils voient tous deux la 13. -Ouais, Partage, euh, peu importe. Alors, allons-nous changer de place maintenant? Oh, regardons, nous manquons de temps. -But-- -Juste Rappeler les trois règles de pointeur. Numéro 1, la structure de base est que vous avez un pointeur, et il souligne plus à un pointée. Mais le pointeur et pointée sont séparés. Et l'erreur commune est de mettre en place un pointeur mais oublier de lui donner un pointée. Numéro 2, pointeur déréférencement commence au niveau du pointeur et suit sa flèche sur pour accéder à sa pointée. Comme nous le savons tous, cela ne fonctionne que si est un pointée, qui obtient sorte de retour à la règle numéro 1. Numéro 3, pointeur cession prend un pointeur et il change pour indiquer le même pointée comme un autre pointeur. Donc, après la cession, les deux pointeurs va pointer vers le même pointée, parfois que ce qu'on appelle le partage. Et cela est tout ce qu'il ya à faire, vraiment. Bye-bye maintenant. [FIN LECTURE] DAVID J. Malan: Voilà pour CS50. Merci au professeur Nick Parlante. Nous vous verrons la semaine prochaine. [Electronic Music JEU]