1 00:00:00,000 --> 00:00:11,242 >> [音乐播放] 2 00:00:11,242 --> 00:00:16,630 >> DAVID J.马兰:好吧,这是CS50 这是5周开始。 3 00:00:16,630 --> 00:00:21,480 所以今天,坐垫底下, 你不会找到任何东西。 4 00:00:21,480 --> 00:00:24,790 但最重要的,你应该找到这些, 我们欣赏的一点小小的心意 5 00:00:24,790 --> 00:00:26,970 你把所有的工作 进入15游戏。 6 00:00:26,970 --> 00:00:30,290 只要简单地除去小圈上 底部开始打 7 00:00:30,290 --> 00:00:31,680 其余类。 8 00:00:31,680 --> 00:00:38,930 >> 所以记得或知道这个问题集 四,本周末出去, 9 00:00:38,930 --> 00:00:40,340 涉及编写另一场比赛。 10 00:00:40,340 --> 00:00:43,740 但是,这一次,它涉及到使用 实际的图形用户界面,而不是一个 11 00:00:43,740 --> 00:00:46,310 文本界面,如 十五的游戏。 12 00:00:46,310 --> 00:00:50,210 而本场比赛在于你前面, 如果你还没有见过这下, 13 00:00:50,210 --> 00:00:52,310 看起来有点像这样的东西。 14 00:00:52,310 --> 00:00:55,170 我要进入​​我的终端 在GDB窗口。 15 00:00:55,170 --> 00:00:58,600 而且我要继续前进并运行 员工的解决方案,您可以访问 16 00:00:58,600 --> 00:01:01,010 运行update 50后,像往常一样。 17 00:01:01,010 --> 00:01:04,090 >> 不过,我打算把它放入少许 秘密模式,一点点的复活节彩蛋, 18 00:01:04,090 --> 00:01:08,480 所谓的上帝模式, 让上帝argv1。 19 00:01:08,480 --> 00:01:12,920 我要按照我自己的方向, 在我自己的运行 20 00:01:12,920 --> 00:01:14,220 问题设置目录。 21 00:01:14,220 --> 00:01:19,190 所以,现在你看到一个完整的版本 的突围的比赛。 22 00:01:19,190 --> 00:01:21,090 其实,这是没有手模式。 23 00:01:21,090 --> 00:01:24,850 因此,它实际上是 - 24 00:01:24,850 --> 00:01:26,470 叫绝尽管你可能会对 - 25 00:01:26,470 --> 00:01:30,850 很容易实现上帝模式 突围,不像十五的游戏, 26 00:01:30,850 --> 00:01:33,590 一些你可能已经解决 黑客版。 27 00:01:33,590 --> 00:01:37,890 >> 在突围中,只要在上帝 模式简单地做什么, 28 00:01:37,890 --> 00:01:41,220 直观地与桨? 29 00:01:41,220 --> 00:01:45,630 只要使它等于不管 水平位置的球。 30 00:01:45,630 --> 00:01:49,220 所以只要你做到这一点步调一致 ,球移动这个游戏会 31 00:01:49,220 --> 00:01:53,100 永远,永远,永远错过了球 你会每次都赢。 32 00:01:53,100 --> 00:01:55,430 >> 但在本周的黑客版 有以上只是上帝模式。 33 00:01:55,430 --> 00:01:56,720 有一些其他功能。 34 00:01:56,720 --> 00:01:58,140 其中,激光器。 35 00:01:58,140 --> 00:02:01,070 所以,如果你真的不耐烦 可以击落砖开始 36 00:02:01,070 --> 00:02:02,120 和其他几个人。 37 00:02:02,120 --> 00:02:04,560 而对于那些你谁想要 校准标准与黑客 38 00:02:04,560 --> 00:02:08,750 版,我可以看到,本周的 黑客版故意是一个 39 00:02:08,750 --> 00:02:12,830 更可行一点,也就是说,不是神 模式是与游戏的十五。 40 00:02:12,830 --> 00:02:15,300 >> 所以,如果你正在寻找一个舒展和 你正在寻找一些额外的乐趣 41 00:02:15,300 --> 00:02:18,400 如果感兴趣的功能做潜水。 42 00:02:18,400 --> 00:02:21,280 现在更实际,让我点 一件事。 43 00:02:21,280 --> 00:02:24,780 GDB,有些人可能还没有 亲自感动,这是很好的。 44 00:02:24,780 --> 00:02:28,530 但现在是真正的时间来习惯 这和舒适的使用这个工具 45 00:02:28,530 --> 00:02:31,510 因为它会让你的生活 更容易,真正做到。 46 00:02:31,510 --> 00:02:34,900 >> 每罗布GDB的一对夫妇的讲座 数周前,记得 47 00:02:34,900 --> 00:02:36,810 ,GDB调试器。 48 00:02:36,810 --> 00:02:41,230 这是一个工具,可以让你运行你的 程序,但运行它一步一步,线 49 00:02:41,230 --> 00:02:45,680 行,让你可以闲逛, 所以,你看到的事情发生,所以 50 00:02:45,680 --> 00:02:47,310 您可以打印出来 变量的值。 51 00:02:47,310 --> 00:02:50,580 总之,它给了你这么多 功率比printDef。 52 00:02:50,580 --> 00:02:52,900 >> 诚然,现在的界面 是相当神秘。 53 00:02:52,900 --> 00:02:55,180 黑色和白色的文本界面 在大多数情况下。 54 00:02:55,180 --> 00:02:57,400 命令有些艰难 记得在第一。 55 00:02:57,400 --> 00:03:01,230 但是,即使它可能需要你的一半 一个小时,一个小时,把前期 56 00:03:01,230 --> 00:03:02,940 投资的时间把它,相信我。 57 00:03:02,940 --> 00:03:06,440 当然学期的结束,这将节省 你一个数量级以上 58 00:03:06,440 --> 00:03:07,600 时间比。 59 00:03:07,600 --> 00:03:09,200 >> 所以早在本周长驱直入 60 00:03:09,200 --> 00:03:13,200 在突围方面,知道你 能做到这一点,只要你有 61 00:03:13,200 --> 00:03:18,230 分配代码或您自己的代码 在建您的Pst4目录。 62 00:03:18,230 --> 00:03:21,680 要知道,你可以运行gdb。/突破。 63 00:03:21,680 --> 00:03:23,490 >> 这将开辟 这样的窗口。 64 00:03:23,490 --> 00:03:25,530 让我给自己更多 一个终端窗口。 65 00:03:25,530 --> 00:03:27,770 然后呢,我要继续前进 做的,它的不只是运行它。 66 00:03:27,770 --> 00:03:30,690 我要首先设置了一个破发点 召回,它允许你暂停 67 00:03:30,690 --> 00:03:32,500 在一个特定的地方执行。 68 00:03:32,500 --> 00:03:35,750 >> 只是为了简单起见,我要去 只需键入打破行一 69 00:03:35,750 --> 00:03:37,000 头号。 70 00:03:37,000 --> 00:03:40,080 71 00:03:40,080 --> 00:03:43,250 实际上让我重新打开此窗口 因为它才获得了 72 00:03:43,250 --> 00:03:45,700 有一点小。 73 00:03:45,700 --> 00:03:53,270 所以现在,我要在这里做什么 如果我打开终端窗口。 74 00:03:53,270 --> 00:03:53,910 来吧,我们去那里。 75 00:03:53,910 --> 00:03:59,850 >> 所以,现在如果我回去到Dropbox,Pst4 运行gdb。/突破进入,请注意 76 00:03:59,850 --> 00:04:02,600 我要打破一个设置 一个破发点,线一条。 77 00:04:02,600 --> 00:04:04,840 现在我要去 运行前方和类型。 78 00:04:04,840 --> 00:04:07,370 而当我这样做,注意什么 似乎发生。 79 00:04:07,370 --> 00:04:08,120 >> 有没有弹出。 80 00:04:08,120 --> 00:04:09,790 有没有图形 用户界面。 81 00:04:09,790 --> 00:04:13,340 但是,这是可以理解的,因为我 字面上线在我的计划之一。 82 00:04:13,340 --> 00:04:17,110 注意到我快进, 特别是现在到62,因为所有的 83 00:04:17,110 --> 00:04:20,600 在这个文件的顶部的东西是 像注释和常量和 84 00:04:20,600 --> 00:04:22,460 现在的无趣的东西。 85 00:04:22,460 --> 00:04:25,840 >> 所以我现在的主要内, 看起来,在第62行。 86 00:04:25,840 --> 00:04:27,960 而这仅仅是分配 代码,召回。 87 00:04:27,960 --> 00:04:33,810 如果我开这件事,同样, 进入我的下拉框成Pst4目录, 88 00:04:33,810 --> 00:04:35,450 到breakout.c。 89 00:04:35,450 --> 00:04:40,670 如果我向下滚动下来,下来, 并让我继续前进,打开 90 00:04:40,670 --> 00:04:44,990 我的行号。 91 00:04:44,990 --> 00:04:50,300 >> 我会看到什么,如果我向下滚动到 62号线,是完全行 92 00:04:50,300 --> 00:04:50,910 我们已经暂停。 93 00:04:50,910 --> 00:04:53,720 因此,这条线在这里,62岁, 我们是。 94 00:04:53,720 --> 00:04:57,470 所以,现在在GDB,如果我先走,然后键入 现在下,进入它要 95 00:04:57,470 --> 00:04:58,450 执行这条线。 96 00:04:58,450 --> 00:05:00,610 瞧,我们有 所谓的克窗口。 97 00:05:00,610 --> 00:05:02,800 如果什么GWindow不熟悉 ,不用担心。 98 00:05:02,800 --> 00:05:05,740 该规范将为您介绍它,因为 以及大量的演练视频 99 00:05:05,740 --> 00:05:06,830 嵌入在规范中。 100 00:05:06,830 --> 00:05:08,610 >> 但现在让我们做一个 更有趣一点。 101 00:05:08,610 --> 00:05:10,960 让我移动这个窗口 一边一点点。 102 00:05:10,960 --> 00:05:13,480 让我一点窗户 更大,所以我可以看到更多。 103 00:05:13,480 --> 00:05:16,140 >> 现在让我继续 和再下一步要做。 104 00:05:16,140 --> 00:05:17,550 而且有我的砖。 105 00:05:17,550 --> 00:05:20,490 如果我再接下来键入 现在我看到球。 106 00:05:20,490 --> 00:05:23,520 如果我再接下来键入 现在我明白了桨。 107 00:05:23,520 --> 00:05:26,690 >> 幸运的是,这gedit中不 通过展示我真正合作 108 00:05:26,690 --> 00:05:27,660 我想要的一切。 109 00:05:27,660 --> 00:05:30,820 但现在如果我再下一步做, 再接下来,我只是 110 00:05:30,820 --> 00:05:32,260 声明一些变量。 111 00:05:32,260 --> 00:05:34,750 我可以打印任何一个 这些家伙。 112 00:05:34,750 --> 00:05:37,170 打印砖,版画的生活。 113 00:05:37,170 --> 00:05:39,910 >> 现在如果我继续做 接下来,请注意,我会 114 00:05:39,910 --> 00:05:40,870 里面的这个循环。 115 00:05:40,870 --> 00:05:43,380 但是代码执行 正是因为我的期望。 116 00:05:43,380 --> 00:05:45,810 所以,当我打这个功能,等待 按一下,它会做 117 00:05:45,810 --> 00:05:46,830 它的字面。 118 00:05:46,830 --> 00:05:48,870 所以,我似乎已经失去了控制 在节目。 119 00:05:48,870 --> 00:05:50,480 >> GDB是不给我另一个提示。 120 00:05:50,480 --> 00:05:51,500 但不用担心。 121 00:05:51,500 --> 00:05:53,720 转到我的游戏,点击的地方。 122 00:05:53,720 --> 00:05:56,270 >> 瞧,现在进行到第86行。 123 00:05:56,270 --> 00:05:59,460 再次,它是无价的,最终, 调试问题。 124 00:05:59,460 --> 00:06:03,050 因为你可以从字面上步骤通过 你的代码,打印多东西出来, 125 00:06:03,050 --> 00:06:03,640 多少,等等。 126 00:06:03,640 --> 00:06:07,210 但现在,这些工具本身 应该让你很远。 127 00:06:07,210 --> 00:06:10,050 >> 因此,我们,当然,考虑看看 现在显卡,一下子。 128 00:06:10,050 --> 00:06:12,350 现在我们的世界变得有点 更有趣。 129 00:06:12,350 --> 00:06:15,680 你知道,或许,从一些 我们这些在线视频 130 00:06:15,680 --> 00:06:18,280 短裤,你已经看 习题集的一部分。 131 00:06:18,280 --> 00:06:20,460 >> 他们已经出手,故意 以白色背景。 132 00:06:20,460 --> 00:06:23,380 他们中的一些教学 图纸上的某些文本研究员 133 00:06:23,380 --> 00:06:25,490 屏幕覆盖 上侧。 134 00:06:25,490 --> 00:06:27,760 不过,当然,这还不是全部, 在现实世界中有趣。 135 00:06:27,760 --> 00:06:30,520 这仅仅是一个与报告厅 白色的大屏幕和背景。 136 00:06:30,520 --> 00:06:33,330 我们惊人的生产队排序 让一切看上去很美 137 00:06:33,330 --> 00:06:36,620 通过裁剪后的事实 或覆盖任何东西 138 00:06:36,620 --> 00:06:37,840 我们做什么或不想要的。 139 00:06:37,840 --> 00:06:41,560 >> 现在只是为了激励这个星期, 真的,你可以去,最终, 140 00:06:41,560 --> 00:06:42,560 计算机科学。 141 00:06:42,560 --> 00:06:44,260 问题后,不只是设置了四个。 142 00:06:44,260 --> 00:06:48,240 但之后其他课程或整个 课程是惊人的,你可以 143 00:06:48,240 --> 00:06:51,090 这几天而言, 尤其是在图形。 144 00:06:51,090 --> 00:06:53,440 >> 你们当中有些人可能已经看到了这 网上四处流淌。 145 00:06:53,440 --> 00:06:56,240 但我想我会告诉你,只是一个 两分钟,一窥究竟 146 00:06:56,240 --> 00:07:01,890 计算机技术和CGI 计算机图形可以做这些天 147 00:07:01,890 --> 00:07:04,510 熟悉的歌曲 也许电影。 148 00:07:04,510 --> 00:07:05,760 >> [MUSIC - LANA DEL射线, “年轻和美丽] 149 00:07:05,760 --> 00:10:50,270 150 00:10:50,270 --> 00:10:52,470 >> 扬声器1:这只是一点点 惊人的,也许,只是如何 151 00:10:52,470 --> 00:10:52,857 无处不在 - 152 00:10:52,857 --> 00:10:57,040 >> [掌声] 153 00:10:57,040 --> 00:10:59,230 >> 扬声器1:我刚下载了它。 154 00:10:59,230 --> 00:11:02,920 但它真的很神奇,我想,只要 无所不在的软件和代码, 155 00:11:02,920 --> 00:11:04,230 真的是这样的工具。 156 00:11:04,230 --> 00:11:07,685 所以这是一个品味的方向 在其中,你可以走了。 157 00:11:07,685 --> 00:11:10,620 哦,没有更多的电器。 158 00:11:10,620 --> 00:11:14,640 嗯,这实际上是悲惨的时机 点我只是试图让。 159 00:11:14,640 --> 00:11:18,670 >> 好吧,让我们推出 再次融合。 160 00:11:18,670 --> 00:11:20,800 稍后提醒我。 161 00:11:20,800 --> 00:11:24,190 没事了,你应该有一个 顺便说一句,如果你确实得到了电子邮件 162 00:11:24,190 --> 00:11:25,460 类似的通知。 163 00:11:25,460 --> 00:11:29,940 好吧,所以记得,上周 我们开始剥离回 164 00:11:29,940 --> 00:11:31,380 后来被称为串。 165 00:11:31,380 --> 00:11:34,700 >> 字符串回忆起一个数据类型 宣派CS50库。 166 00:11:34,700 --> 00:11:37,740 它的一部分训练轮 现在将开始起飞。 167 00:11:37,740 --> 00:11:41,280 这是一个有用的概念,早期。 168 00:11:41,280 --> 00:11:43,750 但现在它要得到更多 有趣和更强大 169 00:11:43,750 --> 00:11:48,330 实际看到的引擎盖下, 一个字符串就是什么,我们说的吗? 170 00:11:48,330 --> 00:11:50,500 >> 是啊,所以这是一个所谓的char *。 171 00:11:50,500 --> 00:11:53,860 *表示有 涉及某种形式的地址。 172 00:11:53,860 --> 00:11:58,690 因此,当你说你的char *仅仅意味着 一个变量,其数据类型是一个 173 00:11:58,690 --> 00:11:59,290 指针现在。 174 00:11:59,290 --> 00:12:01,770 事实上,有星级 只是意味着你声明 175 00:12:01,770 --> 00:12:03,020 所谓的指针。 176 00:12:03,020 --> 00:12:06,220 该指针是怎么回事显然 存储的地址, 177 00:12:06,220 --> 00:12:07,810 当然,一个字符。 178 00:12:07,810 --> 00:12:08,960 >> 现在为什么不这样做有意义吗? 179 00:12:08,960 --> 00:12:11,200 那么,什么是一个字符串 引擎盖下? 180 00:12:11,200 --> 00:12:15,130 那么,未来一段时间,我们一直在说 引擎盖下是一个字符串 181 00:12:15,130 --> 00:12:18,460 只是H-E-L-L-ø,例如。 182 00:12:18,460 --> 00:12:21,585 >> 但我们已经谈到这是 即,本质上,一个数组。 183 00:12:21,585 --> 00:12:25,410 阵列,然后看起来有点 类似这样的,与这些 184 00:12:25,410 --> 00:12:26,460 咬了一口。 185 00:12:26,460 --> 00:12:28,710 然后我们说,有 一些特别的东西,回到这里, 186 00:12:28,710 --> 00:12:31,270 反斜线0或null终止。 187 00:12:31,270 --> 00:12:35,230 >> 所以这一切的时候,在这里 一个字符串。 188 00:12:35,230 --> 00:12:38,320 不过说真的,一串串 实际上是一个地址。 189 00:12:38,320 --> 00:12:43,210 和地址,如我们所看到的,往往是 按照惯例用0x前缀。 190 00:12:43,210 --> 00:12:44,540 0X表示什么? 191 00:12:44,540 --> 00:12:45,970 有谁知道? 192 00:12:45,970 --> 00:12:47,320 >> 因此,它只是表示十六进制。 193 00:12:47,320 --> 00:12:52,360 所以,你可能还记得,实际上,从PST 1,我相信,一个热身 194 00:12:52,360 --> 00:12:55,740 问题居然问 十六进制表示法中除了 195 00:12:55,740 --> 00:12:57,100 二进制和十进制。 196 00:12:57,100 --> 00:13:00,460 这里的动机是 与十六进制你有16 197 00:13:00,460 --> 00:13:01,770 数字在您的处置。 198 00:13:01,770 --> 00:13:07,900 0,1,2,3,4,5,6,7,8,9,其次 由A,B,C,D,E,F。 199 00:13:07,900 --> 00:13:10,430 >> 如果算上所有这些向上, 你得到了总共16个。 200 00:13:10,430 --> 00:13:13,200 因此,这是在对比 小数,其中有10个 201 00:13:13,200 --> 00:13:14,690 数字0到9。 202 00:13:14,690 --> 00:13:17,750 它的对比度与二进制 我们只是0和1。 203 00:13:17,750 --> 00:13:21,450 >> 但在年底的一天,你可以 表示相同的数字,但 204 00:13:21,450 --> 00:13:22,500 有所不同。 205 00:13:22,500 --> 00:13:25,840 和十六进制是常见的,因为 事实证明 - 我们将看到这一点 206 00:13:25,840 --> 00:13:28,790 后面的课程 - 即使当我们得到 web编程的背景下, 207 00:13:28,790 --> 00:13:32,100 HTML和颜色代码, 十六进制是好的。 208 00:13:32,100 --> 00:13:36,390 因为每一个数字,事实证明, 代表完美四位。 209 00:13:36,390 --> 00:13:39,280 因此,它只是一种很好的线 因为我们最终会看到。 210 00:13:39,280 --> 00:13:44,720 所以这可能是Ox123或东西 这样,表示地址123 211 00:13:44,720 --> 00:13:47,050 里面有我的地方 计算机的内存。 212 00:13:47,050 --> 00:13:50,600 >> 不过,当然,出现了一些问题 因为这一基本 213 00:13:50,600 --> 00:13:51,520 实现。 214 00:13:51,520 --> 00:13:55,930 记得我把刺在 实现这样的功能 - 215 00:13:55,930 --> 00:14:00,260 比较破折号0 C点上周 即使它看起来就像是 216 00:14:00,260 --> 00:14:04,270 没错,它根本不比较 两个字符串正确。 217 00:14:04,270 --> 00:14:07,470 >> 我扔掉的主,我已经抛出 远的意见只是集中在上 218 00:14:07,470 --> 00:14:08,970 代码的兴趣。 219 00:14:08,970 --> 00:14:10,660 ,它是红色的,因为它是越野车。 220 00:14:10,660 --> 00:14:11,670 什么原因呢? 221 00:14:11,670 --> 00:14:15,890 >> 嗯,上方还有,当我宣布 一个字符串,什么是真的 222 00:14:15,890 --> 00:14:17,260 引擎盖下? 223 00:14:17,260 --> 00:14:19,530 那么,就让我走了过来的 此处的画面和借鉴。 224 00:14:19,530 --> 00:14:23,230 所以,我再次宣布, 字符串s的GetString。 225 00:14:23,230 --> 00:14:26,640 >> 所以我要继续前进,现在 画为它到底是什么。 226 00:14:26,640 --> 00:14:28,590 这将是一个正方形。 227 00:14:28,590 --> 00:14:30,490 我要去要求 那是32位。 228 00:14:30,490 --> 00:14:32,890 至少它通常是, 至少在CS50 229 00:14:32,890 --> 00:14:34,520 很多计算机的器具。 230 00:14:34,520 --> 00:14:35,980 我会打电话给它s。 231 00:14:35,980 --> 00:14:39,070 >> 但是,现在还记得我们 称为GetString的。 232 00:14:39,070 --> 00:14:41,430 所以GetString的回报, 当然,一个字符串。 233 00:14:41,430 --> 00:14:45,790 如果H-E-L-L-Ø用户类型进入 获取返回字符串hello。 234 00:14:45,790 --> 00:14:51,010 而该字符串,正如我们刚才所说,结束 某处在您的计算机的内存 235 00:14:51,010 --> 00:14:53,240 在最后一个反斜杠0。 236 00:14:53,240 --> 00:14:56,650 我会得出这样的像数组 - 连续的字符块 - 237 00:14:56,650 --> 00:14:58,330 它实际上是。 238 00:14:58,330 --> 00:15:01,790 >> 而现在,则由GetString引发什么 实际上返回? 239 00:15:01,790 --> 00:15:04,340 有什么的GetString返回 所有这段时间呢? 240 00:15:04,340 --> 00:15:07,520 好吧,我们说,在几周之前, 它返回一个字符串。 241 00:15:07,520 --> 00:15:10,250 但更多的技术上的,这是什么 显然则由GetString引发返回? 242 00:15:10,250 --> 00:15:11,610 >> 观众:一个地址。 243 00:15:11,610 --> 00:15:12,600 >> 扬声器1:一个地址。 244 00:15:12,600 --> 00:15:16,630 具体来说,它返回的地址 第一口,不​​管它是什么。 245 00:15:16,630 --> 00:15:18,830 我只是不停地用一,二,三 因为它的方便。 246 00:15:18,830 --> 00:15:21,380 >> 返回地址的第一个 字符串中的字符。 247 00:15:21,380 --> 00:15:23,510 我们上周说, 是足够的。 248 00:15:23,510 --> 00:15:26,710 因为我们总是可以找出其中 仅仅通过结束的字符串 249 00:15:26,710 --> 00:15:30,150 遍历它,也许,与为 循环或while循环或类似的东西 250 00:15:30,150 --> 00:15:34,990 ,只是在寻找“反斜线0”, 特殊定点字符。 251 00:15:34,990 --> 00:15:37,220 >> 然后我们知道该字符串 的长度恰好是 - 252 00:15:37,220 --> 00:15:37,980 在这种情况下 - 253 00:15:37,980 --> 00:15:38,670 五。 254 00:15:38,670 --> 00:15:43,800 因此,技术上的GetString做什么 是在这种情况下,它返回Ox123。 255 00:15:43,800 --> 00:15:53,670 技术上然后发生了什么 我们存储,里面的s,Ox123。 256 00:15:53,670 --> 00:15:56,460 在一天结束时,尽管这 是新的概念,指针,他们 257 00:15:56,460 --> 00:15:57,350 只是变量。 258 00:15:57,350 --> 00:16:00,440 但他们碰巧存储位 共同表示一个地址。 259 00:16:00,440 --> 00:16:03,700 所以技术上都得到 在s中存储的是Ox123。 260 00:16:03,700 --> 00:16:04,680 >> 但我们作为人类 - 261 00:16:04,680 --> 00:16:06,020 包括今天起 - 262 00:16:06,020 --> 00:16:09,290 真的不会在意,通常, 实际地址是什么 263 00:16:09,290 --> 00:16:10,520 一些大块的内存。 264 00:16:10,520 --> 00:16:14,040 这只是低水平的细节 智力有趣。 265 00:16:14,040 --> 00:16:15,440 所以我打算撤消此。 266 00:16:15,440 --> 00:16:19,810 ,而是更多的高层次,只是说 当我们在谈论指针 267 00:16:19,810 --> 00:16:22,170 我要吸引更多 用户友好的箭头,传达 268 00:16:22,170 --> 00:16:26,060 同样的想法和摘要走 什么实际的详情 269 00:16:26,060 --> 00:16:27,700 基础地址。 270 00:16:27,700 --> 00:16:33,290 >> 现在,如果我们回去的代码, 上周发生,如果我们有字符串t 271 00:16:33,290 --> 00:16:34,510 等于则由GetString引发? 272 00:16:34,510 --> 00:16:38,630 好吧,如果我再次类型打招呼 这次我会得到 273 00:16:38,630 --> 00:16:40,460 另一块内存。 274 00:16:40,460 --> 00:16:44,820 H-E-L-L-O反斜线0。 275 00:16:44,820 --> 00:16:48,320 >> 但是,因为我要求则由GetString引发 第二次 - 276 00:16:48,320 --> 00:16:51,100 我知道这看着 GetString的源代码 - 即使 277 00:16:51,100 --> 00:16:54,350 虽然这是巧合,打招呼 输入两次,GetString的是不 278 00:16:54,350 --> 00:16:55,890 要尝试优化 和聪明。 279 00:16:55,890 --> 00:16:58,550 只是要得到另一块 从计算机中的存储器,这是 280 00:16:58,550 --> 00:16:59,640 要在另一个地址。 281 00:16:59,640 --> 00:17:02,330 让我们任意只是说456。 282 00:17:02,330 --> 00:17:04,079 >> 然后它是什么会回来? 283 00:17:04,079 --> 00:17:08,030 这将返回456 并将其存储在t。 284 00:17:08,030 --> 00:17:12,010 那么,什么是真的,在 左侧是我有另一块 285 00:17:12,010 --> 00:17:14,260 内存,通常是32位。 286 00:17:14,260 --> 00:17:16,720 在那里要去Ox456。 287 00:17:16,720 --> 00:17:20,140 不过,我没有兴趣在这些 特殊的数字了。 288 00:17:20,140 --> 00:17:23,069 我只是抽象 绘制箭头。 289 00:17:23,069 --> 00:17:25,202 >> 所以这是现在一种新的解释。 290 00:17:25,202 --> 00:17:28,735 但它是完全相同的想法 发生这一切的时候。 291 00:17:28,735 --> 00:17:33,150 等原因,那么,这首 版本比较的是越野车, 292 00:17:33,150 --> 00:17:34,480 上周是为什么呢? 293 00:17:34,480 --> 00:17:38,000 当你这样做,如果s等于等于 什么是你真正的吨 294 00:17:38,000 --> 00:17:40,550 引擎盖下比较? 295 00:17:40,550 --> 00:17:41,910 >> 你的地址进行比较。 296 00:17:41,910 --> 00:17:47,950 只是直观,清晰,Ox123 不会等于Ox456。 297 00:17:47,950 --> 00:17:49,380 这些数字,那些位 只是不同而已。 298 00:17:49,380 --> 00:17:53,220 >> 所以一致,上周说 你键入不同的事情,即使 299 00:17:53,220 --> 00:17:55,360 话逐字相同。 300 00:17:55,360 --> 00:17:58,770 因此,我们解决这个问题。 301 00:17:58,770 --> 00:18:00,120 通俗地说,什么是修复? 302 00:18:00,120 --> 00:18:02,110 >> 观众:使用功能。 303 00:18:02,110 --> 00:18:02,870 >> 扬声器1:使用功能。 304 00:18:02,870 --> 00:18:05,190 明星们肯定参与, 但使用功能做什么呢? 305 00:18:05,190 --> 00:18:05,962 >> 观众:要比较字符串。 306 00:18:05,962 --> 00:18:07,390 >> 扬声器1:比较字符串。 307 00:18:07,390 --> 00:18:11,030 所以这里的根本问题是 我只是考虑 308 00:18:11,030 --> 00:18:15,870 质量被定义的字符串 他们的地址相比较。 309 00:18:15,870 --> 00:18:18,540 很显然,这只是愚蠢的现在一次 你明白这是怎么回事 310 00:18:18,540 --> 00:18:19,510 引擎盖下。 311 00:18:19,510 --> 00:18:23,270 要真正比较字符串,看是否 他们是平等的,一个人的方式 312 00:18:23,270 --> 00:18:26,680 会考虑两个字符串是否相等 我们需要对它们进行比较字符 313 00:18:26,680 --> 00:18:28,070 对于字符。 314 00:18:28,070 --> 00:18:30,020 >> 现在我可以做 这很繁琐。 315 00:18:30,020 --> 00:18:32,240 但是,我们亲热 使用for循环。 316 00:18:32,240 --> 00:18:36,050 而只比较Ş支架 我对T支架í。 317 00:18:36,050 --> 00:18:39,590 Ş支架I加1对T支架 i加1,依此类推,里面 318 00:18:39,590 --> 00:18:40,580 某种循环。 319 00:18:40,580 --> 00:18:44,950 如果我发现任何两个字符 不同,或者如果我意识到,哦,S 320 00:18:44,950 --> 00:18:48,410 小于t或长于t 我可以马上说是假的, 321 00:18:48,410 --> 00:18:49,390 他们是不一样的。 322 00:18:49,390 --> 00:18:55,370 >> 但如果我通过s和t说 相同的,相同的,相同的,相同的,同样,年底 323 00:18:55,370 --> 00:18:58,520 这两个字符串,我可以说, 真的,他们都是平等的。 324 00:18:58,520 --> 00:19:01,040 那么,令人欣慰的是,几年前,有人 为我们写的代码。 325 00:19:01,040 --> 00:19:03,790 >> 他们把它称为StrComp 字符串比较。 326 00:19:03,790 --> 00:19:11,900 即使它是一个小柜台 直观,StrComp返回0,如果这些 327 00:19:11,900 --> 00:19:14,520 两个字符串中,s和t是相同的。 328 00:19:14,520 --> 00:19:18,090 但是,如果返回负值 应该是之前按字母顺序或 329 00:19:18,090 --> 00:19:20,610 它应该是正值,如果 后T字母顺序排列。 330 00:19:20,610 --> 00:19:24,030 >> 所以,如果你要排序的东西, StrComp是有用的。 331 00:19:24,030 --> 00:19:26,660 因为它不只是说 yes或no,等于或不。 332 00:19:26,660 --> 00:19:30,440 它给你一个订货感 喜欢字典威力。 333 00:19:30,440 --> 00:19:33,770 所以StrComp,S逗号T等于 等于0,则表示 334 00:19:33,770 --> 00:19:35,200 字符串是真正的平等。 335 00:19:35,200 --> 00:19:38,680 因为谁写了这个功能 几年前大概使用了一个for循环 336 00:19:38,680 --> 00:19:42,840 或一个while循环或类似的东西 再次,整合过的字符 337 00:19:42,840 --> 00:19:45,270 一遍又一遍。 338 00:19:45,270 --> 00:19:47,300 >> 但这里出现问题2。 339 00:19:47,300 --> 00:19:48,750 这是copy0.c。 340 00:19:48,750 --> 00:19:51,680 和两个红色 因为它是有缺陷的。 341 00:19:51,680 --> 00:19:52,800 我们做了什么? 342 00:19:52,800 --> 00:19:54,310 嗯,首先我叫则由GetString引发。 343 00:19:54,310 --> 00:19:56,255 我和存储在s的返回值。 344 00:19:56,255 --> 00:20:00,260 所以这是相当多的相同 这个图片的上部。 345 00:20:00,260 --> 00:20:01,490 >> 但之后呢? 346 00:20:01,490 --> 00:20:04,980 好吧,让我继续前进,摆脱 一大堆。 347 00:20:04,980 --> 00:20:09,650 我们的地方,我们只是时间会倒转 有,这是现在一致 348 00:20:09,650 --> 00:20:10,940 线那里。 349 00:20:10,940 --> 00:20:11,400 >> 我检查。 350 00:20:11,400 --> 00:20:13,450 如果s等于等于0。 351 00:20:13,450 --> 00:20:18,670 现在,快速侧面说明,当 可能的GetString返回0? 352 00:20:18,670 --> 00:20:19,580 有没有足够的内存。 353 00:20:19,580 --> 00:20:19,880 对吗? 354 00:20:19,880 --> 00:20:22,310 >> 这是罕见的,这是将要发生, 当然这是一个计算机 355 00:20:22,310 --> 00:20:24,740 有数百兆 甚至音乐会的RAM。 356 00:20:24,740 --> 00:20:27,080 但也有可能,在理论上,返回 0,特别是如果 357 00:20:27,080 --> 00:20:28,080 用户不配合。 358 00:20:28,080 --> 00:20:31,640 有办法假装像你有没有 输入任何东西和诀窍 359 00:20:31,640 --> 00:20:34,100 返回到则由GetString引发 0有效。 360 00:20:34,100 --> 00:20:35,470 >> 因此,它要检查。 361 00:20:35,470 --> 00:20:39,430 因为如果你开始 已经得到的,分割故障 - 362 00:20:39,430 --> 00:20:42,280 这可能是一个源 有些无奈 - 363 00:20:42,280 --> 00:20:46,150 这些结果几乎总是 内存相关的错误。 364 00:20:46,150 --> 00:20:50,440 不知怎的,你搞砸了,对于一个 指针,即使你没有意识到 365 00:20:50,440 --> 00:20:51,530 有一个指针。 366 00:20:51,530 --> 00:20:55,260 所以,你可能诱发分割 早在第一个星期使用故障 367 00:20:55,260 --> 00:21:02,100 像一个循环或while 循环和阵列走得太远的 368 00:21:02,100 --> 00:21:05,900 过去的一些阵列的边界 宣布,在本周二 369 00:21:05,900 --> 00:21:06,690 尤其如此。 370 00:21:06,690 --> 00:21:09,220 >> 你可能已经做了,即使问题 设置四个与突围。 371 00:21:09,220 --> 00:21:12,910 即使你可能从来没有见过 任何恒星分布代码 372 00:21:12,910 --> 00:21:17,410 突围,事实证明,那些GRect 和GOval和其他这样的事情, 373 00:21:17,410 --> 00:21:19,650 其实这些都是指针 引擎盖下。 374 00:21:19,650 --> 00:21:23,430 >> 但是,斯坦福大学,像我们这样的,排序的皮革 至少详细的库 375 00:21:23,430 --> 00:21:26,540 的目的,就像我们做 字符串和char *。 376 00:21:26,540 --> 00:21:30,060 但GRect GOval所有这些 你们的事情或将使用 377 00:21:30,060 --> 00:21:32,630 这个星期都少不了 内存地址。 378 00:21:32,630 --> 00:21:33,650 你只是不知道这一点。 379 00:21:33,650 --> 00:21:37,240 >> 所以这是不奇怪的话,也许, 你可能会绊倒一些 380 00:21:37,240 --> 00:21:38,580 段故障。 381 00:21:38,580 --> 00:21:41,290 但是,什么是有趣的, 如果我们检查后我们做 382 00:21:41,290 --> 00:21:43,460 字符串t得到s。 383 00:21:43,460 --> 00:21:44,690 好吧,让我申报吨。 384 00:21:44,690 --> 00:21:47,730 我打算把它画一个正方形, 32位,它吨。 385 00:21:47,730 --> 00:21:49,740 然后我要做的事情,得到s。 386 00:21:49,740 --> 00:21:51,130 >> 那么,是什么意思呢? 387 00:21:51,130 --> 00:21:53,280 嗯,这是一个有点很难想象 关于它的想象明智的。 388 00:21:53,280 --> 00:21:55,025 但是让我们想想 里面的x是什么? 389 00:21:55,025 --> 00:21:59,430 这里面变量字面上什么? 390 00:21:59,430 --> 00:22:01,500 价值Ox123。 391 00:22:01,500 --> 00:22:05,815 >> 所以当我说字符串t得到s,这只是 字面意思是取数 392 00:22:05,815 --> 00:22:10,070 在s,这是Ox123,并把它Ox123。 393 00:22:10,070 --> 00:22:13,740 或形象,如果我有点抽象 远离细节,它有 394 00:22:13,740 --> 00:22:16,600 从字面上做效果 这一点。 395 00:22:16,600 --> 00:22:22,110 >> 所以,现在,回想起上周 我们进行资本主义T.我 396 00:22:22,110 --> 00:22:23,800 Ť支架0。 397 00:22:23,800 --> 00:22:27,150 那么,T支架0,即使它是一个 指针,你可以把它仿佛 398 00:22:27,150 --> 00:22:29,220 它是一个数组,用方形 支架符号。 399 00:22:29,220 --> 00:22:31,550 >> 那么,是T支架0? 400 00:22:31,550 --> 00:22:32,990 那么,它的h。 401 00:22:32,990 --> 00:22:36,800 因此,当我们使用这行代码, 两个上,是C type.h中的 402 00:22:36,800 --> 00:22:38,460 头文件,这就是 它的声明。 403 00:22:38,460 --> 00:22:44,410 你把握H.但 当然,这是完全相同的h上 404 00:22:44,410 --> 00:22:46,540 s的内部,可以这么说。 405 00:22:46,540 --> 00:22:51,930 所以现在你已经改变或 资本化的原件和 406 00:22:51,930 --> 00:22:53,120 所谓的副本。 407 00:22:53,120 --> 00:22:56,620 因为你没有做一个副本 的方式,一个人会希望它是。 408 00:22:56,620 --> 00:22:59,710 >> 那么,什么是这里的修复, 在上周copy1.c? 409 00:22:59,710 --> 00:23:03,070 410 00:23:03,070 --> 00:23:05,580 功能,所以实际上,我们可以 复制字符串。 411 00:23:05,580 --> 00:23:08,700 从根本上说,我们需要 做以复制字符串? 412 00:23:08,700 --> 00:23:12,070 >> 那么,在我这里这个绿色版 要做到这一点相当低的水平。 413 00:23:12,070 --> 00:23:14,260 实际上有功能 他们可以帮助这一点。 414 00:23:14,260 --> 00:23:17,710 但是最基本的,而最 熟悉的,至少会很快 415 00:23:17,710 --> 00:23:19,600 我们所熟悉的,是下面的 - 416 00:23:19,600 --> 00:23:21,910 所以在第一行 现在代码在绿色。 417 00:23:21,910 --> 00:23:23,970 >> 我刚刚改写的char * s作为。 418 00:23:23,970 --> 00:23:25,250 有没有功能 区别。 419 00:23:25,250 --> 00:23:28,790 我只是扔掉CS50库 我打电话是什么,它​​是一个char *。 420 00:23:28,790 --> 00:23:31,640 >> 现在,点,点,点,因为有 这不是一些错误检查 421 00:23:31,640 --> 00:23:33,200 有趣的念叨。 422 00:23:33,200 --> 00:23:34,710 所以,现在t的声明。 423 00:23:34,710 --> 00:23:35,780 它也是一个char *。 424 00:23:35,780 --> 00:23:38,280 所以我画了一个小广场上 屏幕上像前。 425 00:23:38,280 --> 00:23:41,870 >> 但在右侧时,malloc 我们说的是内存分配。 426 00:23:41,870 --> 00:23:44,130 因此,分配一定的内存块。 427 00:23:44,130 --> 00:23:48,830 和我们实际上做了多少字节 要分配,它似乎? 428 00:23:48,830 --> 00:23:50,340 >> 嗯,字符串的长度为s。 429 00:23:50,340 --> 00:23:52,310 所以,如果要打招呼, 是五。 430 00:23:52,310 --> 00:23:53,950 我们会说:H-E-L-L-O。 431 00:23:53,950 --> 00:23:55,090 因此,5个字节。 432 00:23:55,090 --> 00:23:57,960 >> 但是,再加上1,为什么? 433 00:23:57,960 --> 00:23:58,830 0字符。 434 00:23:58,830 --> 00:24:03,640 如果我们不留有余地,这家伙我们 可能无意中造成这样的局面 435 00:24:03,640 --> 00:24:05,600 字符串是H-E-L-L-O。 436 00:24:05,600 --> 00:24:08,470 那么下一次的GetString 叫我输入,例如, 437 00:24:08,470 --> 00:24:14,020 戴维,D-α-v型的i-ð时,计算机会 认为s是 438 00:24:14,020 --> 00:24:18,900 h-e在升升 - 邻-D-α-v型的i-D因为有 没有打破这些单词之间。 439 00:24:18,900 --> 00:24:19,810 >> 因此,我们需要休息。 440 00:24:19,810 --> 00:24:20,720 所以,我们不希望五。 441 00:24:20,720 --> 00:24:22,100 我们需要6个字节。 442 00:24:22,100 --> 00:24:23,110 >> 和字节我说。 443 00:24:23,110 --> 00:24:25,220 但它是真的时大小字符。 444 00:24:25,220 --> 00:24:28,040 技术上char是几乎 始终是一个单字节。 445 00:24:28,040 --> 00:24:31,030 >> 但是,只是为了让我们的代码便携, 可以这么说,所以它的工作原理 446 00:24:31,030 --> 00:24:33,750 不同的计算机上,即使他们可能 下方的有所不同 447 00:24:33,750 --> 00:24:36,590 油烟机,我要笼统 说尺寸的字符,所以 448 00:24:36,590 --> 00:24:37,660 我的代码总是工作。 449 00:24:37,660 --> 00:24:40,610 我没有重新编译它只是 因为我的计算机升级或使用 450 00:24:40,610 --> 00:24:42,140 一些不同的平台。 451 00:24:42,140 --> 00:24:45,300 >> 所以我已经有了6倍的大小 一个字符,这恰好是1。 452 00:24:45,300 --> 00:24:47,440 因此,这意味着的malloc 给我六个月字节。 453 00:24:47,440 --> 00:24:49,140 ,实际上做的是什么? 454 00:24:49,140 --> 00:24:52,810 好吧,让我回滚时间在这里 我们所处的这个故事。 455 00:24:52,810 --> 00:24:57,620 >> 所以,如果我回到这里,我已经声明 一个char *名为t。 456 00:24:57,620 --> 00:25:00,280 我现在已经被称为6字节的malloc。 457 00:25:00,280 --> 00:25:06,400 现在我要吸引那些六 就像字节数组同期。 458 00:25:06,400 --> 00:25:10,570 但其实我不知道什么是 这个数组里面。 459 00:25:10,570 --> 00:25:14,640 >> 如果你分配内存事实证明, 你可以不相信有一些 460 00:25:14,640 --> 00:25:15,810 已知值。 461 00:25:15,810 --> 00:25:18,400 它可能已被使用的东西 否则,其他的一些功能,其他一些 462 00:25:18,400 --> 00:25:19,630 你写的代码行。 463 00:25:19,630 --> 00:25:22,870 所以,我们一般会调用这些垃圾 价值和借鉴他们,也许, 464 00:25:22,870 --> 00:25:26,170 问号,只是表明我们 不知道什么是实际存在的。 465 00:25:26,170 --> 00:25:30,390 这没什么大不了的,只要我们 有足够的智慧来覆盖这些 466 00:25:30,390 --> 00:25:34,550 垃圾值以数字或 我们关心的字符。 467 00:25:34,550 --> 00:25:36,340 >> 因此,在这种情况下,我该怎么办? 468 00:25:36,340 --> 00:25:38,670 好吧,我行代码 接下来,我有四个。 469 00:25:38,670 --> 00:25:41,350 INT I得到0,n变 字符串s的长度。 470 00:25:41,350 --> 00:25:42,750 因此,一个熟悉的for循环。 471 00:25:42,750 --> 00:25:45,875 I小于或等于n, 这通常是上述。 472 00:25:45,875 --> 00:25:47,500 >> 但是,这一次它是经过深思熟虑的。 473 00:25:47,500 --> 00:25:51,890 我+ +,然后我只是做 吨支架我得到s。 474 00:25:51,890 --> 00:25:56,320 因为我的照片看起来像这样 储存在这一刻,是 475 00:25:56,320 --> 00:25:59,530 ,随机的内存块的地址 它的值是未知的。 476 00:25:59,530 --> 00:26:03,030 但只要我做T支架 0,让我在这里。 477 00:26:03,030 --> 00:26:07,430 >> 什么最终会被绘制在那里? 478 00:26:07,430 --> 00:26:08,740 我们最终把ħ。 479 00:26:08,740 --> 00:26:11,170 ,因为这是在s支架0。 480 00:26:11,170 --> 00:26:14,300 然后同样的事情 E,和l,和l和o。 481 00:26:14,300 --> 00:26:17,930 >> N,为什么我去通过 一个等于n? 482 00:26:17,930 --> 00:26:19,200 由于“0”字符。 483 00:26:19,200 --> 00:26:23,580 所以只要是明确的,那么,如果我真的 清除这些垃圾 484 00:26:23,580 --> 00:26:28,870 值,然后绘制 我所期望的,这是支架1,2, 485 00:26:28,870 --> 00:26:32,440 3,4,加尾随 新的字符。 486 00:26:32,440 --> 00:26:36,080 >> 所以,如果我们现在继续过去的点, 点,点在这条正确的版本 487 00:26:36,080 --> 00:26:41,930 及资本化支架0我想, 当然,把握这一点 488 00:26:41,930 --> 00:26:47,050 家伙在这里,从概念上讲, 最终的目标。 489 00:26:47,050 --> 00:26:48,040 所以这是所有的指针。 490 00:26:48,040 --> 00:26:51,430 >> 而你一直在使用他们周 现在在字符串的上下文中。 491 00:26:51,430 --> 00:26:53,530 但引擎盖下他们 更复杂一点。 492 00:26:53,530 --> 00:26:57,520 但如果你认为他们在这 图文并茂的形式,我建议他们 493 00:26:57,520 --> 00:27:01,720 可能不是所有的可怕,因为他们 可能先乍一看, 494 00:27:01,720 --> 00:27:04,730 尤其是这种新的语法。 495 00:27:04,730 --> 00:27:07,290 如有任何问题上的指针, 字符串或字符? 496 00:27:07,290 --> 00:27:07,580 是吗? 497 00:27:07,580 --> 00:27:09,252 >> 观众:你能回去 [听不清]? 498 00:27:09,252 --> 00:27:10,502 >> 扬声器1:当然。 499 00:27:10,502 --> 00:27:14,058 500 00:27:14,058 --> 00:27:19,525 >> 观众:那么,为什么你最后的 行了,你没有一个* T线 501 00:27:19,525 --> 00:27:21,513 行中的A * S? 502 00:27:21,513 --> 00:27:23,004 难道你不具有参考 - 503 00:27:23,004 --> 00:27:24,640 >> 扬声器1:啊,一个很好的问题。 504 00:27:24,640 --> 00:27:26,800 为什么不我有一个* t和A * S? 505 00:27:26,800 --> 00:27:30,340 因为简单地说,上周,像在我们的 交换功能,我没有说,当 506 00:27:30,340 --> 00:27:33,350 你已经有了一个指针的手段 你去那里,因为我们没有 507 00:27:33,350 --> 00:27:36,590 身体在舞台上,实际 使用星算。 508 00:27:36,590 --> 00:27:40,570 >> 事实证明,这个方括号 符号是什么,我们会打电话给句法 509 00:27:40,570 --> 00:27:44,190 糖,这仅仅是一个性感的方式 说这是速记符号 510 00:27:44,190 --> 00:27:45,950 正是你所描述的。 511 00:27:45,950 --> 00:27:49,385 但它更直观一点。 512 00:27:49,385 --> 00:27:53,510 决策的风险,这似乎更 复杂,比它需要的是, 513 00:27:53,510 --> 00:27:56,990 这里到底发生了什么 - 514 00:27:56,990 --> 00:28:01,450 如果我说*吨,这意味着去 在t存储的地址。 515 00:28:01,450 --> 00:28:04,350 >> 从字面上看,如果T是存储 使得h的地址 516 00:28:04,350 --> 00:28:07,300 最初,* T手段去这里。 517 00:28:07,300 --> 00:28:10,730 现在,吨支架0是什么意思? 518 00:28:10,730 --> 00:28:11,560 完全相同的事情。 519 00:28:11,560 --> 00:28:13,510 这只是一个对用户来说更加 友好的写。 520 00:28:13,510 --> 00:28:14,430 >> 但我还没有完成。 521 00:28:14,430 --> 00:28:17,800 我不能只是说* T *秒获得。 522 00:28:17,800 --> 00:28:19,440 因为我会做什么呢? 523 00:28:19,440 --> 00:28:22,950 我把H,H,H,H,H 在整个事情。 524 00:28:22,950 --> 00:28:22,995 对吗? 525 00:28:22,995 --> 00:28:26,020 >> 由于* t是在t的地址。 526 00:28:26,020 --> 00:28:27,580 但是,我们是在一个循环内。 527 00:28:27,580 --> 00:28:32,150 什么样的价值,我在递增, 当然,在每次迭代中吗? 528 00:28:32,150 --> 00:28:32,690 (一) 529 00:28:32,690 --> 00:28:34,590 >> 但是,有一个机会 在这里,对不对? 530 00:28:34,590 --> 00:28:37,870 尽管这种感觉就像它变得 更复杂一点 531 00:28:37,870 --> 00:28:40,730 方括号表示法比 我们已经用了一段时间 - 532 00:28:40,730 --> 00:28:43,840 让我撤消我的H有变化 - 533 00:28:43,840 --> 00:28:48,870 即使是现在开始有点 神奇的是,基本的想法,如果* T 534 00:28:48,870 --> 00:28:53,630 这里指的* t是刚刚 去t的地址。 535 00:28:53,630 --> 00:28:54,990 >> 但是,什么是在t的地址? 536 00:28:54,990 --> 00:28:56,850 我们一直使用的号码? 537 00:28:56,850 --> 00:29:00,540 像Ox456,让带回来 只是就事论事。 538 00:29:00,540 --> 00:29:05,380 好吧,如果我想要得到电子 吨字符串,我只是想归想, 539 00:29:05,380 --> 00:29:06,460 从本质上讲,456。 540 00:29:06,460 --> 00:29:09,230 >> 或者更确切地说,457。 541 00:29:09,230 --> 00:29:10,590 我只需要添加一个。 542 00:29:10,590 --> 00:29:11,790 但我可以做到这一点,对不对? 543 00:29:11,790 --> 00:29:14,680 因为T,即使我把图纸 现在作为一个箭头,它只是一个 544 00:29:14,680 --> 00:29:16,570 号,Ox456。 545 00:29:16,570 --> 00:29:21,400 而如果我添加一个,或多个 一般而言,如果我加我,我可以 546 00:29:21,400 --> 00:29:24,350 实际上,正是我想要的。 547 00:29:24,350 --> 00:29:26,260 所以,如果我真的这样做 - 548 00:29:26,260 --> 00:29:28,970 这就是现在被称为 指针运算 - 549 00:29:28,970 --> 00:29:30,375 我可以删除这一行。 550 00:29:30,375 --> 00:29:33,550 这是,坦率地说,我觉得更清晰, 对用户来说更加友好的阅读。 551 00:29:33,550 --> 00:29:35,970 但是,这是不正确的。 552 00:29:35,970 --> 00:29:38,570 >> 现在这行代码使用 指针的算术运算。 553 00:29:38,570 --> 00:29:40,920 说去 地址如下 - 554 00:29:40,920 --> 00:29:44,670 无论吨开始,这 再加上我是,最初 555 00:29:44,670 --> 00:29:45,730 为0,这是伟大的。 556 00:29:45,730 --> 00:29:49,280 因为这意味着吨的开始 加1,加2,加3,依此类推。 557 00:29:49,280 --> 00:29:51,030 和相同的处理为s。 558 00:29:51,030 --> 00:29:52,750 >> 所以语法糖。 559 00:29:52,750 --> 00:29:55,900 但是,了解究竟发生了什么事情 引擎盖下,我认为, 560 00:29:55,900 --> 00:29:57,410 本身实际上是有用。 561 00:29:57,410 --> 00:30:00,620 因为这意味着现在有没有 更魔法 562 00:30:00,620 --> 00:30:01,620 引擎盖下。 563 00:30:01,620 --> 00:30:03,920 不会多 我们可以剥离备份你的层。 564 00:30:03,920 --> 00:30:04,810 这是c。 565 00:30:04,810 --> 00:30:06,410 这是编程。 566 00:30:06,410 --> 00:30:08,002 真是个好问题。 567 00:30:08,002 --> 00:30:11,570 >> 所有的权利,所以这是那个马车 我指的是早期的程序。 568 00:30:11,570 --> 00:30:12,650 交换是有缺陷的。 569 00:30:12,650 --> 00:30:14,070 如果没有似乎工作。 570 00:30:14,070 --> 00:30:17,390 回想一下,就像牛奶和 橙汁 - 我开始 571 00:30:17,390 --> 00:30:18,660 喝今天的示范。 572 00:30:18,660 --> 00:30:22,220 因此,正如橙汁和 牛奶,我们也必须使用 573 00:30:22,220 --> 00:30:26,200 临时变量,TMP,举行 暂时这样,我们便可以 574 00:30:26,200 --> 00:30:28,820 改变它的值,然后更新B。 575 00:30:28,820 --> 00:30:32,870 >> 但是这个功能,我们说,这 程序中,此功能 576 00:30:32,870 --> 00:30:35,670 写的是错的,有缺陷的,为什么呢? 577 00:30:35,670 --> 00:30:38,870 578 00:30:38,870 --> 00:30:39,090 是吗? 579 00:30:39,090 --> 00:30:42,471 >> 观众:[听不清]。 580 00:30:42,471 --> 00:30:44,940 >> 扬声器1:没错,当 你叫掉期 - 581 00:30:44,940 --> 00:30:47,820 或者更一般地,当你 调用任何功能最 - 582 00:30:47,820 --> 00:30:51,210 如果该函数的参数 原始的,可以这么说,整数和字符 583 00:30:51,210 --> 00:30:56,740 双打和花车,万物而不 星星,你是通过在副本 584 00:30:56,740 --> 00:30:57,540 的说法。 585 00:30:57,540 --> 00:31:01,580 因此,如果x为1,y为2,将 1和b为2。 586 00:31:01,580 --> 00:31:05,250 但他们要去不同的块 位,不同的块 587 00:31:05,250 --> 00:31:07,540 内存发生存储 相同的值。 588 00:31:07,540 --> 00:31:12,160 >> 因此,这段代码是超​​级完美 在交换a和b。 589 00:31:12,160 --> 00:31:13,850 这是没有什么好交换 - 590 00:31:13,850 --> 00:31:15,290 在上周的例子 - 591 00:31:15,290 --> 00:31:16,390 x和y。 592 00:31:16,390 --> 00:31:18,780 这还是因为同样的原因,他们是 在错误的范围内。 593 00:31:18,780 --> 00:31:21,310 >> 现在,我们怎么去解决这个? 594 00:31:21,310 --> 00:31:23,140 我们不得不做出的功能 看起来有点丑陋。 595 00:31:23,140 --> 00:31:25,250 但是还要考虑什么 这也就意味着。 596 00:31:25,250 --> 00:31:27,840 597 00:31:27,840 --> 00:31:31,500 >> 而实际上,让我的一致性, 改变的一件事,所以这是相同的 598 00:31:31,500 --> 00:31:33,200 我们只是做了什么。 599 00:31:33,200 --> 00:31:35,690 正如我上周提到的,它不会 无论身在何处。 600 00:31:35,690 --> 00:31:38,120 事实上,通常你会放 星级旁边的变量名。 601 00:31:38,120 --> 00:31:40,750 但我认为这将是更容易一些 旁边的考虑* 602 00:31:40,750 --> 00:31:44,910 这意味着它的数据类型是一个指针 在这种情况下,一个int。 603 00:31:44,910 --> 00:31:46,270 >> 所以我在这里做什么? 604 00:31:46,270 --> 00:31:49,590 我说不要给我一个int 其次另一个诠释, 605 00:31:49,590 --> 00:31:50,810 称他们为a和b。 606 00:31:50,810 --> 00:31:52,460 给我一个int的地址。 607 00:31:52,460 --> 00:31:53,960 给我地址的另一种诠释。 608 00:31:53,960 --> 00:31:56,330 调用这些地址a和b。 609 00:31:56,330 --> 00:32:00,860 >> 然后使用*符号下降 下面,每个地址 610 00:32:00,860 --> 00:32:05,290 根据需要,以得到 或设置其价值。 611 00:32:05,290 --> 00:32:07,400 但这里有一个例外。 612 00:32:07,400 --> 00:32:11,130 为什么我不会有* TMP旁边? 613 00:32:11,130 --> 00:32:15,070 为什么我不能做到这一点,例如? 614 00:32:15,070 --> 00:32:19,370 这感觉就像我应该全力以赴 和纠正整个事情。 615 00:32:19,370 --> 00:32:19,752 是吗? 616 00:32:19,752 --> 00:32:21,002 >> 观众:[听不清]。 617 00:32:21,002 --> 00:32:23,280 618 00:32:23,280 --> 00:32:25,480 >> 扬声器1:我还没有宣布 tmp作为一个字符串。 619 00:32:25,480 --> 00:32:28,830 620 00:32:28,830 --> 00:32:34,950 因此,这将声明,在这种情况下, 一个tmp目录是一个int的地址。 621 00:32:34,950 --> 00:32:37,380 但是,这不是我想要的那种, 一对夫妇的原因。 622 00:32:37,380 --> 00:32:38,616 >> 观众:你不想来交换他们。 623 00:32:38,616 --> 00:32:41,800 >> 扬声器1:没错,我不想要交换 任何与TMP。 tmp是刚 624 00:32:41,800 --> 00:32:42,790 本周一的东西。 625 00:32:42,790 --> 00:32:45,150 所有我想要的是一个变量 存储一些数字。 626 00:32:45,150 --> 00:32:47,330 我什至不关心地址 在这一刻。 627 00:32:47,330 --> 00:32:50,530 >> 我只需要32位或 因此存储一个int。 628 00:32:50,530 --> 00:32:56,690 我要把这32位 无论是不是在,可以这么说,但 629 00:32:56,690 --> 00:33:01,260 处于什么,只是为了更精确。 630 00:33:01,260 --> 00:33:06,420 因为如果是一个地址,一个表示 去那里,并获得价值1。 631 00:33:06,420 --> 00:33:10,560 例如,在上周的例子 或在b的情况下,得到的价值2。 632 00:33:10,560 --> 00:33:11,750 >> 所以,到底发生了什么? 633 00:33:11,750 --> 00:33:15,070 让我画一幅画,在这里,将 只梳理除了今天的一部分。 634 00:33:15,070 --> 00:33:18,580 但是,这将继续出现 相当长的一段时间。 635 00:33:18,580 --> 00:33:22,430 >> ,我要求,这就是您的电脑 当你运行一个内存看起来像 636 00:33:22,430 --> 00:33:24,060 程序,任何程序。 637 00:33:24,060 --> 00:33:28,340 当你运行一个程序在最高层 您的计算机的RAM - 所以想到 638 00:33:28,340 --> 00:33:33,530 这个矩形,真正实现了,因为你的 计算机的RAM或内存,所有101 639 00:33:33,530 --> 00:33:36,920 全2亿亿字节, 字节,两个千兆字节的, 640 00:33:36,920 --> 00:33:39,910 无论你有, 让我们绘制一个矩形。 641 00:33:39,910 --> 00:33:43,260 我要求,当你运行一个程序 如Microsoft Word或Chrome 642 00:33:43,260 --> 00:33:49,220 或类似的东西,的位 微软,谷歌写道 - 643 00:33:49,220 --> 00:33:50,910 在这些程序的案件 - 644 00:33:50,910 --> 00:33:54,490 被加载到您的计算机的内存 在那里他们可以执行 645 00:33:54,490 --> 00:33:57,520 迅速送入CPU, 是计算机大脑。 646 00:33:57,520 --> 00:34:00,940 >> 谭它们存储非常 你的程序,可以这么说。 647 00:34:00,940 --> 00:34:03,300 换言之,如果这是一个块的 内存,当你双击 648 00:34:03,300 --> 00:34:05,740 微软的Word,位来 关闭硬盘驱动器。 649 00:34:05,740 --> 00:34:06,680 他们得到加载到RAM中。 650 00:34:06,680 --> 00:34:10,330 我们要赶路他们在最高层 这个矩形的概念。 651 00:34:10,330 --> 00:34:13,010 >> 好吧,剩下的是你的记忆 用于不同的事情。 652 00:34:13,010 --> 00:34:16,460 在最顶端,你看到初始化 数据和未初始化的数据。 653 00:34:16,460 --> 00:34:20,500 这样做的,在大多数情况下, 常量或全局变量 654 00:34:20,500 --> 00:34:21,340 有值。 655 00:34:21,340 --> 00:34:22,980 但那些其他时间。 656 00:34:22,980 --> 00:34:25,150 >> 然后你有堆, 我们会回来的。 657 00:34:25,150 --> 00:34:28,420 但在底部则是部分 尤其是现在有密切关系。 658 00:34:28,420 --> 00:34:30,210 这是所谓的堆栈。 659 00:34:30,210 --> 00:34:33,850 所以,就像在任何D厅 大学校园,你有那些托盘 660 00:34:33,850 --> 00:34:37,210 只是堆放在彼此顶部上 你可以把食物和诸如此类的东西。 661 00:34:37,210 --> 00:34:40,139 在计算机系统中的堆栈 是非常相似的。 662 00:34:40,139 --> 00:34:42,679 除而托盘,我们使用 食堂,当然是 663 00:34:42,679 --> 00:34:45,710 随身携带的东西托盘 或框架 - 664 00:34:45,710 --> 00:34:49,469 因为我们会打电话给他们 - 在计算机的 存储器是用来存放 665 00:34:49,469 --> 00:34:51,610 变量和值。 666 00:34:51,610 --> 00:34:53,929 >> 那么真正的推移 引擎盖下? 667 00:34:53,929 --> 00:34:55,820 好吧,让我翻转 这里的画面。 668 00:34:55,820 --> 00:34:58,370 而让刚上的重点 片刻的底部的一部分。 669 00:34:58,370 --> 00:35:02,770 如果这是我的底部 电脑的记忆体,它原来的时候我 670 00:35:02,770 --> 00:35:05,350 调用函数主 - 发生的事情,坦率地说, 671 00:35:05,350 --> 00:35:06,950 自动为我 - 672 00:35:06,950 --> 00:35:10,510 我得到一个内存块 我的内存的底部可以这么说。 673 00:35:10,510 --> 00:35:13,390 这是主要的 局部变量去。 674 00:35:13,390 --> 00:35:16,770 这是argc和argv也许 走,和我的任何变量 675 00:35:16,770 --> 00:35:18,170 主要内申报。 676 00:35:18,170 --> 00:35:20,260 他们最终在底部 我的电脑的RAM。 677 00:35:20,260 --> 00:35:25,040 >> 现在,假设主要的电话功能 像掉,像它上周? 678 00:35:25,040 --> 00:35:30,620 好吧,我们基本上是把一个新的托盘, 新的框架,到我的内存块。 679 00:35:30,620 --> 00:35:34,160 我要形容这是 属于交换功能。 680 00:35:34,160 --> 00:35:35,770 >> 现在里面有什么交换? 681 00:35:35,770 --> 00:35:39,240 嗯,根据上周的节目 我们刚才看到的一段摘录, 682 00:35:39,240 --> 00:35:46,590 交换的框架内,或掉期 托盘,有哪些变量? 683 00:35:46,590 --> 00:35:47,970 那么,a和b。 684 00:35:47,970 --> 00:35:51,850 因为那是其本地的参数, 加上第三,TMP。 685 00:35:51,850 --> 00:35:54,470 所以,说真的,我可以得出这样的 一个更干净一点。 686 00:35:54,470 --> 00:35:56,680 让我继续前进,撤消标签。 687 00:35:56,680 --> 00:35:58,520 我要求你知道是什么吗? 688 00:35:58,520 --> 00:36:00,560 >> 一个很可能会在这里结束了。 689 00:36:00,560 --> 00:36:02,160 B是在这里要结束了。 690 00:36:02,160 --> 00:36:03,810 和TMP在这里要结束了。 691 00:36:03,810 --> 00:36:05,160 现在,顺序可能 有点不同。 692 00:36:05,160 --> 00:36:06,840 但是,这是概念上的想法。 693 00:36:06,840 --> 00:36:11,490 >> 只是统称,这是什么 我们会打电话给交换的框架,或 694 00:36:11,490 --> 00:36:12,136 餐饮大厅托盘。 695 00:36:12,136 --> 00:36:13,150 同样处理主要。 696 00:36:13,150 --> 00:36:14,040 但我不会重绘。 697 00:36:14,040 --> 00:36:17,810 但是,这其中argc和argv和任何 等局部变量x和y 698 00:36:17,810 --> 00:36:18,940 可能。 699 00:36:18,940 --> 00:36:22,170 >> 所以,现在考虑到底发生了什么 当你调用掉。 700 00:36:22,170 --> 00:36:26,370 当你调用swap,执行这样的代码 这一点,你正在传递中,在 701 00:36:26,370 --> 00:36:30,670 越野车的版本,a和b; 作为x和y的副本。 702 00:36:30,670 --> 00:36:34,300 所以,如果我现在得出这样的 在屏幕上 - 703 00:36:34,300 --> 00:36:36,700 得到得到更好的产品 - 704 00:36:36,700 --> 00:36:40,850 这样的故事,我告诉我自己 在这个马车版本,当我们 705 00:36:40,850 --> 00:36:46,130 调用交换传递字面上a和b 整数,到底发生了什么? 706 00:36:46,130 --> 00:36:48,250 >> 那么,这到底发生了什么。 707 00:36:48,250 --> 00:36:52,850 让我继续前进,只是撤消 这里明确了一些空间。 708 00:36:52,850 --> 00:36:54,720 所以这是我的电脑的内存。 709 00:36:54,720 --> 00:36:57,510 >> 所以,如果我有,例如 - 710 00:36:57,510 --> 00:36:58,910 居然让这样来做 - 711 00:36:58,910 --> 00:37:02,690 如果这是我要求的x,存储 就像上周的值为1。 712 00:37:02,690 --> 00:37:05,930 这是Y,存储的价值 就像上周。 713 00:37:05,930 --> 00:37:11,370 这是主要的,当我打电话交换, 从而给自己访问和 714 00:37:11,370 --> 00:37:15,150 b和TMP,我要去声称 这是一个,这是1。 715 00:37:15,150 --> 00:37:16,080 >> 这是b。 716 00:37:16,080 --> 00:37:17,010 这是2。 717 00:37:17,010 --> 00:37:18,370 这就是所谓的TMP。 718 00:37:18,370 --> 00:37:23,360 >> 最初,它有一些垃圾值 直到我真正存储在一个 719 00:37:23,360 --> 00:37:24,450 这是1。 720 00:37:24,450 --> 00:37:28,320 然后,我去动手改变 一个是什么? 721 00:37:28,320 --> 00:37:29,720 B的值。 722 00:37:29,720 --> 00:37:31,980 >> 所以现在我这里有两个。 723 00:37:31,980 --> 00:37:34,050 然后我们说,B得到TMP。 724 00:37:34,050 --> 00:37:37,670 同样,就像进行仔细的检查,第三 这里的代码很简单,就是 725 00:37:37,670 --> 00:37:39,440 一,B得到TMP。 726 00:37:39,440 --> 00:37:41,730 >> 所以最后,我该怎么办? 727 00:37:41,730 --> 00:37:46,800 我继续前进,变动b是什么 tmp的值,也就是1。 728 00:37:46,800 --> 00:37:48,390 我不碰TMP。 729 00:37:48,390 --> 00:37:54,100 >> 但是,现在的问题是尽快交换 的回报,因为它的不移交 730 00:37:54,100 --> 00:37:57,540 备份有一定的价值,不归路 声明中明确。 731 00:37:57,540 --> 00:37:59,080 实际上发生了什么? 732 00:37:59,080 --> 00:38:03,480 嗯,基本上这一切的记忆 - 733 00:38:03,480 --> 00:38:07,410 OK,显然橡皮擦喜欢 只用一根手指在一个时间 - 734 00:38:07,410 --> 00:38:08,180 就这样消失。 735 00:38:08,180 --> 00:38:10,070 >> 现在,在现实中,它不是 去任何地方。 736 00:38:10,070 --> 00:38:11,810 但是,你可以把它想象 现在为问号。 737 00:38:11,810 --> 00:38:14,040 因为它不再 实际使用。 738 00:38:14,040 --> 00:38:17,470 并没有什么做这些值。 739 00:38:17,470 --> 00:38:21,920 >> 因此,在的情况下,绿色版的 这段代码,而不是什么是 740 00:38:21,920 --> 00:38:24,640 传递到交换? 741 00:38:24,640 --> 00:38:25,770 所以解决。 742 00:38:25,770 --> 00:38:28,520 因此,x的地址和 y的地址。 743 00:38:28,520 --> 00:38:35,790 因此,如果我们重新讲述这个故事的最后一 时间,其实我画再次交换, 744 00:38:35,790 --> 00:38:44,620 但与指针,这是一个,这 B,这是TMP,是什么 745 00:38:44,620 --> 00:38:49,080 实际上存储在这个绿色 我通过我的代码版本 746 00:38:49,080 --> 00:38:52,110 在地址? 747 00:38:52,110 --> 00:38:53,780 >> 这将是一个指向x的指针。 748 00:38:53,780 --> 00:38:54,890 所以,我可以画一个箭头。 749 00:38:54,890 --> 00:38:57,310 但是,让我们使用相同的任意 如前。 750 00:38:57,310 --> 00:39:01,220 比方说,这是 像Ox123。 751 00:39:01,220 --> 00:39:04,970 这是怎么回事Ox127,因为 这四个字节,因为它是一个 752 00:39:04,970 --> 00:39:07,370 INT,所以Ox127。 753 00:39:07,370 --> 00:39:09,080 >> 再次,我采取了一些自由 数字。 754 00:39:09,080 --> 00:39:11,430 他们会比他们小得多 实际上是在不同的顺序。 755 00:39:11,430 --> 00:39:14,350 但是,这是怎样的画面 现在不同了。 756 00:39:14,350 --> 00:39:19,060 >> 但是当我使用这个绿色的代码 我INT TMP * A。 757 00:39:19,060 --> 00:39:25,010 *一种手段,做到以下几点,采取 解决在去 758 00:39:25,010 --> 00:39:26,190 这是1。 759 00:39:26,190 --> 00:39:28,480 这就是我然后把tmp中。 760 00:39:28,480 --> 00:39:32,480 同时,在下一行代码 在这里,一个得到b,是什么意思呢? 761 00:39:32,480 --> 00:39:36,910 >> 那么,*,所以要在这里得到* B, 这意味着去那里。 762 00:39:36,910 --> 00:39:39,310 这意味着把那里的价值。 763 00:39:39,310 --> 00:39:43,670 最后,最后一行代码 简单地说* B得到TMP。 764 00:39:43,670 --> 00:39:48,900 >> 所以B说去那里,覆盖它 tmp的,在这种情况下,将 765 00:39:48,900 --> 00:39:51,520 再次,1。 766 00:39:51,520 --> 00:39:54,920 这就是为什么绿色版 我们的代码工作,而红色 767 00:39:54,920 --> 00:39:56,010 版本从来没有。 768 00:39:56,010 --> 00:39:59,020 这一切都只是归结到如何 内存管理,并在它的 769 00:39:59,020 --> 00:40:02,580 实际上放置在您的 计算机的RAM。 770 00:40:02,580 --> 00:40:07,270 现在来看,这是一个的事 堆栈被用于。 771 00:40:07,270 --> 00:40:09,225 >> 布局上的问题? 772 00:40:09,225 --> 00:40:10,380 指针? 773 00:40:10,380 --> 00:40:11,630 或掉期? 774 00:40:11,630 --> 00:40:13,740 775 00:40:13,740 --> 00:40:17,043 >> 所有的权利,这样的malloc,召回, 做这样的事情。 776 00:40:17,043 --> 00:40:18,260 这是一个超级简单的例子。 777 00:40:18,260 --> 00:40:20,550 这是一个宾基 向我们介绍,虽然相当 778 00:40:20,550 --> 00:40:21,870 很快,在末级。 779 00:40:21,870 --> 00:40:24,480 该死,我们又来了。 780 00:40:24,480 --> 00:40:28,780 >> 所以记得,这是例子 宾基向我们介绍,尽管 781 00:40:28,780 --> 00:40:30,360 有些快速末级。 782 00:40:30,360 --> 00:40:33,640 在这里,我们真正使用的malloc 第二次。 783 00:40:33,640 --> 00:40:37,330 因为我们第一次用它来 创造足够的RAM,分配足够的RAM 784 00:40:37,330 --> 00:40:38,340 存储字符串。 785 00:40:38,340 --> 00:40:40,250 >> 这一次宾基保持简单。 786 00:40:40,250 --> 00:40:42,465 因此,它是只存储 一个int,显然。 787 00:40:42,465 --> 00:40:43,510 这是完全正常的。 788 00:40:43,510 --> 00:40:46,560 这是一个有点怪异,坦率地说, 使用malloc来分配一个int。 789 00:40:46,560 --> 00:40:50,650 但有一点是尼克的黏土动画 真的只是讲什么样的故事 790 00:40:50,650 --> 00:40:53,830 发生或不会发生在 你虐待内存。 791 00:40:53,830 --> 00:40:56,520 >> 因此,在这种情况下,本程序 做了几件事。 792 00:40:56,520 --> 00:41:01,580 这里在第一种情况下,它声明 一个指向名为x为int类型。 793 00:41:01,580 --> 00:41:04,480 然后声明一个指针 称为y为一个int。 794 00:41:04,480 --> 00:41:06,150 然后,它存储在x,什么? 795 00:41:06,150 --> 00:41:07,110 现在别人。 796 00:41:07,110 --> 00:41:09,685 什么被存储在x 第三行这个程序吗? 797 00:41:09,685 --> 00:41:12,380 >> 观众:[听不清]。 798 00:41:12,380 --> 00:41:14,130 >> 扬声器1:嗯,不太 字节,每说。 799 00:41:14,130 --> 00:41:16,760 现在更精确。 800 00:41:16,760 --> 00:41:18,325 被存储在x什么? 801 00:41:18,325 --> 00:41:21,000 802 00:41:21,000 --> 00:41:22,060 一个地址,我想我听到了。 803 00:41:22,060 --> 00:41:23,570 >> 那么,是什么的malloc返回? 804 00:41:23,570 --> 00:41:26,030 行为上的malloc分配 一块内存。 805 00:41:26,030 --> 00:41:27,850 但它是如何给你访问它? 806 00:41:27,850 --> 00:41:29,460 它返回什么? 807 00:41:29,460 --> 00:41:32,000 第一个字节的地址 在内存块。 808 00:41:32,000 --> 00:41:33,020 >> 现在,这是超级简单。 809 00:41:33,020 --> 00:41:35,380 这只是一个字节,这意味着 解决我们要的是 810 00:41:35,380 --> 00:41:37,300 整个事情的地址。 811 00:41:37,300 --> 00:41:42,070 因此,存储在x,那么,地址是 该内存块。 812 00:41:42,070 --> 00:41:43,400 同时,接下来会发生什么? 813 00:41:43,400 --> 00:41:45,890 因此,实际上,让我们继续前进, 绘制出真正的快。 814 00:41:45,890 --> 00:41:52,490 >> 因此,如果我们去到屏幕 我们玩了这一点* X和int * Y 815 00:41:52,490 --> 00:41:53,740 打算做什么我? 816 00:41:53,740 --> 00:41:58,280 我要求它只是打算做 这样的事情,并称之为x, 817 00:41:58,280 --> 00:42:00,010 这Ÿ。 818 00:42:00,010 --> 00:42:03,110 同时,第三行代码 要分配一个int的大小, 819 00:42:03,110 --> 00:42:06,160 这恰好是 - 对不起,如果我说 前一个,我的意思是一个int - 820 00:42:06,160 --> 00:42:08,280 一个典型的计算机上的四个字节。 821 00:42:08,280 --> 00:42:09,720 至少与CS50器具。 822 00:42:09,720 --> 00:42:11,490 >> 所以,这是怎么回事分配 它,谁知道? 823 00:42:11,490 --> 00:42:12,800 某处在这里。 824 00:42:12,800 --> 00:42:15,780 而这在某些存储 地址牛,谁知道? 825 00:42:15,780 --> 00:42:18,330 但是,这是怎么回事返回 是该地址。 826 00:42:18,330 --> 00:42:22,270 但是,我们会得出这样的形象 只是这样的箭头。 827 00:42:22,270 --> 00:42:25,430 >> 现在,在下一行* x变42。 828 00:42:25,430 --> 00:42:29,400 * X是什么意思通俗地说? 829 00:42:29,400 --> 00:42:30,040 只是去那里。 830 00:42:30,040 --> 00:42:30,960 进入到该地址。 831 00:42:30,960 --> 00:42:35,900 或者换句话说,按照 箭头,并有42把。 832 00:42:35,900 --> 00:42:38,140 但是坏事发生 宾基,对不对? 833 00:42:38,140 --> 00:42:43,950 >> 回想一下,行五在这里,* Y获取 13日,确实是一个不吉利的数字, 834 00:42:43,950 --> 00:42:44,760 做了什么,对我们? 835 00:42:44,760 --> 00:42:47,320 那么,* y表示去那里。 836 00:42:47,320 --> 00:42:50,460 嗯,这还没有得到 值,对不对? 837 00:42:50,460 --> 00:42:54,090 代码没有y为 初始化任何东西。 838 00:42:54,090 --> 00:42:56,120 我们照了X被初始化 一个地址。 839 00:42:56,120 --> 00:42:57,640 但Y被宣布往上顶。 840 00:42:57,640 --> 00:43:00,250 但随后一个分号,没有价值 实际上是把它。 841 00:43:00,250 --> 00:43:02,330 所以这是公平地调用这个 垃圾值。 842 00:43:02,330 --> 00:43:03,430 谁知道那里有什么? 843 00:43:03,430 --> 00:43:07,160 这是残存使用的位 以前的一些行代码 844 00:43:07,160 --> 00:43:08,300 我的计划。 845 00:43:08,300 --> 00:43:13,250 >> 所以,如果我说去那里,这是什么样子, 我不知道这个箭头 846 00:43:13,250 --> 00:43:14,490 要结束了。 847 00:43:14,490 --> 00:43:17,720 这时候你通常 得到分割故障。 848 00:43:17,720 --> 00:43:22,430 如果你不小心取消引用,所以 说话,还是去这不是一个地址 849 00:43:22,430 --> 00:43:25,400 实际上是一个合法的地址, 不好的事情发生。 850 00:43:25,400 --> 00:43:27,550 >> 这到底发生了什么 宾基认为。 851 00:43:27,550 --> 00:43:31,060 所以记得尼克的故事 这里讲的是同样的想法什么 852 00:43:31,060 --> 00:43:34,050 我画的错觉 粉笔在黑板上板。 853 00:43:34,050 --> 00:43:35,960 X和Y宣布。 854 00:43:35,960 --> 00:43:39,690 >> 然后我们分配的大小 一个int,并把它保存在x。 855 00:43:39,690 --> 00:43:42,130 然后我们所做的下一行* X。 856 00:43:42,130 --> 00:43:46,070 这是尼克的魔杖 提领。 857 00:43:46,070 --> 00:43:49,780 这把42在存储器 指出由x。 858 00:43:49,780 --> 00:43:51,600 >> 但是,这是东西 去可怕的错误。 859 00:43:51,600 --> 00:43:51,820 对吗? 860 00:43:51,820 --> 00:43:53,550 试图取消引用Ÿ。 861 00:43:53,550 --> 00:43:55,620 但Y有一些虚假的价值,对不对? 862 00:43:55,620 --> 00:43:57,720 >> 在左下方即箭头 角落里,是不是 863 00:43:57,720 --> 00:43:58,950 其实都指向任何东西。 864 00:43:58,950 --> 00:44:01,520 这是一种做什么,我 在这里做的在黑板上。 865 00:44:01,520 --> 00:44:05,900 如此糟糕的事情发生,分割 故障时,或宾基故障,在这种情况下。 866 00:44:05,900 --> 00:44:10,800 >> 但是,如果我们再解决,通过做x 得到Ÿ的故事是如何变化的呢? 867 00:44:10,800 --> 00:44:15,760 嗯,如果我做X得到Y,这是 同样有效的话说 868 00:44:15,760 --> 00:44:19,235 不管这是牛的东西 这里是相同的, 869 00:44:19,235 --> 00:44:20,080 牛年的东西。 870 00:44:20,080 --> 00:44:22,970 或者形象,我们将绘制一个箭头。 871 00:44:22,970 --> 00:44:25,530 >> 所以在这里宾基板, 的下一行 872 00:44:25,530 --> 00:44:28,350 代码* y表示去那里。 873 00:44:28,350 --> 00:44:29,400 哪里有? 874 00:44:29,400 --> 00:44:30,820 这意味着在这里。 875 00:44:30,820 --> 00:44:36,050 >> 而当我们更新到13 它只是涉及到要和 876 00:44:36,050 --> 00:44:39,470 写13现在在这里。 877 00:44:39,470 --> 00:44:44,130 因此,也许不完全 乍一看简单。 878 00:44:44,130 --> 00:44:47,740 但总括来说,并使用相同的行话 宾基是用在这里,所以 879 00:44:47,740 --> 00:44:50,485 前两个分配的指针, x和y,但不是指针对象。 880 00:44:50,485 --> 00:44:54,750 指针对象是不是一个 通常使用的术语。 881 00:44:54,750 --> 00:44:56,120 但指针绝对是。 882 00:44:56,120 --> 00:44:59,200 但究竟是什么原因被指向 在宾基命名。 883 00:44:59,200 --> 00:45:01,660 >> 这下一行,当然 分配一个int pointee的。 884 00:45:01,660 --> 00:45:04,840 所以一大块内存 - 因为我吸引了 右手侧 - 集 885 00:45:04,840 --> 00:45:06,470 x等于指向它。 886 00:45:06,470 --> 00:45:11,350 这解引用x到存储42 内存,它的指向。 887 00:45:11,350 --> 00:45:13,380 然后,当然,这 是一件坏事。 888 00:45:13,380 --> 00:45:15,600 因为Y并不是指向 任何东西。 889 00:45:15,600 --> 00:45:16,530 这修复它。 890 00:45:16,530 --> 00:45:18,240 因此,这仍是错误的程序。 891 00:45:18,240 --> 00:45:21,580 只是因为我们正在吹遍 代码一行行,并说,很不错哦, 892 00:45:21,580 --> 00:45:22,690 让它崩溃。 893 00:45:22,690 --> 00:45:23,420 这是一件坏事。 894 00:45:23,420 --> 00:45:26,790 赔率是程序只是要 完全中止在该行。 895 00:45:26,790 --> 00:45:30,550 但是,如果你要删除坠毁 排队,取而代之的是与过去两年 896 00:45:30,550 --> 00:45:32,470 线等也有你分配 - 897 00:45:32,470 --> 00:45:35,310 使用指针赋值 - γ 指向x作为点t。 898 00:45:35,310 --> 00:45:39,280 然后你取 y在一个非常安全的方式。 899 00:45:39,280 --> 00:45:41,520 >> 那么,这给我们吗? 900 00:45:41,520 --> 00:45:45,350 嗯,事实证明,引擎盖下 的CS50库中,指针是 901 00:45:45,350 --> 00:45:46,320 用于整个。 902 00:45:46,320 --> 00:45:48,910 实际上,我们将开始剥离 没过多久回那层。 903 00:45:48,910 --> 00:45:51,740 但事实证明,一个表达式, 一些你可能很熟悉, 904 00:45:51,740 --> 00:45:54,580 特别是那些更舒适, 实际上是一个非常受欢迎的 905 00:45:54,580 --> 00:45:56,390 网站,或者堆栈溢出, 这些天。 906 00:45:56,390 --> 00:45:58,720 >> 但是,这实际上有很 技术含义。 907 00:45:58,720 --> 00:46:00,160 我们现在知道堆栈是什么。 908 00:46:00,160 --> 00:46:02,550 这就像一摞托盘 内的食堂。 909 00:46:02,550 --> 00:46:05,140 >> 或您的计算机内的 内存它的那些帧 910 00:46:05,140 --> 00:46:06,900 所使用的功能。 911 00:46:06,900 --> 00:46:10,760 嗯,事实证明,正因为如此 非常简单的实现 912 00:46:10,760 --> 00:46:14,970 所谓的存储器和帧 叠加,实际上你可以控制 913 00:46:14,970 --> 00:46:17,050 一个计算机系统相当容易。 914 00:46:17,050 --> 00:46:22,180 你能砍成一个系统,如果人们 像我们这样没有写我们的代码 915 00:46:22,180 --> 00:46:23,300 特别好。 916 00:46:23,300 --> 00:46:26,670 >> 如果像我们这样的人用大块 内存或使用阵列 - 917 00:46:26,670 --> 00:46:27,810 更常见 - 918 00:46:27,810 --> 00:46:31,800 但有时会忘记检查 我们的数组的边界,你可能 919 00:46:31,800 --> 00:46:38,470 有自己的时候,迭代 路太远结束过去的一个数组。 920 00:46:38,470 --> 00:46:40,520 在最好的情况下,你的程序 可能只是崩溃。 921 00:46:40,520 --> 00:46:42,280 分割故障,善良 尴尬的。 922 00:46:42,280 --> 00:46:45,480 不是很大,但是它不一定 一个非常糟糕的事情。 923 00:46:45,480 --> 00:46:49,480 >> 但是,如果你的程序实际上是对真实 用户的计算机上,如果它的运行 924 00:46:49,480 --> 00:46:53,070 在网站上,实际随机人 在互联网上打,让 925 00:46:53,070 --> 00:46:56,690 人们引发不好的事情,对你的代码 一般不是一件好事,因为 926 00:46:56,690 --> 00:46:59,930 这意味着一个机会,采取 计算机的控制权。 927 00:46:59,930 --> 00:47:01,350 这是怎么回事看 有点神秘。 928 00:47:01,350 --> 00:47:04,570 但我想我会吓唬你 这里最后一个例子。 929 00:47:04,570 --> 00:47:05,650 >> 下面是一个例子的代码。 930 00:47:05,650 --> 00:47:07,370 维基百科有一个很好的 文章,走过 931 00:47:07,370 --> 00:47:08,530 这更多的细节。 932 00:47:08,530 --> 00:47:13,890 我有主的底部电话 富,1 argv中传递。 933 00:47:13,890 --> 00:47:15,750 而这仅仅是这样就可以了 运行程序,并通过 934 00:47:15,750 --> 00:47:17,080 任意输入。 935 00:47:17,080 --> 00:47:20,180 >> 然后foo被宣布往上顶 接受一个字符串,或者更 936 00:47:20,180 --> 00:47:21,700 准确地说,一个char *。 937 00:47:21,700 --> 00:47:23,860 然后声明一个字符数组。 938 00:47:23,860 --> 00:47:27,130 缓冲液,更一般地, 大小为12。 939 00:47:27,130 --> 00:47:30,900 所以,可以装进12个字符 该数组名为c。 940 00:47:30,900 --> 00:47:33,510 >> 然后,它使用这个新功能, 这是新的,但并不难 941 00:47:33,510 --> 00:47:34,930 理解,记忆复制。 942 00:47:34,930 --> 00:47:39,290 将内存复制吧,这是 过去的变量N,无论 943 00:47:39,290 --> 00:47:42,080 用户输入到argv 1到c。 944 00:47:42,080 --> 00:47:43,090 多少个字节? 945 00:47:43,090 --> 00:47:44,260 的字符串长度酒吧。 946 00:47:44,260 --> 00:47:48,380 >> 因此,换句话说,如果用户键入的 H-E-L-L-o输入字符串的长度 947 00:47:48,380 --> 00:47:49,260 你好五。 948 00:47:49,260 --> 00:47:52,790 所以五个那些字节是会得到 复制到阵列名为c, 949 00:47:52,790 --> 00:47:54,110 大小为12。 950 00:47:54,110 --> 00:47:58,710 但是,什么类型的用户在更长 这是13个字符或14字 951 00:47:58,710 --> 00:48:01,250 字符或100个或更多字符? 952 00:48:01,250 --> 00:48:02,660 >> 他们要去哪里去了? 953 00:48:02,660 --> 00:48:06,090 嗯,这架,托盘 在用餐大厅堆栈, 954 00:48:06,090 --> 00:48:06,930 他们去那里。 955 00:48:06,930 --> 00:48:10,080 它只是将开始覆盖 其他的东西,这已经 956 00:48:10,080 --> 00:48:12,880 该堆栈上,满溢 栈,可以这么说。 957 00:48:12,880 --> 00:48:14,780 >> 因此,形象,认为这种方式。 958 00:48:14,780 --> 00:48:17,970 这仅仅是一个多彩版 图片中,我们一直在画画。 959 00:48:17,970 --> 00:48:20,060 在底部,让我们说,是主要的。 960 00:48:20,060 --> 00:48:24,690 和顶部,你现在看到的 的帧,颜色编码,对于一个 961 00:48:24,690 --> 00:48:26,090 名为foo的功能。 962 00:48:26,090 --> 00:48:30,170 但是,什么是有趣的,在这里对 foo是,这里是它的框架。 963 00:48:30,170 --> 00:48:32,860 所以,就像我画 没有,但在淡蓝色的。 964 00:48:32,860 --> 00:48:35,220 现在这是 Ç支架0去。 965 00:48:35,220 --> 00:48:37,410 这是其中c支架 11要结束了。 966 00:48:37,410 --> 00:48:39,670 >> 换句话说,它发生在 被表示为一个正方形。 967 00:48:39,670 --> 00:48:42,320 但如果你只是保持扑通字节 - 煤焦 - 他们将结束 968 00:48:42,320 --> 00:48:46,070 位置0一路上扬 0到11,因为它是建立索引。 969 00:48:46,070 --> 00:48:49,170 >> 但如果是13个字符 要结束了吗? 970 00:48:49,170 --> 00:48:50,310 14日在哪里? 971 00:48:50,310 --> 00:48:52,430 50字符在哪里 要结束了吗? 972 00:48:52,430 --> 00:48:54,070 >> 这将继续下去。 973 00:48:54,070 --> 00:48:57,350 因为即使我们已经得出了 图片与堆栈长大, 974 00:48:57,350 --> 00:48:59,920 事实证明,地址,从 小的地址,小 975 00:48:59,920 --> 00:49:01,830 指针,大的地址。 976 00:49:01,830 --> 00:49:03,540 因此,它只是不断向上和向上。 977 00:49:03,540 --> 00:49:05,660 >> 因此,如果用户键入 你好,这是伟大的。 978 00:49:05,660 --> 00:49:08,650 没有错误,没有问题,每个人的安全。 979 00:49:08,650 --> 00:49:11,940 但是,如果我们的用户类型 调用对抗性的代码,代表 980 00:49:11,940 --> 00:49:16,040 统称为,攻击,攻击, 发作,发作时,会发生什么? 981 00:49:16,040 --> 00:49:19,760 >> 好了,如果所有的输入,用户 键入不只是一些友好 982 00:49:19,760 --> 00:49:21,540 或令人反感的一串字符。 983 00:49:21,540 --> 00:49:24,050 它实际上是一个字符序列 如果你编译它, 984 00:49:24,050 --> 00:49:26,050 它实际上是代码。 985 00:49:26,050 --> 00:49:29,570 也许这是代码,删除所有 您的硬盘驱动器上的文件或发送垃圾邮件 986 00:49:29,570 --> 00:49:30,810 或类似的东西。 987 00:49:30,810 --> 00:49:35,110 请注意,这里的关键是, 如果坏家伙得到了足够幸运 988 00:49:35,110 --> 00:49:37,830 覆盖红色的内存块 - 989 00:49:37,830 --> 00:49:41,080 我没有画上我的照片,但 这个维基百科的图片在这里 - 990 00:49:41,080 --> 00:49:42,890 其所谓的返回地址。 991 00:49:42,890 --> 00:49:47,470 >> 当食品的回报,掉期回报时, 电脑知道如何去从 992 00:49:47,470 --> 00:49:49,790 这里这里? 993 00:49:49,790 --> 00:49:52,920 或者在高科技板块上面,如何 它知道去从交换 994 00:49:52,920 --> 00:49:54,870 代码 - 0和1的 构成掉期 - 995 00:49:54,870 --> 00:49:56,020 回到主? 996 00:49:56,020 --> 00:50:00,450 有一个所谓的返回地址 存储在相同的堆栈帧,在 997 00:50:00,450 --> 00:50:02,140 同一食堂盘。 998 00:50:02,140 --> 00:50:06,080 >> 因此,如果坏家伙是足够聪明, 把攻击代码,攻击代码,攻击 999 00:50:06,080 --> 00:50:07,960 代码,并获得足够幸运 - 1000 00:50:07,960 --> 00:50:11,630 往往是通过试验和错误 - 覆盖,红色返回地址, 1001 00:50:11,630 --> 00:50:14,360 的地址和通知 极顶。 1002 00:50:14,360 --> 00:50:16,830 注意0835C080。 1003 00:50:16,830 --> 00:50:20,650 倒着写往上顶 原因也许我们会重新审视。 1004 00:50:20,650 --> 00:50:22,050 这是这个数字。 1005 00:50:22,050 --> 00:50:25,790 >> 因此,如果坏家伙得到足够幸运或 足够聪明,红色覆盖 1006 00:50:25,790 --> 00:50:29,480 剥离用的地址的存储器 他或她有某种代码 1007 00:50:29,480 --> 00:50:34,980 注入到你的电脑,你猜的 代码将被返回到 1008 00:50:34,980 --> 00:50:38,260 富尽快执行完? 1009 00:50:38,260 --> 00:50:39,440 >> 坏家伙的代码。 1010 00:50:39,440 --> 00:50:43,610 因此,这种攻击代码,AAA,再次,可能 发送垃圾邮件,可能会删除所有文件 1011 00:50:43,610 --> 00:50:44,500 您的硬盘驱动器上。 1012 00:50:44,500 --> 00:50:48,740 但是,这是一个真正的堆栈溢出 或缓冲区溢出,或 1013 00:50:48,740 --> 00:50:51,060 缓冲区溢出攻击。 1014 00:50:51,060 --> 00:50:54,400 >> 这是令人难以置信的,令人难以置信的普遍 这一天,编写的程序 1015 00:50:54,400 --> 00:50:58,220 C,C + +,甚至还有一些其他的语言。 1016 00:50:58,220 --> 00:51:02,275 在那个可怕的音符,我们将 结束一个笑话。 1017 00:51:02,275 --> 00:51:03,230 >> [笑] 1018 00:51:03,230 --> 00:51:04,550 >> 星期三见。 1019 00:51:04,550 --> 00:51:07,920 1020 00:51:07,920 --> 00:51:10,310 于下CS50 - 1021 00:51:10,310 --> 00:51:15,920 所以,我所有的磁盘灯,但今天 等待,无脂牛奶,有一半的手机 1022 00:51:15,920 --> 00:51:17,850 书,橙汁 今天我喝。 1023 00:51:17,850 --> 00:51:20,370 1024 00:51:20,370 --> 00:51:22,780 USB连接线,一个扳手。 1025 00:51:22,780 --> 00:51:24,800 >> [音乐播放]