1 00:00:00,000 --> 00:00:02,520 [Powered by Google Translate] [Section 4 - Plus confortable] 2 00:00:02,520 --> 00:00:04,850 [Rob Bowden - Université de Harvard] 3 00:00:04,850 --> 00:00:07,370 [C'est CS50. - CS50.TV] 4 00:00:08,920 --> 00:00:13,350 Nous avons un quizz demain, au cas où vous les gars ne savaient pas que. 5 00:00:14,810 --> 00:00:20,970 Il s'agit essentiellement de tout ce que vous avez vu en classe ou aurait dû voir en classe. 6 00:00:20,970 --> 00:00:26,360 Qui inclut des pointeurs, même si elles sont un sujet très récent. 7 00:00:26,360 --> 00:00:29,860 Vous devriez au moins comprendre les niveaux élevés d'entre eux. 8 00:00:29,860 --> 00:00:34,760 Tout ce qui a été dépassé dans la classe que vous devez comprendre pour le quiz. 9 00:00:34,760 --> 00:00:37,320 Donc, si vous avez des questions à leur sujet, vous pouvez les poser maintenant. 10 00:00:37,320 --> 00:00:43,280 Mais cela va être une séance très dirigée par des étudiants où vous les gars poser des questions, 11 00:00:43,280 --> 00:00:45,060 alors j'espère que les gens ont des questions. 12 00:00:45,060 --> 00:00:48,020 Quelqu'un at-il des questions? 13 00:00:49,770 --> 00:00:52,090 Oui. >> [L'élève] Pourriez-vous nous pointeurs à nouveau? 14 00:00:52,090 --> 00:00:54,350 Je vais aller sur les pointeurs. 15 00:00:54,350 --> 00:00:59,180 Toutes les variables nécessairement vivre dans la mémoire, 16 00:00:59,180 --> 00:01:04,450 mais en général, vous ne vous inquiétez pas à ce sujet et que vous venez de dire x + 2 et + 3 y 17 00:01:04,450 --> 00:01:07,080 et le compilateur de savoir où les choses vivent pour vous. 18 00:01:07,080 --> 00:01:12,990 Une fois que vous avez affaire avec des pointeurs, vous êtes maintenant explicitement l'utilisation de ces adresses mémoire. 19 00:01:12,990 --> 00:01:19,800 Donc, une seule variable ne jamais vivre à une adresse unique à un moment donné. 20 00:01:19,800 --> 00:01:24,040 Si nous voulons déclarer un pointeur, ce qui est le type va ressembler? 21 00:01:24,040 --> 00:01:26,210 >> Je tiens à déclarer un pointeur p. Qu'est-ce que le type de ressembler? 22 00:01:26,210 --> 00:01:33,530 [L'élève] int * p. Ouais >>. Donc, int * p. 23 00:01:33,530 --> 00:01:38,030 Et comment puis-je le faire pointer vers x? >> [L'élève] Ampersand. 24 00:01:40,540 --> 00:01:45,300 [Bowden] Donc esperluette est littéralement appelé l'adresse de l'opérateur. 25 00:01:45,300 --> 00:01:50,460 Donc, quand je dis et ça devient de x l'adresse mémoire de la variable x. 26 00:01:50,460 --> 00:01:56,790 Alors maintenant, j'ai le pointeur p, et partout dans mon code que je peux utiliser * p 27 00:01:56,790 --> 00:02:02,960 ou je pourrais utiliser x et ce sera exactement la même chose. 28 00:02:02,960 --> 00:02:09,520 (* P). Quel est ce fait? Qu'est-ce que cette étoile signifie? 29 00:02:09,520 --> 00:02:13,120 [L'élève] Cela signifie une valeur à ce point. Ouais >>. 30 00:02:13,120 --> 00:02:17,590 Donc, si on y regarde, il peut être très utile pour faire ressortir les diagrammes 31 00:02:17,590 --> 00:02:22,230 lorsqu'il s'agit d'une petite boîte de la mémoire pour x, qui arrive à avoir la valeur 4, 32 00:02:22,230 --> 00:02:25,980 alors nous avons une petite boîte de la mémoire pour p, 33 00:02:25,980 --> 00:02:31,590 et ainsi de p points de X, donc nous dessiner une flèche de p à x. 34 00:02:31,590 --> 00:02:40,270 Ainsi quand nous disons p * nous disons allez à la boîte qui est p. 35 00:02:40,270 --> 00:02:46,480 Star est de suivre la flèche, puis faites ce que vous voulez avec cette boîte là. 36 00:02:46,480 --> 00:03:01,090 Donc je peux dire * p = 7, et qui ira à la boîte qui est x et que le changement à 7. 37 00:03:01,090 --> 00:03:13,540 Ou je pourrais dire int z = * p * 2; C'est déroutant parce que son étoile, étoile. 38 00:03:13,540 --> 00:03:19,230 L'étoile est le déréférencement p, l'autre star est multiplié par 2. 39 00:03:19,230 --> 00:03:26,780 Remarquez que j'ai pu tout aussi bien remplacer le p * avec x. 40 00:03:26,780 --> 00:03:29,430 Vous pouvez les utiliser de la même manière. 41 00:03:29,430 --> 00:03:38,000 Et puis, plus tard, je peux avoir un point p à quelque chose de complètement nouveau. 42 00:03:38,000 --> 00:03:42,190 Je peux juste dire p = &z; 43 00:03:42,190 --> 00:03:44,940 Alors maintenant, P Pas de points de plus à x, il pointe vers z. 44 00:03:44,940 --> 00:03:50,510 Et chaque fois que je fais p * c'est la même chose que faire z. 45 00:03:50,510 --> 00:03:56,170 Donc la seule chose utile à ce sujet est une fois que nous commencer à entrer dans les fonctions. 46 00:03:56,170 --> 00:03:59,790 >> C'est un peu inutile de déclarer un pointeur qui pointe vers quelque chose de 47 00:03:59,790 --> 00:04:03,140 et puis vous êtes juste à l'déréférencement 48 00:04:03,140 --> 00:04:06,060 quand vous auriez pu utiliser la variable d'origine pour commencer. 49 00:04:06,060 --> 00:04:18,190 Mais quand vous entrez dans les fonctions - alors disons que nous avons une certaine fonction, int foo, 50 00:04:18,190 --> 00:04:32,810 qui prend un pointeur et fait exactement * p = 6; 51 00:04:32,810 --> 00:04:39,990 Comme nous l'avons vu avec swap, vous ne pouvez pas faire un échange efficace et une fonction distincte 52 00:04:39,990 --> 00:04:45,180 simplement en passant parce que tout entiers dans C est toujours passage par valeur. 53 00:04:45,180 --> 00:04:48,360 Même si vous êtes de passage pointeurs vous êtes de passage par valeur. 54 00:04:48,360 --> 00:04:51,940 Il se trouve que ces valeurs sont des adresses mémoire. 55 00:04:51,940 --> 00:05:00,770 Donc, quand je dis foo (p), je suis de passage du pointeur dans la fonction foo 56 00:05:00,770 --> 00:05:03,910 puis foo fait * p = 6; 57 00:05:03,910 --> 00:05:08,600 Donc à l'intérieur de cette fonction, * p est toujours équivalent à x, 58 00:05:08,600 --> 00:05:12,720 mais je ne peux pas utiliser x à l'intérieur de cette fonction, car elle n'est pas portée au sein de cette fonction. 59 00:05:12,720 --> 00:05:19,510 Donc, * p = 6 est le seul moyen que je peux accéder à une variable locale d'une autre fonction. 60 00:05:19,510 --> 00:05:23,600 Ou bien, les pointeurs sont la seule façon que je peux accéder à une variable locale d'une autre fonction. 61 00:05:23,600 --> 00:05:31,600 [L'élève] Disons que vous vouliez retourner un pointeur. Comment voulez-vous faire? 62 00:05:31,600 --> 00:05:44,270 [Bowden] Renvoie un pointeur comme dans quelque chose comme int y = 3; retour et y? >> [L'élève] Ouais. 63 00:05:44,270 --> 00:05:48,480 [Bowden] D'accord. Vous ne devriez jamais faire cela. Cela est mauvais. 64 00:05:48,480 --> 00:05:59,480 Je crois que j'ai vu dans ces diapositives de cours vous commencé à voir ce schéma l'ensemble de la mémoire 65 00:05:59,480 --> 00:06:02,880 où ici vous avez l'adresse mémoire 0 66 00:06:02,880 --> 00:06:09,550 et ici vous avez d'adresse mémoire 4 Go ou 2 à la 32. 67 00:06:09,550 --> 00:06:15,120 Alors vous avez des trucs et des trucs et puis vous avez votre pile 68 00:06:15,120 --> 00:06:21,780 et vous avez votre tas, que vous juste commencé à apprendre à propos, en grandissant. 69 00:06:21,780 --> 00:06:24,390 [L'élève] N'est-ce pas le tas au-dessus de la pile? 70 00:06:24,390 --> 00:06:27,760 >> Ouais. Le tas est sur le dessus, n'est-ce pas? >> [L'élève] Eh bien, il a mis 0 sur le dessus. 71 00:06:27,760 --> 00:06:30,320 [L'élève] Oh, il a mis 0 sur le dessus. >> [L'élève] Oh, d'accord. 72 00:06:30,320 --> 00:06:36,060 Avertissement: N'importe où avec CS50 vous allez voir de cette façon. >> [L'élève] D'accord. 73 00:06:36,060 --> 00:06:40,290 C'est juste que quand vous êtes le premier voyant des piles, 74 00:06:40,290 --> 00:06:45,000 comme quand vous pensez d'une pile vous pensez de l'empilement des choses l'un sur l'autre. 75 00:06:45,000 --> 00:06:50,810 Nous avons donc tendance à retourner cette sorte autour de la pile est de plus en plus comme une pile normalement 76 00:06:50,810 --> 00:06:55,940 au lieu de la pile qui pend. >> [L'élève] Ne pas techniquement tas grandir trop, si? 77 00:06:55,940 --> 00:07:01,100 Cela dépend de ce que vous entendez par grandir. 78 00:07:01,100 --> 00:07:04,010 La pile et le tas se développent toujours dans des directions opposées. 79 00:07:04,010 --> 00:07:09,420 Une pile est toujours grandir dans le sens où il grandit 80 00:07:09,420 --> 00:07:12,940 vers des adresses de mémoire élevées, et le tas est de plus en plus bas 81 00:07:12,940 --> 00:07:17,260 en ce qu'elle a de plus en plus vers des adresses de mémoire inférieures. 82 00:07:17,260 --> 00:07:20,250 Ainsi, la partie supérieure est 0 et le fond est élevé adresses mémoire. 83 00:07:20,250 --> 00:07:26,390 Ils sont de plus en plus à la fois, juste dans des directions opposées. 84 00:07:26,390 --> 00:07:29,230 [L'élève] Je voulais juste dire que, parce que vous avez dit que vous mettez la pile sur le fond 85 00:07:29,230 --> 00:07:33,640 car il semble plus intuitif, car pour la pile à commencer par le haut d'un tas, 86 00:07:33,640 --> 00:07:37,520 tas est au-dessus de lui-même aussi, donc C'est - >> Oui. 87 00:07:37,520 --> 00:07:44,960 Vous pouvez aussi penser à le tas comme grandissent et plus grande, mais la pile plus. 88 00:07:44,960 --> 00:07:50,280 Ainsi, la pile est celle qui nous sorte de vouloir montrer grandir. 89 00:07:50,280 --> 00:07:55,390 Mais partout où vous regardez ailleurs va montrer l'adresse 0 en haut 90 00:07:55,390 --> 00:07:59,590 et l'adresse mémoire la plus élevée au fond, si ceci est votre point de vue habituel de la mémoire. 91 00:07:59,590 --> 00:08:02,100 >> Avez-vous une question? 92 00:08:02,100 --> 00:08:04,270 [L'élève] Pouvez-vous nous en dire plus sur le tas? 93 00:08:04,270 --> 00:08:06,180 Ouais. Je vais y revenir dans un instant. 94 00:08:06,180 --> 00:08:12,220 Tout d'abord, revenir aux raisons pour lesquelles le retour et y est une mauvaise chose, 95 00:08:12,220 --> 00:08:18,470 sur la pile, vous avez un groupe de cadres de pile qui représentent toutes les fonctions 96 00:08:18,470 --> 00:08:20,460 qui ont été appelés. 97 00:08:20,460 --> 00:08:27,990 Donc ignorer les choses précédentes, le haut de votre pile va toujours être la principale fonction 98 00:08:27,990 --> 00:08:33,090 puisque c'est la première fonction qui est appelée. 99 00:08:33,090 --> 00:08:37,130 Et puis, lorsque vous appelez une autre fonction, la pile va se développer vers le bas. 100 00:08:37,130 --> 00:08:41,640 Donc, si je l'appelle une fonction, foo, et il obtient son cadre propre pile, 101 00:08:41,640 --> 00:08:47,280 il peut appeler une fonction, d'un bar, il obtient son cadre propre pile. 102 00:08:47,280 --> 00:08:49,840 Et le bar pourrait être récursive et il pourrait se faire appeler, 103 00:08:49,840 --> 00:08:54,150 et que second appel à la barre va obtenir son cadre propre pile. 104 00:08:54,150 --> 00:08:58,880 Et donc ce qui se passe dans ces cadres de pile sont tous des variables locales 105 00:08:58,880 --> 00:09:03,450 et tous les arguments de la fonction que - 106 00:09:03,450 --> 00:09:08,730 Toutes les choses qui sont localement portée à cette fonction, allez dans ces cadres de pile. 107 00:09:08,730 --> 00:09:21,520 Cela signifie donc que quand j'ai dit quelque chose comme bar est une fonction, 108 00:09:21,520 --> 00:09:29,270 Je vais juste de déclarer un entier, puis renvoyer un pointeur vers cet entier. 109 00:09:29,270 --> 00:09:33,790 Alors d'où vient y vivre? 110 00:09:33,790 --> 00:09:36,900 [L'élève] y vit dans un bar. >> [Bowden] Ouais. 111 00:09:36,900 --> 00:09:45,010 Quelque part dans ce petit carré de mémoire est un carré qui a Littler y en elle. 112 00:09:45,010 --> 00:09:53,370 Quand je reviens et y, je retourne un pointeur vers ce bloc peu de mémoire. 113 00:09:53,370 --> 00:09:58,400 Mais alors, quand un retour de la fonction, de son cadre de pile se extraites de la pile. 114 00:10:01,050 --> 00:10:03,530 Et c'est pourquoi il est appelé pile. 115 00:10:03,530 --> 00:10:06,570 C'est comme si la structure de données pile, si vous savez ce que c'est. 116 00:10:06,570 --> 00:10:11,580 Ou même comme une pile de plateaux est toujours l'exemple, 117 00:10:11,580 --> 00:10:16,060 principal va aller sur le fond, puis la première fonction que vous appelez va aller au-dessus de cela, 118 00:10:16,060 --> 00:10:20,400 et vous ne pouvez pas revenir au menu principal jusqu'à ce que vous revenez de toutes les fonctions qui ont été appelées 119 00:10:20,400 --> 00:10:22,340 qui ont été placés sur le dessus de celui-ci. 120 00:10:22,340 --> 00:10:28,650 >> [L'élève] Donc, si vous avez fait faire revenir l'y &, cette valeur est sujette à changement sans préavis. 121 00:10:28,650 --> 00:10:31,290 Oui, C'est - >> [l'élève] Il pourrait être écrasé. Ouais >>. 122 00:10:31,290 --> 00:10:34,660 C'est tout à fait - Si vous essayez de - 123 00:10:34,660 --> 00:10:38,040 Ce serait également un bar int * car il est retourne un pointeur, 124 00:10:38,040 --> 00:10:41,310 de sorte que son retour est de type int *. 125 00:10:41,310 --> 00:10:46,500 Si vous essayez d'utiliser la valeur de retour de cette fonction, c'est un comportement indéfini 126 00:10:46,500 --> 00:10:51,770 parce que ce pointeur pointe vers une mauvaise mémoire. >> [L'élève] D'accord. 127 00:10:51,770 --> 00:11:01,250 Alors que faire si, par exemple, vous avez déclaré int * y = malloc (sizeof (int))? 128 00:11:01,250 --> 00:11:03,740 Voilà qui est mieux. Oui. 129 00:11:03,740 --> 00:11:07,730 [L'élève] Nous avons parlé de la façon quand nous traîner les choses à notre corbeille 130 00:11:07,730 --> 00:11:11,750 ils ne sont pas réellement effacée; nous venons de perdre leurs aiguilles. 131 00:11:11,750 --> 00:11:15,550 Donc dans ce cas avons-nous réellement effacer la valeur ou est-il toujours là dans la mémoire? 132 00:11:15,550 --> 00:11:19,130 Pour la plupart, ça va être encore là. 133 00:11:19,130 --> 00:11:24,220 Mais disons que nous arrive d'appeler une autre fonction, baz. 134 00:11:24,220 --> 00:11:28,990 Baz va obtenir son cadre propre pile ici. 135 00:11:28,990 --> 00:11:31,470 Ça va être écrasant toutes ces choses, 136 00:11:31,470 --> 00:11:34,180 et puis si vous essayez plus tard et utilisez le pointeur que vous avez obtenu précédemment, 137 00:11:34,180 --> 00:11:35,570 ça ne va pas être la même valeur. 138 00:11:35,570 --> 00:11:38,150 Il va avoir changé juste parce que vous avez appelé la fonction baz. 139 00:11:38,150 --> 00:11:43,080 [L'élève] Mais si nous n'avions pas, aurions-nous encore obtenir 3? 140 00:11:43,080 --> 00:11:44,990 [Bowden] Selon toute vraisemblance, vous le feriez. 141 00:11:44,990 --> 00:11:49,670 Mais vous ne pouvez pas compter sur cela. C dit que le comportement est indéterminé. 142 00:11:49,670 --> 00:11:51,920 >> [L'élève] Oh, c'est vrai. D'accord. 143 00:11:51,920 --> 00:11:58,190 Alors, quand vous voulez retourner un pointeur, c'est là que malloc est en cours d'utilisation. 144 00:12:00,930 --> 00:12:15,960 Je vous écris en fait juste retour de malloc (3 * sizeof (int)). 145 00:12:17,360 --> 00:12:24,050 Nous allons passer en revue malloc plus en une seconde, mais l'idée est de malloc toutes vos variables locales 146 00:12:24,050 --> 00:12:26,760 toujours sur la pile. 147 00:12:26,760 --> 00:12:31,570 Tout ce qui est malloced va sur le tas, et il sera pour toujours et toujours sur le tas 148 00:12:31,570 --> 00:12:34,490 jusqu'à ce que vous explicitement le libérer. 149 00:12:34,490 --> 00:12:42,130 Donc, cela signifie que lorsque malloc vous quelque chose, il va survivre après le retour de la fonction. 150 00:12:42,130 --> 00:12:46,800 [L'élève]-t-il survivre après l'arrêt du programme en cours d'exécution? Non >> 151 00:12:46,800 --> 00:12:53,180 Ok, donc ça va être là jusqu'à ce que le programme est tout le chemin accompli en marche. Oui >>. 152 00:12:53,180 --> 00:12:57,510 On peut aller sur des détails de ce qui se passe quand le programme s'arrête. 153 00:12:57,510 --> 00:13:02,150 Vous pourriez avoir besoin de me le rappeler, mais c'est une chose séparée entièrement. 154 00:13:02,150 --> 00:13:04,190 [L'élève] Donc malloc crée un pointeur? Ouais >>. 155 00:13:04,190 --> 00:13:13,030 Malloc - >> [l'élève] Je pense que malloc désigne un bloc de mémoire qu'un pointeur peut utiliser. 156 00:13:15,400 --> 00:13:19,610 [Bowden] Je veux que le diagramme à nouveau. >> [L'élève] Donc, cette fonction fonctionne, cependant? 157 00:13:19,610 --> 00:13:26,430 [L'élève] Ouais, malloc désigne un bloc de mémoire que vous pouvez utiliser, 158 00:13:26,430 --> 00:13:30,470 puis il retourne l'adresse du premier bloc de cette mémoire. 159 00:13:30,470 --> 00:13:36,750 >> [Bowden] Ouais. Ainsi, lorsque vous malloc, vous attrapant un certain bloc de mémoire 160 00:13:36,750 --> 00:13:38,260 qui est actuellement dans le tas. 161 00:13:38,260 --> 00:13:43,040 Si le tas est trop petit, alors le tas va tout simplement de se développer, et il pousse dans cette direction. 162 00:13:43,040 --> 00:13:44,650 Donc, disons que le tas est trop petite. 163 00:13:44,650 --> 00:13:49,960 Ensuite, il est sur le point de grandir un peu et retourner un pointeur vers ce bloc qui a juste grandi. 164 00:13:49,960 --> 00:13:55,130 Lorsque vous des trucs gratuits, vous faites plus de place dans le tas, 165 00:13:55,130 --> 00:14:00,030 oui, alors un appel ultérieur à malloc pouvez réutiliser cette mémoire que vous aviez libéré. 166 00:14:00,030 --> 00:14:09,950 La chose importante à propos de malloc et free, c'est qu'il vous donne un contrôle complet 167 00:14:09,950 --> 00:14:12,700 au cours de la durée de vie de ces blocs de mémoire. 168 00:14:12,700 --> 00:14:15,420 Les variables globales sont toujours en vie. 169 00:14:15,420 --> 00:14:18,500 Les variables locales sont vivants dans leur champ. 170 00:14:18,500 --> 00:14:22,140 Dès que vous passez une accolade, les variables locales sont morts. 171 00:14:22,140 --> 00:14:28,890 Malloced mémoire est vivante lorsque vous voulez qu'elle soit vivante 172 00:14:28,890 --> 00:14:33,480 et est ensuite libérée lorsque vous lui demandez d'être libéré. 173 00:14:33,480 --> 00:14:38,420 Ce sont en fait les seuls 3 types de mémoire, vraiment. 174 00:14:38,420 --> 00:14:41,840 Il s'agit de gestion automatique de la mémoire, qui est la pile. 175 00:14:41,840 --> 00:14:43,840 Les choses se passent automatiquement pour vous. 176 00:14:43,840 --> 00:14:46,910 Quand vous dites int x, la mémoire est allouée pour x int. 177 00:14:46,910 --> 00:14:51,630 Lorsque x est hors de portée, la mémoire est récupérée pour x. 178 00:14:51,630 --> 00:14:54,790 Ensuite, il ya la gestion dynamique de la mémoire, qui est ce que malloc, 179 00:14:54,790 --> 00:14:56,740 ce qui est quand vous avez le contrôle. 180 00:14:56,740 --> 00:15:01,290 Vous dynamiquement décider quand la mémoire doit et ne doit pas être affecté. 181 00:15:01,290 --> 00:15:05,050 Et puis il ya statique, ce qui signifie simplement qu'il vit pour toujours, 182 00:15:05,050 --> 00:15:06,610 qui est ce que les variables globales sont. 183 00:15:06,610 --> 00:15:10,240 Ils sont tout simplement toujours en mémoire. 184 00:15:10,960 --> 00:15:12,760 >> Des questions? 185 00:15:14,490 --> 00:15:17,230 [L'élève] Pouvez-vous définir un bloc simplement en utilisant des accolades 186 00:15:17,230 --> 00:15:21,220 mais n'ayant pas d'avoir une? instruction if ou d'une instruction while ou quelque chose comme ça 187 00:15:21,220 --> 00:15:29,130 Vous pouvez définir un bloc comme dans une fonction, mais qui a aussi des accolades. 188 00:15:29,130 --> 00:15:32,100 [L'élève] Donc, vous ne pouvez pas avoir comme une paire d'accolades aléatoire dans votre code 189 00:15:32,100 --> 00:15:35,680 qui ont des variables locales? >> Oui, vous le pouvez. 190 00:15:35,680 --> 00:15:45,900 A l'intérieur de la barre int nous pourrions avoir {int y = 3;}. 191 00:15:45,900 --> 00:15:48,440 C'est censé être ici. 192 00:15:48,440 --> 00:15:52,450 Mais qui définit complètement la portée de int y. 193 00:15:52,450 --> 00:15:57,320 Après cette deuxième entretoise bouclés, y ne peut plus être utilisée. 194 00:15:57,910 --> 00:16:00,630 Vous avez failli ne jamais le faire, cependant. 195 00:16:02,940 --> 00:16:07,370 Pour en revenir à ce qui se passe quand un programme se termine, 196 00:16:07,370 --> 00:16:18,760 il ya une sorte de mensonge méprise / demi que nous donnons dans le but de faire juste les choses plus faciles. 197 00:16:18,760 --> 00:16:24,410 Nous vous disons que lorsque vous allouer de la mémoire 198 00:16:24,410 --> 00:16:29,860 vous allouons une bonne partie de la RAM pour cette variable. 199 00:16:29,860 --> 00:16:34,190 Mais vous n'êtes pas vraiment en contact direct avec RAM jamais dans vos programmes. 200 00:16:34,190 --> 00:16:37,490 Si vous y pensez, comment j'ai dessiné - 201 00:16:37,490 --> 00:16:44,330 Et en fait, si vous passez par chez GDB, vous verrez la même chose. 202 00:16:51,120 --> 00:16:57,590 Peu importe combien de fois vous exécutez votre programme ou le programme que vous utilisez, 203 00:16:57,590 --> 00:16:59,950 la pile va toujours commencer - 204 00:16:59,950 --> 00:17:06,510 vous allez toujours à voir les variables autour de quelque chose oxbffff adresse. 205 00:17:06,510 --> 00:17:09,470 C'est généralement quelque part dans cette région. 206 00:17:09,470 --> 00:17:18,760 Mais comment pouvons-2 programmes peut avoir des pointeurs vers la même mémoire? 207 00:17:20,640 --> 00:17:27,650 [L'élève] Il ya une désignation arbitraire de oxbfff où est censé être sur la RAM 208 00:17:27,650 --> 00:17:31,320 qui peut réellement être dans des endroits différents selon le moment où la fonction a été appelée. 209 00:17:31,320 --> 00:17:35,920 Ouais. Le terme est la mémoire virtuelle. 210 00:17:35,920 --> 00:17:42,250 L'idée est que chaque processus, chaque programme qui s'exécute sur votre ordinateur 211 00:17:42,250 --> 00:17:49,450 dispose de son propre - supposons 32 bits - espace d'adressage complètement indépendant. 212 00:17:49,450 --> 00:17:51,590 C'est l'espace d'adressage. 213 00:17:51,590 --> 00:17:56,220 Elle a ses propres complètement indépendants de 4 giga-octets à utiliser. 214 00:17:56,220 --> 00:18:02,220 >> Donc, si vous exécutez 2 programmes simultanément, ce programme voit 4 gigaoctets à lui-même, 215 00:18:02,220 --> 00:18:04,870 ce programme voit 4 gigaoctets à lui-même, 216 00:18:04,870 --> 00:18:07,720 et il est impossible pour ce programme de déréférencer un pointeur 217 00:18:07,720 --> 00:18:10,920 et se retrouver avec la mémoire de ce programme. 218 00:18:10,920 --> 00:18:18,200 Et que la mémoire virtuelle est une application d'un espace d'adresses des processus 219 00:18:18,200 --> 00:18:20,470 à des choses réelles sur la RAM. 220 00:18:20,470 --> 00:18:22,940 Donc, c'est à votre système d'exploitation pour savoir que, 221 00:18:22,940 --> 00:18:28,080 hey, quand ce gars oxbfff pointeur déréférence, que cela signifie vraiment 222 00:18:28,080 --> 00:18:31,040 qu'il veut octets de RAM 1000, 223 00:18:31,040 --> 00:18:38,150 tandis que si le programme de déréférence ce oxbfff, il veut vraiment octets de RAM 10000. 224 00:18:38,150 --> 00:18:41,590 Ils peuvent être arbitrairement éloignés. 225 00:18:41,590 --> 00:18:48,730 Cela est vrai même des choses dans un espace d'adressage des processus unique. 226 00:18:48,730 --> 00:18:54,770 Donc, comme il voit les 4 giga-octets de lui-même, mais disons - 227 00:18:54,770 --> 00:18:57,290 [L'élève] Est-ce que tous les processus - 228 00:18:57,290 --> 00:19:01,350 Disons que vous avez un ordinateur avec seulement 4 Go de RAM. 229 00:19:01,350 --> 00:19:06,430 Est-ce que tous les processus unique voir les 4 giga-octets entiers? Oui >>. 230 00:19:06,430 --> 00:19:13,060 Mais les 4 gigaoctets qu'il voit est un mensonge. 231 00:19:13,060 --> 00:19:20,460 C'est juste qu'il pense qu'il a tout ce mémoire, car il ne sait pas tout autre processus existe. 232 00:19:20,460 --> 00:19:28,140 Il utilisera uniquement la mémoire autant qu'il a réellement besoin. 233 00:19:28,140 --> 00:19:32,340 Le système d'exploitation ne va pas donner de RAM pour ce processus 234 00:19:32,340 --> 00:19:35,750 si ce n'est pas en utilisant toute la mémoire dans toute cette région. 235 00:19:35,750 --> 00:19:39,300 Il ne va pas lui donner la mémoire pour cette région. 236 00:19:39,300 --> 00:19:54,780 Mais l'idée est que - je suis en train de penser - je ne peux pas penser à une analogie. 237 00:19:54,780 --> 00:19:56,780 Les analogies sont difficiles. 238 00:19:57,740 --> 00:20:02,700 L'un des problèmes de mémoire virtuelle ou l'une des choses c'est de résolution 239 00:20:02,700 --> 00:20:06,810 est que les processus doivent être complètement inconscient de l'autre. 240 00:20:06,810 --> 00:20:12,140 Et si vous pouvez écrire un programme qui vient tout déréférence de pointeur, 241 00:20:12,140 --> 00:20:19,340 comme il suffit d'écrire un programme qui dit * (ox1234), 242 00:20:19,340 --> 00:20:22,890 et que l'adresse mémoire déréférencement 1234. 243 00:20:22,890 --> 00:20:28,870 >> Mais il appartient au système d'exploitation pour ensuite traduire ce moyen 1234. 244 00:20:28,870 --> 00:20:33,960 Donc, si 1234 se trouve être une adresse mémoire valide pour ce processus, 245 00:20:33,960 --> 00:20:38,800 comme il est sur la pile ou quelque chose, alors ce sera de retour la valeur de cette adresse mémoire 246 00:20:38,800 --> 00:20:41,960 dans la mesure où le processus courant. 247 00:20:41,960 --> 00:20:47,520 Mais si 1234 est pas une adresse valide, comme il arrive à la terre 248 00:20:47,520 --> 00:20:52,910 dans certains petit morceau de la mémoire qui est ici au-delà de la pile et le tas au-delà 249 00:20:52,910 --> 00:20:57,200 et vous n'avez pas vraiment utilisé que, alors que c'est quand vous obtenez des choses comme des erreurs de segmentation 250 00:20:57,200 --> 00:21:00,260 parce que vous touchez mémoire que vous ne doit pas toucher. 251 00:21:07,180 --> 00:21:09,340 Cela est également vrai - 252 00:21:09,340 --> 00:21:15,440 Un système 32 bits, 32 bits signifie que vous avez 32 bits pour définir une adresse mémoire. 253 00:21:15,440 --> 00:21:22,970 C'est pourquoi les pointeurs sont de 8 octets, car 32 bits ya 8 octets - ou 4 octets. 254 00:21:22,970 --> 00:21:25,250 Les pointeurs sont 4 octets. 255 00:21:25,250 --> 00:21:33,680 Alors, quand vous voyez un pointeur comme oxbfffff, c'est - 256 00:21:33,680 --> 00:21:40,080 Dans un programme donné, vous pouvez simplement construire un pointeur arbitraire, 257 00:21:40,080 --> 00:21:46,330 n'importe où à partir ox0 de bœuf 8 f's - ffffffff. 258 00:21:46,330 --> 00:21:49,180 [L'élève] N'avez-vous pas dire qu'ils sont 4 octets? Ouais >>. 259 00:21:49,180 --> 00:21:52,730 [L'élève] Ensuite, chaque octet aura - >> [Bowden] Hexadécimal. 260 00:21:52,730 --> 00:21:59,360 Hexadécimal - 5, 6, 7, 8. Donc pointeurs vous allez toujours voir en hexadécimal. 261 00:21:59,360 --> 00:22:01,710 C'est juste la façon dont nous classons les pointeurs. 262 00:22:01,710 --> 00:22:05,240 Tous les 2 chiffres du hexadécimale est de 1 octet. 263 00:22:05,240 --> 00:22:09,600 Donc, il va y avoir 8 chiffres hexadécimaux de 4 octets. 264 00:22:09,600 --> 00:22:14,190 Ainsi, chaque pointeur unique sur un système 32-bit va être 4 octets, 265 00:22:14,190 --> 00:22:18,550 ce qui signifie que dans votre processus, vous pouvez construire tout 4 octets arbitraires 266 00:22:18,550 --> 00:22:20,550 et faire un pointeur sur elle, 267 00:22:20,550 --> 00:22:32,730 ce qui signifie que dans la mesure où il est courant, il peut traiter un ensemble de 2 à 32 octets de la mémoire. 268 00:22:32,730 --> 00:22:34,760 Même si elle n'a pas vraiment d'avoir accès à cela, 269 00:22:34,760 --> 00:22:40,190 même si votre ordinateur ne dispose que de 512 mégaoctets, il pense qu'il a autant de mémoire. 270 00:22:40,190 --> 00:22:44,930 Et le système d'exploitation est assez intelligent pour qu'il n'attribuera ce que vous avez réellement besoin. 271 00:22:44,930 --> 00:22:49,630 Il ne se contente pas y aller, oh, un nouveau procédé: 4 concerts. 272 00:22:49,630 --> 00:22:51,930 >> Ouais. >> [L'élève] Qu'est-ce que le bœuf veut dire? Pourquoi pensez-vous écrire? 273 00:22:51,930 --> 00:22:54,980 C'est juste le symbole hexadécimal. 274 00:22:54,980 --> 00:22:59,590 Quand vous voyez un numéro de départ avec le bœuf, les choses successives sont en hexadécimal. 275 00:23:01,930 --> 00:23:05,760 [L'élève] Vous avez expliqué ce qui se passe quand un programme se termine. Oui >>. 276 00:23:05,760 --> 00:23:09,480 Qu'est-ce qui se passe quand un programme se termine est le système d'exploitation 277 00:23:09,480 --> 00:23:13,600 seulement efface les mappages qu'il a pour ces adresses, et c'est tout. 278 00:23:13,600 --> 00:23:17,770 Le système d'exploitation peut maintenant vous donner que la mémoire à un autre programme à utiliser. 279 00:23:17,770 --> 00:23:19,490 [L'élève] D'accord. 280 00:23:19,490 --> 00:23:24,800 Donc, lorsque vous affectez quelque chose sur le tas ou les variables de la pile ou mondial ou quelque chose, 281 00:23:24,800 --> 00:23:27,010 ils ont tous simplement disparaître dès la fin du programme 282 00:23:27,010 --> 00:23:32,120 parce que le système d'exploitation est maintenant libre de donner ce mémoire à un autre procédé. 283 00:23:32,120 --> 00:23:35,150 [L'élève] Même s'il ya probablement encore des valeurs écrites en? Ouais >>. 284 00:23:35,150 --> 00:23:37,740 Les valeurs sont probablement encore là. 285 00:23:37,740 --> 00:23:41,570 C'est juste que ça va être difficile de les atteindre. 286 00:23:41,570 --> 00:23:45,230 Il est beaucoup plus difficile de les atteindre que de l'obtenir à un fichier supprimé 287 00:23:45,230 --> 00:23:51,450 parce que le type de fichier supprimé est assis là pendant une longue période et le disque dur est beaucoup plus grand. 288 00:23:51,450 --> 00:23:54,120 Donc, il va écraser des parties différentes de la mémoire 289 00:23:54,120 --> 00:23:58,640 avant qu'il arrive à écraser le morceau de mémoire que ce fichier sert à être à. 290 00:23:58,640 --> 00:24:04,520 Mais la mémoire principale, la mémoire vive, vous faites défiler beaucoup plus vite, 291 00:24:04,520 --> 00:24:08,040 il va très vite être remplacé. 292 00:24:10,300 --> 00:24:13,340 Questions sur ceci ou autre chose? 293 00:24:13,340 --> 00:24:16,130 [L'élève] J'ai des questions sur un sujet différent. Ok >>. 294 00:24:16,130 --> 00:24:19,060 Quelqu'un at-il des questions à ce sujet? 295 00:24:20,170 --> 00:24:23,120 >> D'accord. Sujet différent. >> [L'élève] D'accord. 296 00:24:23,120 --> 00:24:26,550 Je passais par quelques-uns des tests pratiques, 297 00:24:26,550 --> 00:24:30,480 et dans l'un d'eux parlait du sizeof 298 00:24:30,480 --> 00:24:35,630 et la valeur qu'il renvoie ou différents types de variables. Oui >>. 299 00:24:35,630 --> 00:24:45,060 Et il a dit que les deux int et long à la fois le retour 4, de sorte qu'ils sont tous les deux de 4 octets. 300 00:24:45,060 --> 00:24:48,070 Y at-il une différence entre un int et un long, ou est-ce la même chose? 301 00:24:48,070 --> 00:24:50,380 Oui, il ya une différence. 302 00:24:50,380 --> 00:24:52,960 Le standard C - 303 00:24:52,960 --> 00:24:54,950 Je vais probablement mettre en désordre. 304 00:24:54,950 --> 00:24:58,800 Le standard C est juste comme ce que C est à la documentation officielle de C. 305 00:24:58,800 --> 00:25:00,340 C'est ce qu'il dit. 306 00:25:00,340 --> 00:25:08,650 Ainsi, le standard C indique juste que un char sera pour toujours et toujours être à 1 octet. 307 00:25:10,470 --> 00:25:19,040 Tout ce qui suit - une courte est toujours défini comme étant juste supérieure ou égale à un produit de carbonisation. 308 00:25:19,040 --> 00:25:23,010 Cela pourrait être strictement supérieur, mais pas positive. 309 00:25:23,010 --> 00:25:31,940 Un int est simplement définie comme étant supérieure ou égale à une courte. 310 00:25:31,940 --> 00:25:36,210 Et une longue est simplement définie comme étant supérieure ou égale à un entier. 311 00:25:36,210 --> 00:25:41,600 Et un long long est supérieure ou égale à une longueur. 312 00:25:41,600 --> 00:25:46,610 Donc, la seule chose que la norme C définit l'ordre relatif est de tout. 313 00:25:46,610 --> 00:25:54,880 La quantité réelle de mémoire que les choses prennent place est généralement à la mise en œuvre, 314 00:25:54,880 --> 00:25:57,640 mais il est assez bien définie à ce stade. >> [L'élève] D'accord. 315 00:25:57,640 --> 00:26:02,490 Ainsi, les shorts sont presque toujours va être de 2 octets. 316 00:26:04,920 --> 00:26:09,950 Ints sont presque toujours va être de 4 octets. 317 00:26:12,070 --> 00:26:15,340 Longs longs sont presque toujours va être de 8 octets. 318 00:26:17,990 --> 00:26:23,160 Et aspire, cela dépend si vous utilisez une version 32 bits ou un système 64-bit. 319 00:26:23,160 --> 00:26:27,450 Si une longue va correspondre au type de système. 320 00:26:27,450 --> 00:26:31,920 Si vous utilisez un système 32-bit, comme l'appareil, il va y avoir 4 octets. 321 00:26:34,530 --> 00:26:42,570 Si vous utilisez une version 64-bit comme un grand nombre d'ordinateurs récents, il va être de 8 octets. 322 00:26:42,570 --> 00:26:45,230 >> Ints sont presque toujours 4 octets à ce stade. 323 00:26:45,230 --> 00:26:47,140 Longs longs sont presque toujours de 8 octets. 324 00:26:47,140 --> 00:26:50,300 Dans le passé, ints utilisé pour être que 2 octets. 325 00:26:50,300 --> 00:26:56,840 Mais remarquez que cette satisfait complètement tous ces rapports de plus grande et égale à. 326 00:26:56,840 --> 00:27:01,280 Donc, est depuis longtemps parfaitement le droit d'être de la même taille comme un entier, 327 00:27:01,280 --> 00:27:04,030 et il est également autorisé à être la même taille qu'un long long. 328 00:27:04,030 --> 00:27:11,070 Et il se trouve être celle de 99,999% des systèmes, il va être égal à 329 00:27:11,070 --> 00:27:15,800 soit un int ou un long long. Tout dépend de la 32-bit ou 64-bit. >> [L'élève] D'accord. 330 00:27:15,800 --> 00:27:24,600 En flotteurs, comment est le point décimal désigné en termes de bits? 331 00:27:24,600 --> 00:27:27,160 Comme en binaire? Ouais >>. 332 00:27:27,160 --> 00:27:30,570 Vous n'avez pas besoin de savoir que pour CS50. 333 00:27:30,570 --> 00:27:32,960 Vous n'avez même pas savoir que dans 61. 334 00:27:32,960 --> 00:27:37,350 On n'apprend pas vraiment que dans n'importe quel cours. 335 00:27:37,350 --> 00:27:42,740 C'est juste une représentation. 336 00:27:42,740 --> 00:27:45,440 J'ai oublié les attributions exactes bits. 337 00:27:45,440 --> 00:27:53,380 L'idée de la virgule flottante, c'est que vous allouez un certain nombre de bits pour représenter - 338 00:27:53,380 --> 00:27:56,550 Fondamentalement, tout ce qui est en notation scientifique. 339 00:27:56,550 --> 00:28:05,600 Donc, vous allouez un nombre spécifique de bits pour représenter le nombre lui-même, comme 1,2345. 340 00:28:05,600 --> 00:28:10,200 Je ne pourrai jamais représenter un nombre avec plus de chiffres que 5. 341 00:28:12,200 --> 00:28:26,300 Alors vous aussi allouer un nombre spécifique de bits de sorte qu'il a tendance à être comme 342 00:28:26,300 --> 00:28:32,810 vous ne pouvez aller à un certain nombre, comme c'est le plus grand exposant, vous pouvez avoir, 343 00:28:32,810 --> 00:28:36,190 et vous ne pouvez descendre à un exposant donné, 344 00:28:36,190 --> 00:28:38,770 comme c'est le plus petit exposant vous pouvez avoir. 345 00:28:38,770 --> 00:28:44,410 >> Je ne me souviens pas de façon exacte les bits sont affectés à l'ensemble de ces valeurs, 346 00:28:44,410 --> 00:28:47,940 mais un certain nombre de bits sont consacrés à 1,2345, 347 00:28:47,940 --> 00:28:50,930 un autre certain nombre de bits sont consacrés à l'exposant, 348 00:28:50,930 --> 00:28:55,670 et il est seulement possible de représenter un exposant d'une certaine taille. 349 00:28:55,670 --> 00:29:01,100 [L'élève] Et un double? Est-ce comme un flotteur extra long? Ouais >>. 350 00:29:01,100 --> 00:29:07,940 C'est la même chose que d'un flotteur sauf que maintenant vous utilisez 8 octets au lieu de 4 octets. 351 00:29:07,940 --> 00:29:11,960 Maintenant, vous serez en mesure d'utiliser 9 chiffres ou 10 chiffres, 352 00:29:11,960 --> 00:29:16,630 et cela pourra aller jusqu'à 300 au lieu de 100. >> [L'élève] D'accord. 353 00:29:16,630 --> 00:29:21,550 Et flotteurs sont aussi 4 octets. Oui >>. 354 00:29:21,550 --> 00:29:27,520 Eh bien, encore une fois, cela dépend probablement d'ensemble sur l'application générale, 355 00:29:27,520 --> 00:29:30,610 mais flotteurs sont 4 octets, les doubles sont 8. 356 00:29:30,610 --> 00:29:33,440 Doubles sont appelés double, car ils sont le double de la taille des flotteurs. 357 00:29:33,440 --> 00:29:38,380 [L'élève] D'accord. Et y at-il double double? >> Il n'y a pas. 358 00:29:38,380 --> 00:29:43,660 Je pense - >> [l'élève] Comme longs longs? Ouais >>. Je ne le pense pas. Oui. 359 00:29:43,660 --> 00:29:45,950 [L'élève] Le test de l'année dernière, il y avait une question sur la fonction principale 360 00:29:45,950 --> 00:29:49,490 avoir à faire partie de votre programme. 361 00:29:49,490 --> 00:29:52,310 La réponse a été qu'il n'a pas à faire partie de votre programme. 362 00:29:52,310 --> 00:29:55,100 Dans quelle situation? C'est ce que j'ai vu. 363 00:29:55,100 --> 00:29:59,090 [Bowden] Il semble - >> [l'élève] Quelle est la situation? 364 00:29:59,090 --> 00:30:02,880 Avez-vous le problème? >> [L'élève] Oui, je peux le tirer vers le haut. 365 00:30:02,880 --> 00:30:07,910 Il ne doit pas être, techniquement, mais fondamentalement, il va être. 366 00:30:07,910 --> 00:30:10,030 [L'élève] J'ai vu un sur un autre de l'année. 367 00:30:10,030 --> 00:30:16,220 C'était comme Vrai ou faux: Un valables - >> Oh, un fichier c.? 368 00:30:16,220 --> 00:30:18,790 . [L'élève] Tout fichier doit avoir c - [les deux parlent en même temps - inintelligible] 369 00:30:18,790 --> 00:30:21,120 D'accord. C'est donc séparé. 370 00:30:21,120 --> 00:30:26,800 >> Un fichier. C doit juste contenir fonctions. 371 00:30:26,800 --> 00:30:32,400 Vous pouvez compiler un fichier en code machine, binaire, que ce soit, 372 00:30:32,400 --> 00:30:36,620 sans qu'il soit exécutable pour le moment. 373 00:30:36,620 --> 00:30:39,420 Un exécutable valide doit avoir une fonction principale. 374 00:30:39,420 --> 00:30:45,460 Vous pouvez écrire 100 fonctions dans 1 fichier, mais pas de grandes 375 00:30:45,460 --> 00:30:48,800 et ensuite compiler que jusqu'à binaire, 376 00:30:48,800 --> 00:30:54,460 alors vous écrire un autre fichier qui n'a principale mais il demande un tas de ces fonctions 377 00:30:54,460 --> 00:30:56,720 dans ce fichier binaire ici. 378 00:30:56,720 --> 00:31:01,240 Et donc quand vous faites de l'exécutable, c'est ce que l'éditeur de liens ne 379 00:31:01,240 --> 00:31:05,960 est il combine ces 2 fichiers binaires dans un fichier exécutable. 380 00:31:05,960 --> 00:31:11,400 Ainsi, un fichier. C n'a pas besoin d'avoir une fonction principale à tous. 381 00:31:11,400 --> 00:31:19,220 Et sur les bases de code, vous verrez de grands milliers de fichiers et c. 1 fichier principal. 382 00:31:23,960 --> 00:31:26,110 Plus de questions? 383 00:31:29,310 --> 00:31:31,940 [L'élève] Il y avait une autre question. 384 00:31:31,940 --> 00:31:36,710 Il a dit faire est un compilateur. Vrai ou Faux? 385 00:31:36,710 --> 00:31:42,030 Et la réponse était fausse, et j'ai compris pourquoi ce n'est pas comme Clang. 386 00:31:42,030 --> 00:31:44,770 Mais qu'est-ce que nous appelons faire si ce n'est pas? 387 00:31:44,770 --> 00:31:49,990 Assurez est fondamentalement juste - je peux voir exactement ce qu'il l'appelle. 388 00:31:49,990 --> 00:31:52,410 Mais il fonctionne très commandes. 389 00:31:53,650 --> 00:31:55,650 Faire. 390 00:31:58,240 --> 00:32:00,870 Je peux tirer de cette place. Ouais. 391 00:32:10,110 --> 00:32:13,180 Oh, ouais. Assurez fait aussi cela. 392 00:32:13,180 --> 00:32:17,170 Cela indique que le but de l'utilitaire make est de déterminer automatiquement 393 00:32:17,170 --> 00:32:19,610 quelles pièces d'un vaste programme devront être recompilés 394 00:32:19,610 --> 00:32:22,350 et exécutez les commandes pour les recompiler. 395 00:32:22,350 --> 00:32:27,690 Vous pouvez faire faire des fichiers qui sont absolument énormes. 396 00:32:27,690 --> 00:32:33,210 Assurez regarde les horodatages des fichiers et, comme nous l'avons dit, 397 00:32:33,210 --> 00:32:36,930 vous pouvez compiler des fichiers individuels vers le bas, et il n'est pas jusqu'à ce que vous arrivez à l'éditeur de liens 398 00:32:36,930 --> 00:32:39,270 qu'ils sont mis ensemble dans un fichier exécutable. 399 00:32:39,270 --> 00:32:43,810 Donc, si vous avez 10 fichiers différents et vous apportez une modification à 1 d'entre eux, 400 00:32:43,810 --> 00:32:47,870 alors qu'est-ce marque va faire, c'est juste que recompiler 1 fichier 401 00:32:47,870 --> 00:32:50,640 puis la relier le tout. 402 00:32:50,640 --> 00:32:53,020 Mais c'est beaucoup plus bête que cela. 403 00:32:53,020 --> 00:32:55,690 C'est à vous de définir complètement que c'est ce qu'il devrait faire. 404 00:32:55,690 --> 00:32:59,560 Il a par défaut la capacité de reconnaître ce genre de choses horodatage, 405 00:32:59,560 --> 00:33:03,220 mais vous pouvez écrire un fichier make rien faire. 406 00:33:03,220 --> 00:33:09,150 Vous pouvez écrire un fichier make sorte que lorsque vous tapez le rendre juste cd dans un autre répertoire. 407 00:33:09,150 --> 00:33:15,560 J'étais frustré parce que tout amure Je intérieur de mon appareil 408 00:33:15,560 --> 00:33:21,740 puis-je consulter le PDF à partir du Mac. 409 00:33:21,740 --> 00:33:30,720 >> Donc je vais Finder et que je peux faire Allez, Se connecter au serveur, 410 00:33:30,720 --> 00:33:36,950 et le serveur je me connecte à mon Appliance est, puis-je ouvrir le PDF 411 00:33:36,950 --> 00:33:40,190 qui est compilée par LaTeX. 412 00:33:40,190 --> 00:33:49,320 Mais j'ai été frustré parce que chaque fois que j'avais besoin de rafraîchir le PDF, 413 00:33:49,320 --> 00:33:53,900 J'ai eu à le copier dans un répertoire spécifique qu'elle pourrait accéder à 414 00:33:53,900 --> 00:33:57,710 et il devenait gênant. 415 00:33:57,710 --> 00:34:02,650 Ainsi, au lieu que j'ai écrit un fichier de marque, que vous devez définir la façon dont il rend les choses. 416 00:34:02,650 --> 00:34:06,130 Comment vous faites dans ce PDF LaTeX. 417 00:34:06,130 --> 00:34:10,090 Tout comme n'importe quel fichier autre marque - ou je suppose que vous n'avez pas vu les fichiers make, 418 00:34:10,090 --> 00:34:13,510 mais nous avons dans l'appareil un fichier marque mondiale qui dit simplement, 419 00:34:13,510 --> 00:34:16,679 si vous compilez un fichier C, utilisez Clang. 420 00:34:16,679 --> 00:34:20,960 Et alors voici dans mon dossier que je fais make-je dire, 421 00:34:20,960 --> 00:34:25,020 ce fichier que vous allez avoir à compiler avec LaTeX PDF. 422 00:34:25,020 --> 00:34:27,889 Et il est donc LaTeX PDF qui a fait la compilation. 423 00:34:27,889 --> 00:34:31,880 Assurez n'est pas la compilation. C'est juste exécutant ces commandes dans la séquence I spécifié. 424 00:34:31,880 --> 00:34:36,110 Donc, il va LaTeX PDF, il le copie dans le répertoire que je veux qu'il soit copié, 425 00:34:36,110 --> 00:34:38,270 il cd dans le répertoire et fait d'autres choses, 426 00:34:38,270 --> 00:34:42,380 mais tout ce qu'il fait est de reconnaître quand un fichier est modifié, 427 00:34:42,380 --> 00:34:45,489 et si elle change, alors il exécute les commandes qu'il est censé fonctionner 428 00:34:45,489 --> 00:34:48,760 lorsque le fichier est modifié. >> [L'élève] D'accord. 429 00:34:50,510 --> 00:34:54,420 Je ne sais pas où les fichiers make mondiaux sont pour moi de le vérifier. 430 00:34:57,210 --> 00:35:04,290 D'autres questions? Quelque chose de passé quiz? Toutes choses pointeur? 431 00:35:06,200 --> 00:35:08,730 Il ya des choses subtiles avec des pointeurs comme - 432 00:35:08,730 --> 00:35:10,220 Je ne vais pas être en mesure de trouver une question quiz sur elle - 433 00:35:10,220 --> 00:35:16,250 mais comme ce genre de chose. 434 00:35:19,680 --> 00:35:24,060 Assurez-vous que vous comprenez que quand je dis int * x * y - 435 00:35:24,890 --> 00:35:28,130 Ce n'est pas exactement quelque chose ici, je suppose. 436 00:35:28,130 --> 00:35:32,140 Mais comme * x * y, ce sont 2 variables qui sont sur la pile. 437 00:35:32,140 --> 00:35:37,220 Quand je dis x = malloc (sizeof (int)), x est toujours une variable sur la pile, 438 00:35:37,220 --> 00:35:41,180 malloc est une rue plus loin dans le tas, et nous allons avoir point x sur le tas. 439 00:35:41,180 --> 00:35:43,900 >> Donc, quelque chose sur les points de pile au tas. 440 00:35:43,900 --> 00:35:48,100 Chaque fois que vous malloc quoi que ce soit, vous êtes inévitablement le stocker à l'intérieur d'un pointeur. 441 00:35:48,100 --> 00:35:55,940 De sorte que le pointeur est sur la pile, le bloc est malloced sur le tas. 442 00:35:55,940 --> 00:36:01,240 Beaucoup de gens se confondre et dire int * x = malloc, x est sur le tas. 443 00:36:01,240 --> 00:36:04,100 Non, ce que x pointe vers est sur le tas. 444 00:36:04,100 --> 00:36:08,540 x lui-même est sur la pile, sauf si pour une raison quelconque vous avez x est une variable globale, 445 00:36:08,540 --> 00:36:11,960 Dans ce cas, il arrive à être dans une autre région de la mémoire. 446 00:36:13,450 --> 00:36:20,820 Donc garder la trace, ces diagrammes boîte et la flèche sont assez commun pour le quiz. 447 00:36:20,820 --> 00:36:25,740 Ou si ce n'est pas le quiz 0, ce sera le quiz 1. 448 00:36:27,570 --> 00:36:31,940 Vous devriez savoir tout cela, les étapes de la compilation 449 00:36:31,940 --> 00:36:35,740 depuis que vous avez eu à répondre à des questions sur ceux-ci. Oui. 450 00:36:35,740 --> 00:36:38,940 [L'élève] Pourrait-on passer en revue ces étapes - >> Bien sûr. 451 00:36:48,340 --> 00:36:58,640 Avant étapes et la compilation que nous avons pré-traitement, 452 00:36:58,640 --> 00:37:16,750 la compilation, l'assemblage et la liaison. 453 00:37:16,750 --> 00:37:21,480 Le pré-traitement. Qu'est-ce que ça fait? 454 00:37:29,720 --> 00:37:32,290 C'est l'étape la plus facile à - bien, pas comme - 455 00:37:32,290 --> 00:37:35,770 cela ne signifie pas qu'il devrait être évident, mais ce n'est étape la plus facile. 456 00:37:35,770 --> 00:37:38,410 Les gars, vous pourriez mettre en œuvre vous-mêmes. Ouais. 457 00:37:38,410 --> 00:37:43,410 [L'élève] Prenez ce que vous avez dans votre comprend comme ceci et le copie puis définit également. 458 00:37:43,410 --> 00:37:49,250 Il cherche des choses comme # include et # define, 459 00:37:49,250 --> 00:37:53,800 et que des copies et des pâtes ce que ceux qui veulent réellement dire. 460 00:37:53,800 --> 00:37:59,240 Donc quand vous dites # include cs50.h, le préprocesseur est un copier-coller cs50.h 461 00:37:59,240 --> 00:38:01,030 dans cette ligne. 462 00:38:01,030 --> 00:38:06,640 Quand vous dites # define x est 4, le préprocesseur passe par l'ensemble du programme 463 00:38:06,640 --> 00:38:10,400 et remplace toutes les occurrences de x par 4. 464 00:38:10,400 --> 00:38:17,530 Ainsi, le préprocesseur prend un fichier C valide et génère un fichier valide C 465 00:38:17,530 --> 00:38:20,300 où les choses ont été copiées et collées. 466 00:38:20,300 --> 00:38:24,230 Alors maintenant compiler. Qu'est-ce que ça fait? 467 00:38:25,940 --> 00:38:28,210 [L'élève] Il va de C en binaire. 468 00:38:28,210 --> 00:38:30,970 >> [Bowden] Il ne va pas tout le chemin vers le binaire. 469 00:38:30,970 --> 00:38:34,220 [L'élève] Pour le code machine alors? >> Il ne s'agit pas du code machine. 470 00:38:34,220 --> 00:38:35,700 [L'élève] Assemblée? >> Assemblée. 471 00:38:35,700 --> 00:38:38,890 Il va à l'Assemblée avant qu'il va tout le chemin en code C, 472 00:38:38,890 --> 00:38:45,010 et la plupart des langues faire quelque chose comme ça. 473 00:38:47,740 --> 00:38:50,590 Choisissez n'importe quel langage de haut niveau, et si vous allez pour le compiler, 474 00:38:50,590 --> 00:38:52,390 il est probable que de compiler en plusieurs étapes. 475 00:38:52,390 --> 00:38:58,140 D'abord, il va compiler Python à C, alors il va compiler C à l'Assemblée, 476 00:38:58,140 --> 00:39:01,600 puis l'Assemblée va se traduit en binaire. 477 00:39:01,600 --> 00:39:07,800 Ainsi, la compilation se passe pour le porter de C à l'Assemblée. 478 00:39:07,800 --> 00:39:12,130 Le mot compilation signifie généralement qu'il porte à partir d'un niveau plus élevé 479 00:39:12,130 --> 00:39:14,340 à un langage de programmation de niveau inférieur. 480 00:39:14,340 --> 00:39:19,190 Donc, c'est la seule étape dans la compilation où vous commencez avec un langage de haut niveau 481 00:39:19,190 --> 00:39:23,270 et se retrouvent dans un langage de bas niveau, et c'est pourquoi l'étape est appelée la compilation. 482 00:39:25,280 --> 00:39:33,370 [L'élève] Au cours de la compilation, disons que vous avez fait # include cs50.h. 483 00:39:33,370 --> 00:39:42,190 Est-ce que le compilateur recompiler le cs50.h, que les fonctions qui sont là-dedans, 484 00:39:42,190 --> 00:39:45,280 et les traduire en code Assembleur ainsi, 485 00:39:45,280 --> 00:39:50,830 ou seront-ils copier et coller quelque chose qui a été pré-assemblée? 486 00:39:50,830 --> 00:39:56,910 cs50.h sera à peu près jamais se retrouver à l'Assemblée. 487 00:39:59,740 --> 00:40:03,680 Des trucs comme les prototypes de fonctions et les choses sont pour vous d'être prudent. 488 00:40:03,680 --> 00:40:09,270 Elle garantit que le compilateur peut vérifier des choses comme vous appelez des fonctions 489 00:40:09,270 --> 00:40:12,910 avec les bons types de retour et les arguments bons et des trucs. 490 00:40:12,910 --> 00:40:18,350 >> Donc cs50.h seront prétraitées dans le fichier, puis quand il est la compilation 491 00:40:18,350 --> 00:40:22,310 c'est essentiellement jetés après il permet de s'assurer que tout a été appelée correctement. 492 00:40:22,310 --> 00:40:29,410 Mais les fonctions définies dans la bibliothèque CS50, qui sont séparés de cs50.h, 493 00:40:29,410 --> 00:40:33,610 ceux qui ne seront pas compilés séparément. 494 00:40:33,610 --> 00:40:37,270 Cela fait descendre dans l'étape de liaison, donc nous allons y revenir dans un instant. 495 00:40:37,270 --> 00:40:40,100 Mais d'abord, qu'est-ce montage? 496 00:40:41,850 --> 00:40:44,500 [L'élève] Assemblée en binaire? Ouais >>. 497 00:40:46,300 --> 00:40:48,190 Montage. 498 00:40:48,190 --> 00:40:54,710 Nous n'appelons pas à le compiler, car l'Assemblée est à peu près une traduction pure du binaire. 499 00:40:54,710 --> 00:41:00,230 Il ya très peu de logique pour aller de l'Assemblée en binaire. 500 00:41:00,230 --> 00:41:03,180 C'est comme regarder dans une table, oh, nous avons cette instruction; 501 00:41:03,180 --> 00:41:06,290 qui correspond à la valeur binaire 01110. 502 00:41:10,200 --> 00:41:15,230 Et si les fichiers que l'assemblage sorties sont généralement des fichiers. O. 503 00:41:15,230 --> 00:41:19,020 Et les fichiers. O sont ce que nous disions auparavant, 504 00:41:19,020 --> 00:41:21,570 comment un fichier n'a pas besoin d'avoir une fonction principale. 505 00:41:21,570 --> 00:41:27,640 Tout fichier peut être compilé en un fichier. O tant qu'il s'agit d'un fichier valide C. 506 00:41:27,640 --> 00:41:30,300 Il peut être compilé en. O. 507 00:41:30,300 --> 00:41:43,030 Maintenant, ce qui apporte de liaison est en fait un tas de fichiers. O et les amène à un exécutable. 508 00:41:43,030 --> 00:41:51,110 Et si ce lien ne sont que vous pouvez penser à la bibliothèque CS50 sous forme de fichier. O. 509 00:41:51,110 --> 00:41:56,980 Il s'agit d'un fichier binaire déjà compilé. 510 00:41:56,980 --> 00:42:03,530 Et donc quand vous compilez votre fichier, votre hello.c, qui appelle GetString, 511 00:42:03,530 --> 00:42:06,360 hello.c est compilée vers le bas pour hello.o, 512 00:42:06,360 --> 00:42:08,910 hello.o est maintenant en binaire. 513 00:42:08,910 --> 00:42:12,830 Il utilise GetString, donc il doit passer à cs50.o, 514 00:42:12,830 --> 00:42:16,390 et l'éditeur de liens entre eux smooshes ensemble et copie GetString dans ce fichier 515 00:42:16,390 --> 00:42:20,640 et est livré avec un exécutable qui a toutes les fonctions dont il a besoin. 516 00:42:20,640 --> 00:42:32,620 Donc cs50.o n'est pas réellement un fichier joint, mais il est assez proche qu'il n'y a pas de différence fondamentale. 517 00:42:32,620 --> 00:42:36,880 Donc, reliant simplement apporte un tas de fichiers ainsi que 518 00:42:36,880 --> 00:42:41,390 que séparément contenir toutes les fonctions dont j'ai besoin pour utiliser 519 00:42:41,390 --> 00:42:46,120 et crée l'exécutable qui sera effectivement parcourue. 520 00:42:48,420 --> 00:42:50,780 >> Et donc c'est aussi ce que nous disions avant 521 00:42:50,780 --> 00:42:55,970 où vous pouvez avoir 1000. fichiers c, vous compilez tous à. fichiers o, 522 00:42:55,970 --> 00:43:00,040 ce qui prendra probablement un certain temps, puis vous changez 1. fichier c. 523 00:43:00,040 --> 00:43:05,480 Vous avez seulement besoin de recompiler que: 1. Fichier c et puis tout le reste relink, 524 00:43:05,480 --> 00:43:07,690 relier le tout nouveau ensemble. 525 00:43:09,580 --> 00:43:11,430 [L'élève] Lorsque nous lier nous écrivons lcs50? 526 00:43:11,430 --> 00:43:20,510 Ouais, soi-lcs50. Que les signaux de drapeau à l'éditeur de liens que vous devriez reliant dans cette bibliothèque. 527 00:43:26,680 --> 00:43:28,910 Des questions? 528 00:43:41,310 --> 00:43:46,860 Avons-nous dépassé binaire autre que de 5 secondes à la première conférence? 529 00:43:50,130 --> 00:43:53,010 Je ne le pense pas. 530 00:43:55,530 --> 00:43:58,820 Vous devez connaître tous les grands Os que nous avons passé en revue, 531 00:43:58,820 --> 00:44:02,670 et vous devriez être en mesure d', si nous vous avons donné une fonction, 532 00:44:02,670 --> 00:44:09,410 vous devriez être en mesure de dire que c'est grand O, à peu près. Ou bien, grand O est rugueuse. 533 00:44:09,410 --> 00:44:15,300 Donc, si vous voyez des boucles imbriquées en boucle sur le même nombre de choses, 534 00:44:15,300 --> 00:44:22,260 comme int i, i > [l'élève] n carré. >> Il tend à être n carré. 535 00:44:22,260 --> 00:44:25,280 Si vous avez triple imbriquées, il a tendance à être n cubes. 536 00:44:25,280 --> 00:44:29,330 Donc, ce genre de chose, vous devriez être en mesure de signaler immédiatement. 537 00:44:29,330 --> 00:44:33,890 Vous devez connaître le tri par insertion et tri à bulles et tri par fusion et l'ensemble de ceux-ci. 538 00:44:33,890 --> 00:44:41,420 Il est plus facile de comprendre pourquoi ils sont ceux carré et n n log n et tout cela 539 00:44:41,420 --> 00:44:47,810 parce que je pense qu'il y avait un quiz sur une année où nous avons essentiellement que vous avez donné 540 00:44:47,810 --> 00:44:55,050 une implémentation de tri à bulles et dit: «Qu'est-ce que le temps d'exécution de cette fonction?" 541 00:44:55,050 --> 00:45:01,020 Donc, si vous le reconnaissez comme une sorte de bulle, alors vous pouvez dire tout de suite n carré. 542 00:45:01,020 --> 00:45:05,470 Mais si vous regardez, vous n'avez même pas besoin de réaliser tri à bulles qu'il est; 543 00:45:05,470 --> 00:45:08,990 vous pouvez juste dire ce que fait ceci et cela. Ceci est n au carré. 544 00:45:12,350 --> 00:45:14,710 [L'élève] Y at-il des exemples difficiles que vous pouvez venir avec, 545 00:45:14,710 --> 00:45:20,370 comme une idée similaire de figurer dehors? 546 00:45:20,370 --> 00:45:24,450 >> Je ne pense pas que nous vous donner des exemples difficiles. 547 00:45:24,450 --> 00:45:30,180 La chose tri à bulles est à peu près aussi difficile que nous allions, 548 00:45:30,180 --> 00:45:36,280 et même que, aussi longtemps que vous comprenez que vous êtes l'itération sur le tableau 549 00:45:36,280 --> 00:45:41,670 pour chaque élément du tableau, ce qui va être quelque chose qui n au carré. 550 00:45:45,370 --> 00:45:49,940 Il ya des questions générales, comme ici nous avons - Oh. 551 00:45:55,290 --> 00:45:58,530 Juste l'autre jour, Doug a affirmé: «J'ai inventé un algorithme qui peut trier un tableau 552 00:45:58,530 --> 00:46:01,780 "De n nombres en O (log n)!" 553 00:46:01,780 --> 00:46:04,900 Alors, comment savons-nous que c'est impossible? 554 00:46:04,900 --> 00:46:08,850 [Réponse de l'élève inaudible] >> Oui. 555 00:46:08,850 --> 00:46:13,710 À tout le moins, vous avez de toucher chaque élément du tableau, 556 00:46:13,710 --> 00:46:16,210 il est donc impossible de trier un tableau de - 557 00:46:16,210 --> 00:46:20,850 Si tout est en ordre non triés, alors vous allez être en contact avec tout ce qui dans le tableau, 558 00:46:20,850 --> 00:46:25,320 il est donc impossible de le faire en moins de O de n. 559 00:46:27,430 --> 00:46:30,340 [L'élève] Vous nous avez montré que l'exemple de pouvoir le faire en temps O n 560 00:46:30,340 --> 00:46:33,920 si vous utilisez beaucoup de mémoire. Ouais >>. 561 00:46:33,920 --> 00:46:37,970 Et C'est - je ne sais plus ce que C'est - Est-il compter sorte? 562 00:46:47,360 --> 00:46:51,330 Hmm. C'est un algorithme de tri entier. 563 00:46:59,850 --> 00:47:05,100 Je cherchais le nom spécial pour cela que je ne me souvenais semaine dernière. 564 00:47:05,100 --> 00:47:13,000 Ouais. Ce sont les types de tri qui peuvent accomplir des choses en grand O de n. 565 00:47:13,000 --> 00:47:18,430 Mais il ya des limites, comme vous ne pouvez utiliser que des entiers jusqu'à un certain seuil. 566 00:47:20,870 --> 00:47:24,560 De plus, si vous essayez de trier that's quelque chose - 567 00:47:24,560 --> 00:47:30,750 Si votre tableau est 012, -12, 151, 4 millions, 568 00:47:30,750 --> 00:47:35,120 alors que seul élément qui va complètement ruiner le tri ensemble. 569 00:47:42,060 --> 00:47:44,030 >> Des questions? 570 00:47:49,480 --> 00:47:58,870 [L'élève] Si vous avez une fonction récursive et il est tout simplement les appels récursifs 571 00:47:58,870 --> 00:48:02,230 dans une instruction de retour, c'est récursive, 572 00:48:02,230 --> 00:48:07,360 et donc serait-ce pas utiliser plus de mémoire lors de l'exécution 573 00:48:07,360 --> 00:48:12,550 ou il serait au moins comparable utiliser la mémoire comme une solution itérative? 574 00:48:12,550 --> 00:48:14,530 [Bowden] Oui. 575 00:48:14,530 --> 00:48:19,840 Il serait sans doute un peu plus lent, mais pas vraiment. 576 00:48:19,840 --> 00:48:23,290 Récursive est très bonne. 577 00:48:23,290 --> 00:48:32,640 En regardant de nouveau les cadres de pile, disons que nous avons principal 578 00:48:32,640 --> 00:48:42,920 et nous avons bar (int x) ou quelque chose. 579 00:48:42,920 --> 00:48:52,310 Ce n'est pas une fonction récursive parfaite, mais la barre return (x - 1). 580 00:48:52,310 --> 00:48:57,620 Alors, évidemment, cela est erronée. Vous devez scénarios de référence et d'autres choses. 581 00:48:57,620 --> 00:49:00,360 Mais l'idée ici est que ce n'est récursive, 582 00:49:00,360 --> 00:49:06,020 ce qui signifie que lorsque la barre principale des appels qu'il va obtenir son stack frame. 583 00:49:09,550 --> 00:49:12,440 Dans ce cadre de pile il va y avoir un petit bloc de mémoire 584 00:49:12,440 --> 00:49:17,490 qui correspond à son argument x. 585 00:49:17,490 --> 00:49:25,840 Et alors disons principale arrive à appeler bar (100); 586 00:49:25,840 --> 00:49:30,050 Donc, x va commencer à 100. 587 00:49:30,050 --> 00:49:35,660 Si le compilateur reconnaît qu'il s'agit d'une fonction récursive, 588 00:49:35,660 --> 00:49:38,540 puis lorsque la barre fait son appel récursif à la barre, 589 00:49:38,540 --> 00:49:45,490 au lieu de faire un nouveau frame de pile, qui est l'endroit où la pile commence à se développer largement, 590 00:49:45,490 --> 00:49:48,220 elle finira par tomber sur le tas, puis vous obtenez une erreur de segmentation 591 00:49:48,220 --> 00:49:51,590 parce que la mémoire commence à entrer en collision. 592 00:49:51,590 --> 00:49:54,830 >> Ainsi, au lieu de faire de son propre cadre de pile, il peut réaliser, 593 00:49:54,830 --> 00:49:59,080 hey, je n'ai jamais vraiment besoin de revenir à ce frame de pile, 594 00:49:59,080 --> 00:50:08,040 de sorte qu'au lieu que je vais remplacer cet argument avec 99 puis démarrez barre de partout. 595 00:50:08,040 --> 00:50:11,810 Et puis, il le fera à nouveau et il atteindra la barre return (x - 1), 596 00:50:11,810 --> 00:50:17,320 et au lieu de faire un nouveau frame de pile, il suffit de remplacer son argument actuel à 98 597 00:50:17,320 --> 00:50:20,740 puis revenir au début de la barre. 598 00:50:23,860 --> 00:50:30,430 Ces opérations, en remplacement de la valeur 1 sur la pile et le saut en arrière au début, 599 00:50:30,430 --> 00:50:32,430 sont assez efficaces. 600 00:50:32,430 --> 00:50:41,500 Ainsi, non seulement est-ce la même utilisation de la mémoire comme une fonction distincte qui est itératif 601 00:50:41,500 --> 00:50:45,390 parce que vous êtes seulement en utilisant 1 frame de pile, mais vous ne souffrez pas les inconvénients 602 00:50:45,390 --> 00:50:47,240 d'avoir à appeler des fonctions. 603 00:50:47,240 --> 00:50:50,240 Appel de fonctions peut être un peu cher, car il a tout à faire cette configuration 604 00:50:50,240 --> 00:50:52,470 et le démontage et tout ce genre de choses. 605 00:50:52,470 --> 00:50:58,160 Donc, cette récursivité terminale est bon. 606 00:50:58,160 --> 00:51:01,170 [L'élève] Pourquoi ne pas créer de nouvelles étapes? 607 00:51:01,170 --> 00:51:02,980 Parce qu'il se rend compte qu'il n'a pas besoin d'. 608 00:51:02,980 --> 00:51:07,800 L'appel à la barre revient tout juste l'appel récursif. 609 00:51:07,800 --> 00:51:12,220 Donc, il n'a pas besoin de faire quoi que ce soit avec la valeur de retour. 610 00:51:12,220 --> 00:51:15,120 Il va juste retourner immédiatement. 611 00:51:15,120 --> 00:51:20,530 Donc, il va tout simplement de remplacer son propre argument et recommencer. 612 00:51:20,530 --> 00:51:25,780 Et aussi, si vous n'avez pas la version récursive terminale, 613 00:51:25,780 --> 00:51:31,460 alors vous obtenez tous ces bars où quand cette barre retourne 614 00:51:31,460 --> 00:51:36,010 il doit retourner sa valeur à celle-ci, alors que la barre revient immédiatement 615 00:51:36,010 --> 00:51:39,620 et il renvoie sa valeur à celle-ci, alors il va juste revenir immédiatement 616 00:51:39,620 --> 00:51:41,350 et renvoie sa valeur à celle-ci. 617 00:51:41,350 --> 00:51:45,350 Ainsi, vous économisez de cette éclater toutes ces choses hors de la pile 618 00:51:45,350 --> 00:51:48,730 puisque la valeur de retour va tout simplement être passé tout le chemin du retour quand même. 619 00:51:48,730 --> 00:51:55,400 Alors pourquoi ne pas remplacer notre argument avec l'argument mis à jour et repartir à zéro? 620 00:51:57,460 --> 00:52:01,150 Si la fonction n'est pas récursive, si vous faites quelque chose comme - 621 00:52:01,150 --> 00:52:07,530 [L'élève] si la barre (x + 1). Ouais >>. 622 00:52:07,530 --> 00:52:11,770 >> Donc, si vous le mettez dans un état, puis vous faites quelque chose avec la valeur de retour. 623 00:52:11,770 --> 00:52:16,260 Ou même si vous venez de faire retour 2 bar * (x - 1). 624 00:52:16,260 --> 00:52:23,560 Alors maintenant, bar (x - 1) doit retourner pour qu'il calculer 2 fois cette valeur, 625 00:52:23,560 --> 00:52:26,140 alors maintenant il ne faut son propre cadre pile séparée, 626 00:52:26,140 --> 00:52:31,180 et maintenant, peu importe comment dur vous essayez, vous allez avoir besoin de - 627 00:52:31,180 --> 00:52:34,410 Ce n'est pas récursive. 628 00:52:34,410 --> 00:52:37,590 [L'élève] Aurais-je essayer d'apporter une récurrence de viser une récursivité terminale - 629 00:52:37,590 --> 00:52:41,450 [Bowden] Dans un monde idéal, mais en CS50 vous n'avez pas à. 630 00:52:43,780 --> 00:52:49,280 Afin d'obtenir la récursivité terminale, en général, vous configurez un argument supplémentaire 631 00:52:49,280 --> 00:52:53,550 où la barre sera x int y en 632 00:52:53,550 --> 00:52:56,990 et y correspond à la chose ultime que vous voulez retourner. 633 00:52:56,990 --> 00:53:03,650 Alors ce que vous allez être de retour bar (x - 1), 2 * y. 634 00:53:03,650 --> 00:53:09,810 Donc, c'est juste un haut niveau de transformer la façon dont vous les choses soient récursive. 635 00:53:09,810 --> 00:53:13,790 Mais l'argument supplémentaire - 636 00:53:13,790 --> 00:53:17,410 Et puis à la fin lorsque vous atteignez votre scénario de base, il vous suffit revenir y 637 00:53:17,410 --> 00:53:22,740 parce que vous avez été accumulé tout le temps la valeur de retour que vous souhaitez. 638 00:53:22,740 --> 00:53:27,280 Vous sorte de l'aviez fait de manière itérative, mais en utilisant des appels récursifs. 639 00:53:32,510 --> 00:53:34,900 Des questions? 640 00:53:34,900 --> 00:53:39,890 [L'élève] Peut-être que sur l'arithmétique des pointeurs, comme lors de l'utilisation de chaînes. >> Bien sûr. 641 00:53:39,890 --> 00:53:43,610 L'arithmétique des pointeurs. 642 00:53:43,610 --> 00:53:48,440 Lorsque vous utilisez des chaînes, il est facile parce que les chaînes sont des étoiles de type char, 643 00:53:48,440 --> 00:53:51,860 les caractères sont toujours et toujours un seul octet, 644 00:53:51,860 --> 00:53:57,540 et si l'arithmétique des pointeurs est équivalent à l'arithmétique régulière quand vous avez affaire à cordes. 645 00:53:57,540 --> 00:54:08,790 Disons simplement char * s = "bonjour". 646 00:54:08,790 --> 00:54:11,430 Nous avons donc un bloc dans la mémoire. 647 00:54:19,490 --> 00:54:22,380 Il a besoin de 6 octets, car il faut toujours le terminateur null. 648 00:54:22,380 --> 00:54:28,620 Et char * s va pointer vers le début de ce tableau. 649 00:54:28,620 --> 00:54:32,830 Ainsi, il souligne s. 650 00:54:32,830 --> 00:54:36,710 Maintenant, c'est fondamentalement la façon dont fonctionne n'importe quel tableau, 651 00:54:36,710 --> 00:54:40,780 qu'il s'agisse d'un retour par malloc ou si elle est sur la pile. 652 00:54:40,780 --> 00:54:47,110 Tout réseau est essentiellement un pointeur vers le début de la matrice, 653 00:54:47,110 --> 00:54:53,640 puis toute opération de tableau, aucune indexation, va tout simplement dans ce tableau un certain décalage. 654 00:54:53,640 --> 00:55:05,360 >> Donc, quand je dis quelque chose comme s [3], ce qui va s et compter 3 caractères po 655 00:55:05,360 --> 00:55:12,490 Donc, s [3], on a 0, 1, 2, 3, si s [3] va se référer à cette l. 656 00:55:12,490 --> 00:55:20,460 [L'élève] Et nous pourrions atteindre la même valeur en faisant s + 3 et étoile entre parenthèses? 657 00:55:20,460 --> 00:55:22,570 Oui. 658 00:55:22,570 --> 00:55:26,010 Ceci est équivalent à * (s + 3); 659 00:55:26,010 --> 00:55:31,240 et c'est toujours et toujours équivalent, peu importe ce que vous faites. 660 00:55:31,240 --> 00:55:34,070 Vous n'avez pas besoin d'utiliser la syntaxe support. 661 00:55:34,070 --> 00:55:37,770 Vous pouvez toujours utiliser le caractère * (s + 3) syntaxe. 662 00:55:37,770 --> 00:55:40,180 Les gens ont tendance à aimer la syntaxe support, cependant. 663 00:55:40,180 --> 00:55:43,860 [L'élève] Ainsi, tous les tableaux sont en fait que des pointeurs. 664 00:55:43,860 --> 00:55:53,630 Il ya une légère différence quand je dis int x [4]; >> [l'élève] Est-ce que créer la mémoire? 665 00:55:53,630 --> 00:56:03,320 [Bowden] Cela va créer 4 ints sur la pile, donc 16 octets globale. 666 00:56:03,320 --> 00:56:05,700 Cela va créer 16 octets sur la pile. 667 00:56:05,700 --> 00:56:09,190 x n'est enregistré nulle part. 668 00:56:09,190 --> 00:56:13,420 Il est juste un symbole faisant référence au début de la chose. 669 00:56:13,420 --> 00:56:17,680 Parce que vous avez déclaré le tableau à l'intérieur de cette fonction, 670 00:56:17,680 --> 00:56:22,340 ce que le compilateur va faire est de simplement remplacer toutes les occurrences de la variable x 671 00:56:22,340 --> 00:56:26,400 avec lequel il est arrivé à choisir de mettre ces 16 octets. 672 00:56:26,400 --> 00:56:30,040 Il ne peut pas le faire avec char * s parce que l'art est un pointeur réel. 673 00:56:30,040 --> 00:56:32,380 Il est gratuit pour ensuite pointer vers d'autres choses. 674 00:56:32,380 --> 00:56:36,140 x est une constante. Vous ne pouvez pas pointer vers un tableau différent. >> [L'élève] D'accord. 675 00:56:36,140 --> 00:56:43,420 Mais cette idée, cette indexation est la même indépendamment du fait que c'est un régime traditionnel 676 00:56:43,420 --> 00:56:48,230 ou si c'est un pointeur vers quelque chose ou si c'est un pointeur vers un tableau malloced. 677 00:56:48,230 --> 00:56:59,770 Et en fait, il est tellement équivalent que c'est aussi la même chose. 678 00:56:59,770 --> 00:57:05,440 En fait, il traduit seulement ce qu'il ya dedans des supports et de ce qui reste des crochets, 679 00:57:05,440 --> 00:57:07,970 les additionne, et déréférence. 680 00:57:07,970 --> 00:57:14,710 Donc, c'est tout aussi valable que * (s + 3) ou s [3]. 681 00:57:16,210 --> 00:57:22,090 [L'élève] Pouvez-vous avoir des pointeurs pointant vers 2-dimensionnels? 682 00:57:22,090 --> 00:57:27,380 >> Il est plus difficile. Traditionnellement, non. 683 00:57:27,380 --> 00:57:34,720 Un tableau à 2 dimensions est juste un tableau à 1 dimension avec une syntaxe pratique 684 00:57:34,720 --> 00:57:54,110 parce que quand je dis int x [3] [3], c'est vraiment juste 1 tableau avec 9 valeurs. 685 00:57:55,500 --> 00:58:03,000 Et donc quand je l'index, le compilateur sait ce que je veux dire. 686 00:58:03,000 --> 00:58:13,090 Si je dis que x [1] [2], il sait que je veux aller à la deuxième rangée, donc ça va sauter les 3 premiers, 687 00:58:13,090 --> 00:58:17,460 et puis il veut que la deuxième chose à cela, alors il va obtenir celui-ci. 688 00:58:17,460 --> 00:58:20,480 Mais il est encore juste un tableau unidimensionnel. 689 00:58:20,480 --> 00:58:23,660 Et si je voulais un pointeur vers ce tableau, 690 00:58:23,660 --> 00:58:29,770 Je dirais int * p = x; 691 00:58:29,770 --> 00:58:33,220 Le type de x est juste - 692 00:58:33,220 --> 00:58:38,280 C'est dur de type dit de x puisque c'est juste un symbole et ce n'est pas une variable réelle, 693 00:58:38,280 --> 00:58:40,140 mais c'est juste un int *. 694 00:58:40,140 --> 00:58:44,840 x est simplement un pointeur vers le début de la présente. >> [L'élève] D'accord. 695 00:58:44,840 --> 00:58:52,560 Et je ne vais pas être en mesure d'accéder à [1] [2]. 696 00:58:52,560 --> 00:58:58,370 Je pense qu'il ya une syntaxe spéciale pour déclarer un pointeur, 697 00:58:58,370 --> 00:59:12,480 quelque chose de ridicule comme int (* p [-. quelque chose d'absolument ridicule, je ne sais même pas. 698 00:59:12,480 --> 00:59:17,090 Mais il ya une syntaxe de déclaration des pointeurs comme des parenthèses et des choses. 699 00:59:17,090 --> 00:59:22,960 Il peut même ne pas vous laisser faire cela. 700 00:59:22,960 --> 00:59:26,640 Je pourrais revenir sur quelque chose qui pourrait me dire la vérité. 701 00:59:26,640 --> 00:59:34,160 Je vais le chercher plus tard, s'il ya une syntaxe pour le point. Mais vous ne le verrez jamais. 702 00:59:34,160 --> 00:59:39,670 Et même la syntaxe est si archaïque que si vous l'utilisez, les gens vont être déroutés. 703 00:59:39,670 --> 00:59:43,540 Les tableaux multidimensionnels sont assez rares car il est. 704 00:59:43,540 --> 00:59:44,630 On est quasiment - 705 00:59:44,630 --> 00:59:48,490 Eh bien, si vous faites les choses matrice ça ne va pas être rare, 706 00:59:48,490 --> 00:59:56,730 mais en C rarement vous allez utiliser des tableaux multidimensionnels. 707 00:59:57,630 --> 01:00:00,470 Ouais. >> [L'élève] Disons que vous avez un tableau très long. 708 01:00:00,470 --> 01:00:03,900 >> Ainsi, dans la mémoire virtuelle, il semble être tout de suite, 709 01:00:03,900 --> 01:00:05,640 comme les éléments de droite à côté de l'autre, 710 01:00:05,640 --> 01:00:08,770 mais dans la mémoire physique, serait-il possible que cela soit divisé? Oui >>. 711 01:00:08,770 --> 01:00:16,860 Comment fonctionne la mémoire virtuelle est-elle sépare juste - 712 01:00:19,220 --> 01:00:24,860 L'unité de répartition est une page, qui tend à être 4 kilo-octets, 713 01:00:24,860 --> 01:00:29,680 et donc quand un processus dit, hey, je veux utiliser cette mémoire, 714 01:00:29,680 --> 01:00:35,970 le système d'exploitation va affecter le 4 kilo-octets pour ce bloc de mémoire peu. 715 01:00:35,970 --> 01:00:39,100 Même si vous utilisez uniquement un seul octet peu l'ensemble du bloc de mémoire, 716 01:00:39,100 --> 01:00:42,850 le système d'exploitation va lui donner les 4 kilo-octets complets. 717 01:00:42,850 --> 01:00:49,410 Alors qu'est-ce que cela signifie est que je pourrais avoir - disons que c'est mon tapis. 718 01:00:49,410 --> 01:00:53,180 Cette pile peut être séparé. Ma pile pourrait être méga-octets et méga-octets. 719 01:00:53,180 --> 01:00:55,020 Ma pile pourrait être énorme. 720 01:00:55,020 --> 01:01:00,220 Mais la pile elle-même doit être divisé en différentes pages, 721 01:01:00,220 --> 01:01:09,010 qui, si on regarde par ici disons que c'est notre mémoire, 722 01:01:09,010 --> 01:01:16,600 si j'ai 2 Go de RAM, il s'agit de 0 adresse réelle comme l'octet zéro de ma RAM, 723 01:01:16,600 --> 01:01:22,210 et cela est de 2 gigaoctets tout le chemin vers le bas ici. 724 01:01:22,210 --> 01:01:27,230 Donc, cette page pourrait correspondre à ce bloc ici. 725 01:01:27,230 --> 01:01:29,400 Cette page pourrait correspondre à ce bloc ici. 726 01:01:29,400 --> 01:01:31,560 Celui-ci pourrait correspondre à celui-ci ici. 727 01:01:31,560 --> 01:01:35,540 Ainsi, le système d'exploitation est libre d'attribuer la mémoire physique 728 01:01:35,540 --> 01:01:39,320 à n'importe quelle page individu arbitraire. 729 01:01:39,320 --> 01:01:46,180 Et cela signifie que si cette frontière se trouve à cheval sur un tableau, 730 01:01:46,180 --> 01:01:50,070 un tableau se trouve être à gauche de la droite et de l'ordre d'une page, 731 01:01:50,070 --> 01:01:54,460 alors que matrice va être divisée en mémoire physique. 732 01:01:54,460 --> 01:01:59,280 Et puis, quand vous quittez le programme, lorsque le processus se termine, 733 01:01:59,280 --> 01:02:05,690 ces correspondances obtenir effacé et il est alors libre d'utiliser ces petits blocs pour d'autres choses. 734 01:02:14,730 --> 01:02:17,410 Plus de questions? 735 01:02:17,410 --> 01:02:19,960 [L'élève] Le pointeur arithmétique. Ah oui >>. 736 01:02:19,960 --> 01:02:28,410 Cordes étaient plus faciles, mais en regardant quelque chose comme ints, 737 01:02:28,410 --> 01:02:35,000 donc retour à int x [4]; 738 01:02:35,000 --> 01:02:41,810 Que ce soit un tableau ou si c'est un pointeur vers un tableau de 4 entiers malloced, 739 01:02:41,810 --> 01:02:47,060 ça va être traités de la même manière. 740 01:02:50,590 --> 01:02:53,340 [L'élève] Ainsi les tableaux sont sur le tas? 741 01:03:01,400 --> 01:03:05,270 [] Bowden tableaux ne sont pas sur le tas. >> [L'élève] Oh. 742 01:03:05,270 --> 01:03:08,320 >> [Bowden] Ce type de tableau a tendance à être sur la pile 743 01:03:08,320 --> 01:03:12,220 sauf si vous le déclare à - ignorant les variables globales. Ne pas utiliser des variables globales. 744 01:03:12,220 --> 01:03:16,280 A l'intérieur d'une fonction que je dis int x [4]; 745 01:03:16,280 --> 01:03:22,520 Cela va créer un bloc de 4-entier sur la pile pour ce tableau. 746 01:03:22,520 --> 01:03:26,960 Mais cette malloc (4 * sizeof (int)); va aller sur le tas. 747 01:03:26,960 --> 01:03:31,870 Mais après ce point je peux utiliser x et p dans à peu près les mêmes moyens, 748 01:03:31,870 --> 01:03:36,140 autres que les exceptions que j'ai dit avant de vous pouvez réaffecter p. 749 01:03:36,140 --> 01:03:40,960 Techniquement, leurs tailles sont un peu différentes, mais c'est complètement hors de propos. 750 01:03:40,960 --> 01:03:43,310 Vous n'avez jamais fait d'utiliser leurs tailles. 751 01:03:48,020 --> 01:03:56,810 Le p je pourrais dire p [3] = 2; ou x [3] = 2; 752 01:03:56,810 --> 01:03:59,680 Vous pouvez les utiliser dans exactement de la même façon. 753 01:03:59,680 --> 01:04:01,570 Alors maintenant, l'arithmétique des pointeurs - Oui. 754 01:04:01,570 --> 01:04:07,390 [L'élève] N'avez-vous pas faire p * si vous avez les parenthèses? 755 01:04:07,390 --> 01:04:11,720 Les supports sont un déréférencement implicite. Ok >>. 756 01:04:11,720 --> 01:04:20,200 En fait, aussi ce que vous dites avec le pouvez-vous obtenir des tableaux multidimensionnels 757 01:04:20,200 --> 01:05:02,650 avec des pointeurs, ce que vous pouvez faire quelque chose comme, disons, int ** pp = malloc (sizeof (int *) * 5); 758 01:05:02,650 --> 01:05:06,900 Je vais écrire tout d'abord. 759 01:05:37,880 --> 01:05:41,020 Je ne voulais pas celui-là. 760 01:05:41,020 --> 01:05:42,550 D'accord. 761 01:05:42,550 --> 01:05:48,910 Ce que j'ai fait ici, c'est - Cela devrait être pp [i]. 762 01:05:48,910 --> 01:05:53,680 Donc pp est un pointeur vers un pointeur. 763 01:05:53,680 --> 01:06:02,420 Vous n'êtes allouer de pp pour pointer vers un tableau de 5 étoiles int. 764 01:06:02,420 --> 01:06:10,950 Ainsi, dans la mémoire que vous avez sur la pile pp 765 01:06:10,950 --> 01:06:20,150 Il va pointer vers un tableau de 5 blocs qui sont tous eux-mêmes des pointeurs. 766 01:06:20,150 --> 01:06:28,210 Et puis quand je malloc ici-bas, je malloc que chacun de ces pointeurs individuels 767 01:06:28,210 --> 01:06:32,080 doit pointer vers un bloc séparé de 4 octets sur le tas. 768 01:06:32,080 --> 01:06:35,870 Donc, ce point à 4 octets. 769 01:06:37,940 --> 01:06:40,660 Et celle-ci évoque de 4 octets différents. 770 01:06:40,660 --> 01:06:43,200 >> Et tous les faire pointer vers leurs propres 4 octets. 771 01:06:43,200 --> 01:06:49,080 Cela me donne une façon de faire les choses multidimensionnelles. 772 01:06:49,080 --> 01:06:58,030 Je pourrais dire pp [3] [4], mais maintenant, ce n'est pas la même chose que les tableaux multidimensionnels 773 01:06:58,030 --> 01:07:05,390 parce que les tableaux multidimensionnels traduit [3] [4] en une seule position dans le tableau x. 774 01:07:05,390 --> 01:07:14,790 Ce p déréférence, accède à la troisième indice, alors que déréférence 775 01:07:14,790 --> 01:07:20,790 et des accès - 4 serait invalide - le second indice. 776 01:07:24,770 --> 01:07:31,430 Considérant que, lorsque nous avons eu l'int x [3] [4] avant comme un tableau multidimensionnel 777 01:07:31,430 --> 01:07:35,740 et lorsque vous double étrier c'est vraiment que le déréférencement d'un seul, 778 01:07:35,740 --> 01:07:40,490 vous suivez un seul pointeur, puis un décalage, 779 01:07:40,490 --> 01:07:42,850 c'est vraiment des références 2D. 780 01:07:42,850 --> 01:07:45,840 Vous suivez 2 pointeurs distincts. 781 01:07:45,840 --> 01:07:50,420 Ainsi, cela permet aussi la technique que vous ayez des tableaux multidimensionnels 782 01:07:50,420 --> 01:07:53,550 où chaque ensemble individuel est de différentes tailles. 783 01:07:53,550 --> 01:07:58,000 Je pense donc que déchiquetées tableaux multidimensionnels est ce qu'il a appelé 784 01:07:58,000 --> 01:08:01,870 depuis vraiment la première chose pourrait pointer vers quelque chose qui a 10 éléments, 785 01:08:01,870 --> 01:08:05,540 la deuxième chose pourrait pointer vers quelque chose qui a 100 éléments. 786 01:08:05,540 --> 01:08:10,790 [L'élève] Y at-il une limite au nombre de pointeurs, vous pouvez avoir 787 01:08:10,790 --> 01:08:14,290 pointant vers d'autres pointeurs? Non >> 788 01:08:14,290 --> 01:08:17,010 Vous pouvez avoir int ***** p. 789 01:08:18,050 --> 01:08:23,760 Retour à l'arithmétique de pointeur - >> [l'élève] Oh. Ouais >>. 790 01:08:23,760 --> 01:08:35,649 [L'élève] Si j'ai int *** p puis-je faire un déréférencement et je dis * p est égal à cette valeur, 791 01:08:35,649 --> 01:08:39,560 est-ce que va faire 1 niveau de déréférencement? Oui >>. 792 01:08:39,560 --> 01:08:43,340 Donc, si je veux accéder à la chose que le pointeur de la dernière pointe du doigt - 793 01:08:43,340 --> 01:08:46,210 Ensuite, vous faites p ***. Ok >>. 794 01:08:46,210 --> 01:08:54,080 Donc, ce n'est p points à 1 bloc, pointe vers un autre bloc, pointe vers un autre bloc. 795 01:08:54,080 --> 01:09:02,010 Ensuite, si vous le faites * p = autre chose, alors vous changez ce 796 01:09:02,010 --> 01:09:13,640 maintenant pointer vers un autre bloc. Ok >>. 797 01:09:13,640 --> 01:09:17,649 >> [Bowden] Et si ceux-ci ont été malloced, alors vous avez maintenant une fuite de mémoire 798 01:09:17,649 --> 01:09:20,430 à moins que vous arrive d'avoir des références différentes de ces 799 01:09:20,430 --> 01:09:25,270 puisque vous ne pouvez pas revenir à ceux-là que vous venez jeté. 800 01:09:25,270 --> 01:09:29,550 L'arithmétique des pointeurs. 801 01:09:29,550 --> 01:09:36,310 int x [4]; va allouer un tableau de 4 entiers 802 01:09:36,310 --> 01:09:40,670 où x va pointer vers le début de la matrice. 803 01:09:40,670 --> 01:09:50,420 Donc, quand je dis quelque chose comme x [1], je veux qu'il signifie aller à la deuxième entier dans le tableau, 804 01:09:50,420 --> 01:09:53,319 qui serait celui-ci. 805 01:09:53,319 --> 01:10:04,190 Mais vraiment, c'est 4 octets dans le tableau puisque cet entier occupe 4 octets. 806 01:10:04,190 --> 01:10:08,470 Ainsi, un décalage de 1 signifie réellement un décalage de 1 807 01:10:08,470 --> 01:10:12,030 fois la taille de quel que soit le type du tableau est. 808 01:10:12,030 --> 01:10:17,170 Il s'agit d'un tableau d'entiers, de sorte qu'il sait faire 1 fois la taille de int quand il veut compenser. 809 01:10:17,170 --> 01:10:25,260 L'autre syntaxe. Rappelez-vous que ceci est équivalent à * (x + 1); 810 01:10:25,260 --> 01:10:35,250 Quand je dis pointeur + 1, ce qui revient est l'adresse que le pointeur est le stockage 811 01:10:35,250 --> 01:10:40,360 ainsi que 1 fois la taille du type de l'aiguille. 812 01:10:40,360 --> 01:10:59,510 Donc, si x = OX100, alors x + 1 = ox104. 813 01:10:59,510 --> 01:11:19,750 Et vous pouvez abuser de cela et dire quelque chose comme char * c = (char *) x; 814 01:11:19,750 --> 01:11:23,050 et maintenant c est va être la même adresse que x. 815 01:11:23,050 --> 01:11:26,040 c va être égal à OX100, 816 01:11:26,040 --> 01:11:31,490 mais c + 1 sera égal à ox101 817 01:11:31,490 --> 01:11:38,030 depuis l'arithmétique des pointeurs dépend du type du pointeur que vous ajoutez à. 818 01:11:38,030 --> 01:11:45,390 Donc c + 1, il regarde c, c'est un pointeur de char, il va ajouter 1 fois la taille du char, 819 01:11:45,390 --> 01:11:48,110 qui va toujours être de 1, de sorte que vous obtenez 101, 820 01:11:48,110 --> 01:11:54,890 alors que si je fais x, qui est aussi toujours 100, x + 1 va être 104. 821 01:11:56,660 --> 01:12:06,340 [L'élève] Pouvez-vous utiliser c + + afin de faire avancer le pointeur de 1? 822 01:12:06,340 --> 01:12:09,810 Oui, vous le pouvez. 823 01:12:09,810 --> 01:12:16,180 Vous ne pouvez pas faire cela avec x car x n'est qu'un symbole, c'est une constante, vous ne pouvez pas changer x. 824 01:12:16,180 --> 01:12:22,610 >> Mais c arrive d'être juste un pointeur, donc c + + est parfaitement valable et il sera incrémenté de 1. 825 01:12:22,610 --> 01:12:32,440 Si c était juste un int *, alors c + + serait de 104. 826 01:12:32,440 --> 01:12:41,250 + + Pointeur arithmétique fait juste que c + 1 aurait fait l'arithmétique des pointeurs. 827 01:12:43,000 --> 01:12:48,870 C'est en fait la façon dont beaucoup de choses comme le tri par fusion - 828 01:12:49,670 --> 01:12:55,710 Au lieu de créer des copies de choses, vous pouvez passer à la place - 829 01:12:55,710 --> 01:13:02,400 Comme si je voulais faire passer cette moitié de l'ensemble - nous allons effacer une partie de cela. 830 01:13:04,770 --> 01:13:10,520 Disons que je voulais faire passer ce côté de la baie dans une fonction. 831 01:13:10,520 --> 01:13:12,700 Que ferais-je passer à cette fonction? 832 01:13:12,700 --> 01:13:17,050 Si je réussis x, je passe cette adresse. 833 01:13:17,050 --> 01:13:23,780 Mais je tiens à transmettre cette adresse particulière. Alors, que dois-je passer? 834 01:13:23,780 --> 01:13:26,590 [L'élève] Pointeur + 2? 835 01:13:26,590 --> 01:13:29,350 [Bowden] Donc x + 2. Oui. 836 01:13:29,350 --> 01:13:31,620 Cela va être cette adresse. 837 01:13:31,620 --> 01:13:42,810 Vous serez également très souvent le voir comme x [2], puis l'adresse de cela. 838 01:13:42,810 --> 01:13:47,850 Alors vous avez besoin de prendre l'adresse de celui-ci parce que le support est un déréférencement implicite. 839 01:13:47,850 --> 01:13:53,250 x [2] correspond à la valeur qui se trouve dans cette zone, et que vous voulez l'adresse de cette boîte, 840 01:13:53,250 --> 01:13:56,850 ce que vous dites et x [2]. 841 01:13:56,850 --> 01:14:02,880 C'est comme ça que quelque chose sorte de fusion où vous voulez passer la moitié de la liste pour quelque chose 842 01:14:02,880 --> 01:14:08,790 vous avez vraiment passer et x [2], et maintenant aussi loin que l'appel récursif est concerné, 843 01:14:08,790 --> 01:14:12,510 mon nouveau tableau commence là. 844 01:14:12,510 --> 01:14:15,130 Questions de dernière minute. 845 01:14:15,130 --> 01:14:20,050 [L'élève] Si nous ne mettons pas l'esperluette ou un - qu'est-ce que s'appelle? >> Star? 846 01:14:20,050 --> 01:14:23,200 [L'élève] Star. Techniquement >>, opérateur de déréférencement, mais - >> [l'élève] déréférencement. 847 01:14:23,200 --> 01:14:29,310 >> Si nous ne mettons pas une étoile ou une esperluette, ce qui se passe si je viens de dire y = x et x est un pointeur? 848 01:14:29,310 --> 01:14:34,620 Quel est le type de y? >> [L'élève] Je vais juste dire que c'est le pointeur 2. 849 01:14:34,620 --> 01:14:38,270 Donc, si vous venez de dire y = x, x et le point maintenant y à la même chose. >> [L'élève] Point à la même chose. 850 01:14:38,270 --> 01:14:45,180 Et si x est un pointeur int? >> Il se plaindre parce que vous ne pouvez pas affecter des pointeurs. 851 01:14:45,180 --> 01:14:46,540 [L'élève] D'accord. 852 01:14:46,540 --> 01:14:51,860 Rappelez-vous que les pointeurs, même si nous les attirer comme des flèches, 853 01:14:51,860 --> 01:15:02,010 vraiment tout magasin, ils - int * x - x est vraiment tout ce stockage est quelque chose comme OX100, 854 01:15:02,010 --> 01:15:06,490 ce qui nous arrive à représenter comme pointant vers le bloc stocké à 100. 855 01:15:06,490 --> 01:15:19,660 Donc, quand je dis int * y = x, je suis simplement copier OX100 en y, 856 01:15:19,660 --> 01:15:24,630 que nous allons juste y représenter, en soulignant particulièrement à OX100. 857 01:15:24,630 --> 01:15:39,810 Et si je dis int i = (int) x, puis i va stocker tout ce que la valeur de OX100 est 858 01:15:39,810 --> 01:15:45,100 à l'intérieur de celui-ci, mais maintenant ça va être interprété comme un entier au lieu d'un pointeur. 859 01:15:45,100 --> 01:15:49,310 Mais vous devez le casting ou bien il va se plaindre. 860 01:15:49,310 --> 01:15:53,300 [L'élève] Alors voulez-vous dire de jeter - 861 01:15:53,300 --> 01:16:00,290 Est-ce que ça va être coulée int int x ou de y casting? 862 01:16:00,290 --> 01:16:03,700 [Bowden] Quoi? 863 01:16:03,700 --> 01:16:07,690 [L'élève] D'accord. Après ces parenthèses est qu'il va y avoir un x ou ay il? 864 01:16:07,690 --> 01:16:11,500 >> [Bowden] Soit. x et y sont équivalents. >> [L'élève] D'accord. 865 01:16:11,500 --> 01:16:14,390 Parce qu'ils sont les deux pointeurs. Ouais >>. 866 01:16:14,390 --> 01:16:21,050 [L'élève] Donc, il serait de stocker les 100 hexadécimal sous forme entière? >> [Bowden] Ouais. 867 01:16:21,050 --> 01:16:23,620 Mais ce n'est pas la valeur de ce qu'il désigne. 868 01:16:23,620 --> 01:16:29,940 [Bowden] Ouais. >> [L'élève] Il suffit donc de l'adresse sous forme de nombre entier. D'accord. 869 01:16:29,940 --> 01:16:34,720 [Bowden] Si vous vouliez, pour une raison bizarre, 870 01:16:34,720 --> 01:16:38,900 vous pourriez traiter exclusivement avec des pointeurs et ne jamais traiter avec des nombres entiers 871 01:16:38,900 --> 01:16:49,240 et juste comme int * x = 0. 872 01:16:49,240 --> 01:16:53,000 Ensuite, vous allez être vraiment confus une fois l'arithmétique des pointeurs commence à se produire. 873 01:16:53,000 --> 01:16:56,570 Alors que les chiffres qu'ils contiennent n'ont pas de sens. 874 01:16:56,570 --> 01:16:58,940 C'est juste la façon dont vous vous retrouvez à les interpréter. 875 01:16:58,940 --> 01:17:02,920 Je suis donc libre de copier OX100 d'un * int en int, 876 01:17:02,920 --> 01:17:07,790 et je suis libre de céder - vous êtes probablement va se faire engueuler pour ne pas couler - 877 01:17:07,790 --> 01:17:18,160 Je suis libre de céder quelque chose comme (int *) ox1234 dans ce * int arbitraire. 878 01:17:18,160 --> 01:17:25,480 Donc ox123 est tout aussi valable une adresse mémoire est aussi et y. 879 01:17:25,480 --> 01:17:32,060 Et y arrive de retourner quelque chose qui est à peu près ox123. 880 01:17:32,060 --> 01:17:35,430 [L'élève] Serait-ce une façon vraiment cool d'aller du format hexadécimal au format décimal, 881 01:17:35,430 --> 01:17:39,230 comme si vous avez un pointeur et vous le lancez comme un int? 882 01:17:39,230 --> 01:17:44,860 [Bowden] Vous pouvez vraiment juste imprimer en utilisant comme printf. 883 01:17:44,860 --> 01:17:50,300 Disons que j'ai int y = 100. 884 01:17:50,300 --> 01:18:02,700 Donc printf (% d \ n - que vous devriez déjà savoir - imprimer ce que un entier x%,. 885 01:18:02,700 --> 01:18:05,190 Nous allons l'imprimer en hexadécimal. 886 01:18:05,190 --> 01:18:10,760 Ainsi, un pointeur n'est pas stocké en hexadécimal, 887 01:18:10,760 --> 01:18:12,960 et un entier n'est pas stockée sous forme décimale. 888 01:18:12,960 --> 01:18:14,700 Tout est stocké sous forme binaire. 889 01:18:14,700 --> 01:18:17,950 C'est juste que nous avons tendance à montrer des pointeurs sous forme hexadécimale 890 01:18:17,950 --> 01:18:23,260 parce que nous pensons des choses dans ces blocs de 4 octets, 891 01:18:23,260 --> 01:18:25,390 et les adresses mémoire ont tendance à être familier. 892 01:18:25,390 --> 01:18:28,890 Nous sommes comme si elle commence par bf, puis il arrive à être sur la pile. 893 01:18:28,890 --> 01:18:35,560 Donc, c'est juste notre interprétation des pointeurs sous forme hexadécimale. 894 01:18:35,560 --> 01:18:39,200 D'accord. Toutes les dernières questions? 895 01:18:39,200 --> 01:18:41,700 >> Je serai ici pour un peu plus tard si vous avez quoi que ce soit d'autre. 896 01:18:41,700 --> 01:18:46,070 Et c'est la fin de l'. 897 01:18:46,070 --> 01:18:48,360 >> [L'élève] Yay! [Applaudissements] 898 01:18:51,440 --> 01:18:53,000 >> [CS50.TV]