1 00:00:00,000 --> 00:00:10,970 >> [音乐播放] 2 00:00:10,970 --> 00:00:12,536 >> DAVID J.马兰所有权利。 3 00:00:12,536 --> 00:00:13,392 >> [笑] 4 00:00:13,392 --> 00:00:14,240 >> 欢迎回来。 5 00:00:14,240 --> 00:00:14,990 这是CS50。 6 00:00:14,990 --> 00:00:16,890 而本周五结束。 7 00:00:16,890 --> 00:00:20,020 到现在为止,我们已经差不多 被理所当然地认为有 8 00:00:20,020 --> 00:00:23,480 存在这个编译器,铛,你 被调用的方式,此 9 00:00:23,480 --> 00:00:27,100 其他工具叫,不知怎的, 神奇地转换你的源代码 10 00:00:27,100 --> 00:00:31,350 成目标代码,零和一 您的电脑CPU,中央 11 00:00:31,350 --> 00:00:33,410 处理单元,真正理解。 12 00:00:33,410 --> 00:00:36,770 但事实证明,这是一个数字 在引擎盖下 13 00:00:36,770 --> 00:00:38,690 输入和输出之间。 14 00:00:38,690 --> 00:00:41,800 >> 我想建议,我们的肉体 说出来的更详细一点成 15 00:00:41,800 --> 00:00:45,130 这四个步骤,有一些所谓 前处理,这 16 00:00:45,130 --> 00:00:48,300 被称为编译,我们已经看到, 一些所谓的组装, 17 00:00:48,300 --> 00:00:49,420 一种叫做连接。 18 00:00:49,420 --> 00:00:53,270 所以到现在为止,在我们的一些 计划,我们已经包含尖锐。 19 00:00:53,270 --> 00:00:56,650 最近,我们已经有一些尖锐的 定义常量。 20 00:00:56,650 --> 00:01:00,660 所以,事实证明,那些东西, 哈希符号或前缀 21 00:01:00,660 --> 00:01:04,150 英镑符号是预处理器 指令。 22 00:01:04,150 --> 00:01:07,960 这只是说这是一个奇特的方式 这实际上一行代码 23 00:01:07,960 --> 00:01:12,280 转换成别的东西之前 电脑甚至尝试转换 24 00:01:12,280 --> 00:01:13,800 成0和1的程序。 25 00:01:13,800 --> 00:01:19,000 >> 例如,夏普包括标准 I / O,H,非常简单,只是表示去 26 00:01:19,000 --> 00:01:24,010 未来,抢的文件内容 STDIO.H并粘贴他们的权利有。 27 00:01:24,010 --> 00:01:25,880 因此,没有零和一 但在这一点上。 28 00:01:25,880 --> 00:01:27,470 这真的只是一个替代。 29 00:01:27,470 --> 00:01:30,790 这样做了,在所谓的 预处理阶段,当你 30 00:01:30,790 --> 00:01:34,230 实际运行锵或专门 在大多数情况下,制作。 31 00:01:34,230 --> 00:01:36,950 所以这一切已经发生 首先自动迄今。 32 00:01:36,950 --> 00:01:38,800 >> 然后编译步骤。 33 00:01:38,800 --> 00:01:40,920 但是,我们一直过于简单化 编译。 34 00:01:40,920 --> 00:01:45,060 编译程序的真正含义 把它从像C的东西, 35 00:01:45,060 --> 00:01:48,430 源代码中,我们一直都在写,同比下降 一种叫做组装。 36 00:01:48,430 --> 00:01:52,900 汇编语言是一个较低的水平 语言,令人欣慰的是,我们不会 37 00:01:52,900 --> 00:01:55,480 有很多借势 写这个学期。 38 00:01:55,480 --> 00:01:59,100 但它的最低水平 某种意义上说,你从字面上开始写 39 00:01:59,100 --> 00:02:04,270 加法和减法,乘法和加载 从内存中保存到内存中, 40 00:02:04,270 --> 00:02:08,259 非常基本的指令,一台电脑, 引擎盖下, 41 00:02:08,259 --> 00:02:09,639 其实理解。 42 00:02:09,639 --> 00:02:14,930 >> 最后,组装需要语言 零和的,我们已经 43 00:02:14,930 --> 00:02:16,190 迄今为止描述。 44 00:02:16,190 --> 00:02:19,270 最后,真正有所谓 链接阶段,我们将 45 00:02:19,270 --> 00:02:22,360 看到在短短的时刻,它结合了 您的零和一零 46 00:02:22,360 --> 00:02:24,870 其他的人之前 你已经创建。 47 00:02:24,870 --> 00:02:26,660 >> 所以考虑这个超级简单的程序。 48 00:02:26,660 --> 00:02:27,560 它是从第1周。 49 00:02:27,560 --> 00:02:29,610 它只是说,你好世界, 在屏幕上。 50 00:02:29,610 --> 00:02:30,920 我们跑通过锵。 51 00:02:30,920 --> 00:02:33,200 或者我们跑了,它通过使 跑锵。 52 00:02:33,200 --> 00:02:36,170 和输出在当时 一些零和一。 53 00:02:36,170 --> 00:02:38,100 但事实证明,有 一个中间步骤。 54 00:02:38,100 --> 00:02:40,460 如果我在这里 - 哎呀,没 希望看到他呢。 55 00:02:40,460 --> 00:02:44,800 如果我在这里,我的设备 我打开hello.c的,在这里 56 00:02:44,800 --> 00:02:46,160 是相同的程序。 57 00:02:46,160 --> 00:02:48,600 什么,我要做的事情在我的终端 窗口在这里我要 58 00:02:48,600 --> 00:02:51,430 运行铛,而不是品牌, 自动完成所有四个 59 00:02:51,430 --> 00:02:52,870 我们这些步骤。 60 00:02:52,870 --> 00:02:58,620 我打算做铛-S 然后hello.c的,然后回车。 61 00:02:58,620 --> 00:03:00,590 >> 我得到一个闪烁提示 再次,这是很好的。 62 00:03:00,590 --> 00:03:05,280 现在稍大一点的窗口, 我要打开的gedit这里。 63 00:03:05,280 --> 00:03:09,610 我要打开的文件, 事实证明,被称为hello.s 64 00:03:09,610 --> 00:03:11,870 包含该汇编语言 我前面提到的。 65 00:03:11,870 --> 00:03:15,060 这是什么所谓的装配 语言,相当低的水平 66 00:03:15,060 --> 00:03:18,470 英特尔CPU的指令, 或不管它是什么,里面 67 00:03:18,470 --> 00:03:19,350 理解。 68 00:03:19,350 --> 00:03:24,480 和MOV举动。呼叫是 调用,非常低的水平的功能。 69 00:03:24,480 --> 00:03:26,380 子的减法。 70 00:03:26,380 --> 00:03:30,370 >> 所以当你有一个特定的CPU里面 你的电脑,是什么使得它 71 00:03:30,370 --> 00:03:34,300 层次分明,与其它CPU上 市场,指示 72 00:03:34,300 --> 00:03:39,460 理解,往往它的效率有多高 有多快,它是在执行某些 73 00:03:39,460 --> 00:03:40,380 这些指令。 74 00:03:40,380 --> 00:03:45,150 现在更多,你可以采取 明年秋季在大学CS61。 75 00:03:45,150 --> 00:03:48,170 但在这里,我们有,例如,几 标识符可能看起来很熟悉。 76 00:03:48,170 --> 00:03:50,150 hello.c的程序的名称。 77 00:03:50,150 --> 00:03:51,070 >> 文本 - 。 78 00:03:51,070 --> 00:03:54,190 有没有更多的兴趣 刚才,记得该文本 79 00:03:54,190 --> 00:03:59,190 段,截至周一,是在 内存的程序实际上结束了。 80 00:03:59,190 --> 00:04:01,330 所以,这至少隐约 有熟悉。 81 00:04:01,330 --> 00:04:03,730 在这里,当然,一提 我们的主要功能。 82 00:04:03,730 --> 00:04:07,220 向下滚动,这是指对事物 所谓的寄存器,非常小块 83 00:04:07,220 --> 00:04:09,190 您的实际CPU的内存里面。 84 00:04:09,190 --> 00:04:12,930 如果我什至向下滚动 进一步,我看到某种 85 00:04:12,930 --> 00:04:14,240 间接提及ASCII。 86 00:04:14,240 --> 00:04:17,120 还有,的确是字符串, 你好,逗号,世界。 87 00:04:17,120 --> 00:04:20,079 >> 所以长话短说,这一直是 发生自动为您 88 00:04:20,079 --> 00:04:22,140 在发动机罩下方的这段时间。 89 00:04:22,140 --> 00:04:26,450 什么已经发生,真的是一次 你运行铛,或以 90 00:04:26,450 --> 00:04:29,150 让你得到第一, 从源代码, 91 00:04:29,150 --> 00:04:30,700 所谓的汇编语言。 92 00:04:30,700 --> 00:04:35,210 然后锵转换组件 下降到零和的语言。 93 00:04:35,210 --> 00:04:38,340 这是我们开始的幻灯片 我们讨论周0 - 94 00:04:38,340 --> 00:04:39,840 然后1周。 95 00:04:39,840 --> 00:04:44,030 最后,那些零和一 相结合,与零和一 96 00:04:44,030 --> 00:04:47,190 这些库中,我们一直在服用 标准I / O或理所当然的像 97 00:04:47,190 --> 00:04:50,010 字符串库,甚至 的CS50库。 98 00:04:50,010 --> 00:04:54,200 >> 所以画这幅画 在视觉上,我们有hello.c的。 99 00:04:54,200 --> 00:04:57,220 而且,当然,使用了printf 功能说,你好世界。 100 00:04:57,220 --> 00:05:01,810 编译步骤下来 该文件,我们刚才看到hello.s,甚至 101 00:05:01,810 --> 00:05:04,290 虽然这通常将删除 自动为您。 102 00:05:04,290 --> 00:05:06,050 但是,这是在汇编代码 在中间步骤。 103 00:05:06,050 --> 00:05:09,750 那么当我们组装的组件 语言,可以这么说,这就是当你 104 00:05:09,750 --> 00:05:10,830 得到这些零和一。 105 00:05:10,830 --> 00:05:13,920 因此,我们今天有效放大 我们一直理所当然, 106 00:05:13,920 --> 00:05:16,430 意味着源代码 反对代码。 107 00:05:16,430 --> 00:05:18,850 >> 但最后,现在相同的画面 - 让我们推到 108 00:05:18,850 --> 00:05:20,020 左手侧。 109 00:05:20,020 --> 00:05:22,880 并注意在上方有 我前面提到stdio.h中。 110 00:05:22,880 --> 00:05:25,030 这是一个文件,我们已经包括了 在几乎所有的 111 00:05:25,030 --> 00:05:26,250 我们写的程序。 112 00:05:26,250 --> 00:05:28,830 的文件,其内容 获得复制粘贴, 113 00:05:28,830 --> 00:05:30,350 有效之上代码。 114 00:05:30,350 --> 00:05:34,170 但事实证明,在计算机上 系统某处,那里想必 115 00:05:34,170 --> 00:05:39,150 有人写道多年stdio.c文件 以前,实现了所有的 116 00:05:39,150 --> 00:05:41,870 被宣布功能 在stdio.h。 117 00:05:41,870 --> 00:05:45,465 >> 现在,在现实中它可能不上 您的Mac或PC或者甚至在 118 00:05:45,465 --> 00:05:47,660 CS50设备是一个原始的C代码。 119 00:05:47,660 --> 00:05:52,710 有人已经编译并计入 o文件对象代码或一个 120 00:05:52,710 --> 00:05:56,020 文件,它指的是一个共享库 这已预装和 121 00:05:56,020 --> 00:05:57,240 预编译的为您服务。 122 00:05:57,240 --> 00:06:01,950 但是,假如确实存在 上我们的电脑stdio.c的并行 123 00:06:01,950 --> 00:06:02,650 铛。 124 00:06:02,650 --> 00:06:04,960 你的代码被编译 和组装。 125 00:06:04,960 --> 00:06:09,200 stdio.c代码被编译和 组装,以便将该最后 126 00:06:09,200 --> 00:06:13,730 一步,在这里,我们必须以某种方式 链接,可以这么说,你的零和一 127 00:06:13,730 --> 00:06:18,430 用他或她的零和一成一体 简单的程序,最终是 128 00:06:18,430 --> 00:06:20,540 调用你好。 129 00:06:20,540 --> 00:06:23,340 >> 所以这是所有魔法 发生迄今。 130 00:06:23,340 --> 00:06:26,430 并会继续采取这些 过程是理所当然的,但实现 131 00:06:26,430 --> 00:06:28,750 有很多有趣的细节 下方有。 132 00:06:28,750 --> 00:06:31,920 这是什么使你 电脑与英特尔里面 133 00:06:31,920 --> 00:06:33,940 特别显着。 134 00:06:33,940 --> 00:06:37,020 >> 因此,关于这一点,如果你想 我们一起吃午饭这个星期五,做 135 00:06:37,020 --> 00:06:41,570 到一般地方cs50.net/rsvp, 周五下午1:15。 136 00:06:41,570 --> 00:06:43,400 而现在的几个公告。 137 00:06:43,400 --> 00:06:44,670 因此,我们有一些好消息。 138 00:06:44,670 --> 00:06:45,970 我们有一些坏消息。 139 00:06:45,970 --> 00:06:47,260 开始这里有一些好消息。 140 00:06:47,260 --> 00:06:52,038 141 00:06:52,038 --> 00:06:54,510 >> [呻吟] 142 00:06:54,510 --> 00:06:54,710 >> 好的。 143 00:06:54,710 --> 00:06:56,670 嗯,这是技术上的一个假期,所以 它没有这么多我们的礼物。 144 00:06:56,670 --> 00:06:58,030 但随后的坏消息,当然。 145 00:06:58,030 --> 00:07:00,550 146 00:07:00,550 --> 00:07:01,880 >> [呻吟] 147 00:07:01,880 --> 00:07:03,530 >> 我花了很多的时间 这些动画。 148 00:07:03,530 --> 00:07:04,690 >> [笑] 149 00:07:04,690 --> 00:07:07,000 >> 会有一个审查会议 下星期一。 150 00:07:07,000 --> 00:07:08,340 这将是下午5:30。 151 00:07:08,340 --> 00:07:11,210 所有这些细节,我们会提醒你 通过电子邮件在球场上的 152 00:07:11,210 --> 00:07:13,470 网站在短短两天时间。 153 00:07:13,470 --> 00:07:16,610 将被拍摄下来,并提供 此后不久。 154 00:07:16,610 --> 00:07:19,200 所以,如果你不能让周一 夜间插槽,不用担心。 155 00:07:19,200 --> 00:07:22,270 第接下来的一周也将 专注于审查测验。 156 00:07:22,270 --> 00:07:25,670 如果你的部分是,这是在周一 确实是大学的假期,我们将 157 00:07:25,670 --> 00:07:26,920 仍然满足部分。 158 00:07:26,920 --> 00:07:28,890 如果你根本无法使该 因为你会一节 159 00:07:28,890 --> 00:07:29,860 离开,这很好。 160 00:07:29,860 --> 00:07:33,710 出席星期日或周二部分或 调贾森的部分,这是 161 00:07:33,710 --> 00:07:35,110 网上提供。 162 00:07:35,110 --> 00:07:37,490 >> 所以,更多的坏消息。 163 00:07:37,490 --> 00:07:41,960 因此,根据教学大纲, 我们有讲座将于下周五。 164 00:07:41,960 --> 00:07:43,690 但好消息 - 165 00:07:43,690 --> 00:07:44,860 清楚,我花了太多时间。 166 00:07:44,860 --> 00:07:45,280 >> [笑] 167 00:07:45,280 --> 00:07:47,140 >> 我们将在下周五的讲座取消。 168 00:07:47,140 --> 00:07:50,590 所以这将是一个为我们的礼物,所以你 真的可以有一个很好的喘息 169 00:07:50,590 --> 00:07:52,990 这个星期,两个星期,因此之间。 170 00:07:52,990 --> 00:07:57,460 因此,没有讲座下周,只是一个很小的 小测验,你应该 171 00:07:57,460 --> 00:07:59,030 越来越兴奋。 172 00:07:59,030 --> 00:08:03,870 >> 现在让我们把注意力转向 东西确实是更多的视觉 173 00:08:03,870 --> 00:08:06,990 更加精彩和设置阶段 这是怎么回事,在地平线上 174 00:08:06,990 --> 00:08:08,420 在短短的几个星期的时间。 175 00:08:08,420 --> 00:08:12,160 第一次测验后,我们将把 关注我们的问题集 176 00:08:12,160 --> 00:08:16,710 特定领域的问题,即 取证或安全性比较一般。 177 00:08:16,710 --> 00:08:19,550 >> 事实上,这个问题的传统 集对我来说是一个 178 00:08:19,550 --> 00:08:24,850 教学资深会员​​或CAS走过 校园采取一些照片 179 00:08:24,850 --> 00:08:29,450 可识别的,但无明显的人, 地方或事物,那么每年我 180 00:08:29,450 --> 00:08:34,520 设法不小心删除 或破坏数字媒体卡 181 00:08:34,520 --> 00:08:35,720 这是我们的相机内。 182 00:08:35,720 --> 00:08:36,860 但没什么大不了的。 183 00:08:36,860 --> 00:08:39,200 我可以继续前进,堵塞 进入我的电脑。 184 00:08:39,200 --> 00:08:43,010 我可以做一个法医形象,所以 说话,复制零 185 00:08:43,010 --> 00:08:46,830 该内存卡的,不论是 其SD卡或紧凑型闪存卡或 186 00:08:46,830 --> 00:08:48,100 无论你是熟悉的。 187 00:08:48,100 --> 00:08:49,300 然后我们就可以到手了。 188 00:08:49,300 --> 00:08:53,190 >> 因此,挑战未来,除其他 你的东西,是写 189 00:08:53,190 --> 00:08:58,630 恢复了一大堆的C代码, 我的JPEG文件,并透露将 190 00:08:58,630 --> 00:09:00,190 那些人,地方或事物。 191 00:09:00,190 --> 00:09:03,340 而且我们还说话,在这个问题上 设置,并在未来的日子里,约 192 00:09:03,340 --> 00:09:04,440 更普遍的图形。 193 00:09:04,440 --> 00:09:06,140 我们已经使用,当然, 打破了。 194 00:09:06,140 --> 00:09:09,080 不过,你那种理所当然的 存在这些高层概念 195 00:09:09,080 --> 00:09:10,680 矩形和椭圆形。 196 00:09:10,680 --> 00:09:12,450 但引擎盖下 有像素。 197 00:09:12,450 --> 00:09:14,370 你不得不开始 想着这些。 198 00:09:14,370 --> 00:09:18,800 或者你将P-集合4不得不思考 砖之间的差距,如何 199 00:09:18,800 --> 00:09:21,990 很快,你的球跨越 在屏幕打出来。 200 00:09:21,990 --> 00:09:24,830 所以有这样的概念 在屏幕上,这点 201 00:09:24,830 --> 00:09:26,290 已经开始发挥作用。 202 00:09:26,290 --> 00:09:29,430 >> 现在你所看到的,不过,是什么 你在电脑屏幕上。 203 00:09:29,430 --> 00:09:33,680 如果你曾经看过一些好的或 坏电视,赔率是他们几乎 204 00:09:33,680 --> 00:09:36,280 对待观众喜欢科技进步 谁真的不 205 00:09:36,280 --> 00:09:37,630 知道很多关于计算。 206 00:09:37,630 --> 00:09:40,840 因此,它很容易为​​警察 侦探说,你能不能 207 00:09:40,840 --> 00:09:41,710 清理一下我吗? 208 00:09:41,710 --> 00:09:42,710 或加强,对不对? 209 00:09:42,710 --> 00:09:45,550 Enhance是一样的时髦词语 任何犯罪行为最相关的节目。 210 00:09:45,550 --> 00:09:49,240 而现实的情况是,如果你把一个非常 犯罪嫌疑人在做的模糊照片 211 00:09:49,240 --> 00:09:51,620 坏的东西,你不能 只是增强。 212 00:09:51,620 --> 00:09:53,080 你不能无限放大。 213 00:09:53,080 --> 00:09:56,350 你不能看到有人在闪烁 谁犯的眼 214 00:09:56,350 --> 00:09:59,860 特别是犯罪,尽管 患病率在电视上。 215 00:09:59,860 --> 00:10:04,110 >> 因此,让的激励 一窥即将到来的设置问题 216 00:10:04,110 --> 00:10:05,765 一些演出与您 可能是熟悉的。 217 00:10:05,765 --> 00:10:06,500 >> [视频回放] 218 00:10:06,500 --> 00:10:07,835 >> - 确定。 219 00:10:07,835 --> 00:10:09,956 现在,让我们好好看看你。 220 00:10:09,956 --> 00:10:17,060 221 00:10:17,060 --> 00:10:17,766 >> 保持它。 222 00:10:17,766 --> 00:10:18,658 执行回来。 223 00:10:18,658 --> 00:10:19,550 >> 等待一分钟。 224 00:10:19,550 --> 00:10:21,580 向右走。 225 00:10:21,580 --> 00:10:21,800 >> 有。 226 00:10:21,800 --> 00:10:22,690 冻结。 227 00:10:22,690 --> 00:10:23,692 >> 全屏。 228 00:10:23,692 --> 00:10:23,846 >> - 确定。 229 00:10:23,846 --> 00:10:24,154 冻结。 230 00:10:24,154 --> 00:10:25,140 >> 收紧,好吗? 231 00:10:25,140 --> 00:10:27,090 >> 在那家伙的矢量 由后轮。 232 00:10:27,090 --> 00:10:29,730 >> 放大在这里,在这一点上。 233 00:10:29,730 --> 00:10:33,700 >> 有了合适的设备,成像 可扩大和激化。 234 00:10:33,700 --> 00:10:34,490 >> - 那是什么? 235 00:10:34,490 --> 00:10:35,870 >> 这是一个提升计划。 236 00:10:35,870 --> 00:10:36,793 >> 你能清除的任何? 237 00:10:36,793 --> 00:10:38,560 >> 我不知道。 238 00:10:38,560 --> 00:10:39,090 让的增强。 239 00:10:39,090 --> 00:10:41,690 >> 增强第A-6。 240 00:10:41,690 --> 00:10:43,510 >> 我增强了细节和 - 241 00:10:43,510 --> 00:10:44,456 >> 我认为有足够的提升。 242 00:10:44,456 --> 00:10:45,402 它释放到我的屏幕。 243 00:10:45,402 --> 00:10:47,300 >> 增强反映在她的眼睛。 244 00:10:47,300 --> 00:10:49,330 >> 让我们运行这个通过 视频增强。 245 00:10:49,330 --> 00:10:50,340 >> 埃德加,你可以加强这方面呢? 246 00:10:50,340 --> 00:10:52,320 >> 杭。 247 00:10:52,320 --> 00:10:54,290 >> - 我一直在这种反射。 248 00:10:54,290 --> 00:10:55,560 >> 有人的反思。 249 00:10:55,560 --> 00:10:56,440 >> 反思。 250 00:10:56,440 --> 00:10:57,940 >> - 有一个反射 男人的脸。 251 00:10:57,940 --> 00:10:58,860 >> - 反思。 252 00:10:58,860 --> 00:10:59,710 >> 有一种体现。 253 00:10:59,710 --> 00:11:00,900 >> 放大上镜。 254 00:11:00,900 --> 00:11:03,500 >> 你可以看到的一种体现。 255 00:11:03,500 --> 00:11:04,700 >> 你能提升形象,从这里开始? 256 00:11:04,700 --> 00:11:05,700 >> 你能提高他在这里? 257 00:11:05,700 --> 00:11:06,500 >> 你能提高呢? 258 00:11:06,500 --> 00:11:07,380 >> 你能提高呢? 259 00:11:07,380 --> 00:11:08,190 >> 我们可以加强这方面呢? 260 00:11:08,190 --> 00:11:08,940 >> 你能提高呢? 261 00:11:08,940 --> 00:11:10,280 >> 保持一秒钟,我会提高。 262 00:11:10,280 --> 00:11:11,570 >> - 放大在门上。 263 00:11:11,570 --> 00:11:12,180 >> - X10。 264 00:11:12,180 --> 00:11:13,052 >> 变焦。 265 00:11:13,052 --> 00:11:13,197 >> [笑] 266 00:11:13,197 --> 00:11:14,360 >> 移动英寸 267 00:11:14,360 --> 00:11:15,100 >> 等待,停止。 268 00:11:15,100 --> 00:11:15,740 >> - 停止。 269 00:11:15,740 --> 00:11:16,290 >> 暂停。 270 00:11:16,290 --> 00:11:19,390 >> 旋转75度左右 的立式请。 271 00:11:19,390 --> 00:11:19,886 >> [笑] 272 00:11:19,886 --> 00:11:24,350 >> 停止,和背部的部分 门再次。 273 00:11:24,350 --> 00:11:26,330 >> 得到的图像增强 ,位图? 274 00:11:26,330 --> 00:11:28,990 >> 也许我们可以使用普拉迪普森 进入windows的方法。 275 00:11:28,990 --> 00:11:30,680 >> 这个软件是最先进的。 276 00:11:30,680 --> 00:11:31,676 >> 的图标值是关闭的。 277 00:11:31,676 --> 00:11:34,166 >> 有了正确的组合 的算法。 278 00:11:34,166 --> 00:11:38,399 >> 他采取光照算法 一个新的水平,我可以用它们来 279 00:11:38,399 --> 00:11:38,648 增强这张照片。 280 00:11:38,648 --> 00:11:42,050 >> 锁和放大的z​​轴。 281 00:11:42,050 --> 00:11:42,760 >> - 增强。 282 00:11:42,760 --> 00:11:43,060 >> - 增强。 283 00:11:43,060 --> 00:11:43,760 >> - 增强。 284 00:11:43,760 --> 00:11:45,010 >> 冻结和提高。 285 00:11:45,010 --> 00:11:47,470 286 00:11:47,470 --> 00:11:47,910 >> [END视频播放] 287 00:11:47,910 --> 00:11:51,470 >> DAVID J.马兰:所以习题集 5是有什么样的未来。 288 00:11:51,470 --> 00:11:55,260 所以,我们很快就会得到一个更好的理解 的时候,为什么你可以 289 00:11:55,260 --> 00:11:57,300 我们不能以这种方式提高。 290 00:11:57,300 --> 00:12:00,090 但首先,让我们回到我们的注意力 一些积木,我们会 291 00:12:00,090 --> 00:12:02,250 需要能够讲这个故事。 292 00:12:02,250 --> 00:12:05,580 >> 所以记得我们画了这幅画上 周一有点上周。 293 00:12:05,580 --> 00:12:09,970 描述事物的布局 在您的计算机的内存中时, 294 00:12:09,970 --> 00:12:11,000 运行某些程序。 295 00:12:11,000 --> 00:12:14,310 高科技板块向上顶,召回,是指 实际的零和一 296 00:12:14,310 --> 00:12:16,000 构成你的程序。 297 00:12:16,000 --> 00:12:19,340 有,下面,一些初始化或 未初始化的数据,这通常 298 00:12:19,340 --> 00:12:22,910 指的东西像常量或 字符串或全局变量 299 00:12:22,910 --> 00:12:24,200 事先声明。 300 00:12:24,200 --> 00:12:26,500 还有的堆,但我们还会回来 回到那个在一个位。 301 00:12:26,500 --> 00:12:27,410 >> 再有就是在堆栈中。 302 00:12:27,410 --> 00:12:30,660 很像一个托盘堆叠在 食堂,这就是内存得到 303 00:12:30,660 --> 00:12:33,610 分层和分层时, 你做什么程序? 304 00:12:33,610 --> 00:12:36,380 305 00:12:36,380 --> 00:12:37,730 堆栈的使用是什么? 306 00:12:37,730 --> 00:12:39,320 >> 是吗? 307 00:12:39,320 --> 00:12:40,000 >> 调用的函数。 308 00:12:40,000 --> 00:12:42,890 任何时候当你调用一个函数,它 其内存条子给 309 00:12:42,890 --> 00:12:45,020 局部变量或参数。 310 00:12:45,020 --> 00:12:48,810 形象,我们看到,每个 连续的函数调用,当A 311 00:12:48,810 --> 00:12:52,520 调用B调用C调用D, 分层压入堆栈。 312 00:12:52,520 --> 00:12:55,630 和在每个这些片 存储器本质上是一个独特的范围 313 00:12:55,630 --> 00:12:58,590 该功能,当然 是有问题的,如果你想把手上 314 00:12:58,590 --> 00:13:01,850 从一个函数另一块 你想让它的数据 315 00:13:01,850 --> 00:13:03,500 到突变或更改。 316 00:13:03,500 --> 00:13:08,060 >> 那么,是什么使我们的解决方案 函数代表一个堆栈 317 00:13:08,060 --> 00:13:11,390 帧改变内存里面 另一个堆栈帧呢? 318 00:13:11,390 --> 00:13:14,590 怎么做这两彼此交谈? 319 00:13:14,590 --> 00:13:18,510 因此,通过指针或地址, 再次,只是描述的 320 00:13:18,510 --> 00:13:22,280 存储器,通过一个特定的 咬入号码“,特别是 321 00:13:22,280 --> 00:13:23,830 价值,可以发现。 322 00:13:23,830 --> 00:13:26,860 所以,记得最后一次,我们也继续 的故事,看了一眼 323 00:13:26,860 --> 00:13:28,280 相当错误的程序。 324 00:13:28,280 --> 00:13:32,900 这项计划是几车 的原因,但最令人担忧的是 325 00:13:32,900 --> 00:13:34,620 因为它无法检查什么? 326 00:13:34,620 --> 00:13:39,111 327 00:13:39,111 --> 00:13:40,450 >> 是啊,这不检查输入。 328 00:13:40,450 --> 00:13:41,870 对不起? 329 00:13:41,870 --> 00:13:43,880 >> 如果超过12个字符。 330 00:13:43,880 --> 00:13:47,260 所以非常巧妙,当调用存储器复制, 其中,顾名思义,就是 331 00:13:47,260 --> 00:13:50,630 将存储器从它的第二个参数 进入它的第一个参数。 332 00:13:50,630 --> 00:13:54,730 第三个参数,非常巧妙, 检查以确保你不 333 00:13:54,730 --> 00:13:59,400 复制多个,在这种情况下,长度 酒吧的字符数, 334 00:13:59,400 --> 00:14:03,810 到目标,这也是本 阵列C.但问题是什么 335 00:14:03,810 --> 00:14:07,230 如果C本身不够大 处理这个问题? 336 00:14:07,230 --> 00:14:09,900 你要复制的数量 你已经字节。 337 00:14:09,900 --> 00:14:13,040 可是你实际上有更多的 字节比你有房吗? 338 00:14:13,040 --> 00:14:16,770 >> 那么,这个程序非常愚蠢只是 盲目继续采取一切它 339 00:14:16,770 --> 00:14:20,650 ,你好反斜线0 伟大的,如果字符串是短 340 00:14:20,650 --> 00:14:22,040 够了,像5个字符。 341 00:14:22,040 --> 00:14:26,470 但是,如果它实际上是12个字符 1,200个字符,我们看到了最后一次 342 00:14:26,470 --> 00:14:29,380 ,你只是要完全 覆盖内存, 343 00:14:29,380 --> 00:14:30,470 不属于你。 344 00:14:30,470 --> 00:14:34,390 而最坏的情况下,如果覆盖 红色的部分,我们叫做 345 00:14:34,390 --> 00:14:35,380 返回地址 - 346 00:14:35,380 --> 00:14:38,370 这仅仅是其中计算机 自动为你,后面的 347 00:14:38,370 --> 00:14:43,130 场景,塔克斯走了32位值, 它提醒了什么地址,它应该 348 00:14:43,130 --> 00:14:47,080 返回时富,其他功能, 完成执行。 349 00:14:47,080 --> 00:14:49,320 这是一个各种各样的面包屑 它返回。 350 00:14:49,320 --> 00:14:52,490 如果覆盖潜在的, 如果你是坏人,可以 351 00:14:52,490 --> 00:14:54,750 潜在的接管 别人的电脑。 352 00:14:54,750 --> 00:14:58,020 你肯定 在大多数情况下崩溃。 353 00:14:58,020 --> 00:15:01,690 >> 现在,这个问题只会加剧 当我们开始谈论内存 354 00:15:01,690 --> 00:15:03,010 更普遍的管理。 355 00:15:03,010 --> 00:15:07,150 和malloc内存分配,是一种 我们可以用它来分配的功能, 356 00:15:07,150 --> 00:15:11,260 内存时,我们事先不知道 我们可能需要一些。 357 00:15:11,260 --> 00:15:13,960 因此,举例来说,如果我回去 这里器具。 358 00:15:13,960 --> 00:15:21,010 而且我打开从最后一次hello2.c, 记得这个节目在这里,看着 359 00:15:21,010 --> 00:15:23,500 像这样一个小东西, 短短三行 - 360 00:15:23,500 --> 00:15:27,940 说出你的名字,然后字符串名称, 在左边,等于的GetString。 361 00:15:27,940 --> 00:15:29,690 然后,我们把它打印出来, 该用户的名称。 362 00:15:29,690 --> 00:15:31,170 >> 因此,这是一个超级简单的程序。 363 00:15:31,170 --> 00:15:34,870 要清楚,让我继续前进 ,并招呼-2。 364 00:15:34,870 --> 00:15:36,680 我打算做点斜线HELLO-2。 365 00:15:36,680 --> 00:15:37,750 说出你的名字 - 366 00:15:37,750 --> 00:15:38,140 大卫。 367 00:15:38,140 --> 00:15:38,840 回车键。 368 00:15:38,840 --> 00:15:39,540 你好,戴维。 369 00:15:39,540 --> 00:15:41,060 它似乎确定工作。 370 00:15:41,060 --> 00:15:43,140 但是,什么是真的 这里引擎盖下方? 371 00:15:43,140 --> 00:15:44,670 首先,让我们剥开一些层。 372 00:15:44,670 --> 00:15:48,380 字符串只是一个代名词,我们已经 实现了什么? 373 00:15:48,380 --> 00:15:49,110 字符明星。 374 00:15:49,110 --> 00:15:52,740 因此,让我们让它多了几分神秘的 但更多的技术上是正确的,这 375 00:15:52,740 --> 00:15:55,570 是一个char星级,这意味着 名字,没错,就是一个变量。 376 00:15:55,570 --> 00:15:59,920 但什么名字店的地址是 一个字符,这感觉有点怪 377 00:15:59,920 --> 00:16:01,050 因为我得到一个字符串。 378 00:16:01,050 --> 00:16:03,580 我得到多个 字符不是一个字符。 379 00:16:03,580 --> 00:16:07,400 >> 不过,当然,你只需要第一 字符的地址记住 380 00:16:07,400 --> 00:16:08,870 整个字符串是因为什么原因呢? 381 00:16:08,870 --> 00:16:12,700 你怎么找出其中的结束 字符串是知道的开始? 382 00:16:12,700 --> 00:16:13,630 的反斜线零。 383 00:16:13,630 --> 00:16:17,260 因此,这两条线索,你弄清楚 开始前和结束 384 00:16:17,260 --> 00:16:20,280 任何字符串,只要他们 正确形成与空 385 00:16:20,280 --> 00:16:22,110 终结者,,反斜线零。 386 00:16:22,110 --> 00:16:24,520 >> 但是,这是调用的getString。 387 00:16:24,520 --> 00:16:28,020 事实证明的getString 这一切的时候已经种 388 00:16:28,020 --> 00:16:28,820 欺骗我们。 389 00:16:28,820 --> 00:16:32,460 它一直在做这种劳动,可以肯定, 得到了来自用户的字符串。 390 00:16:32,460 --> 00:16:34,580 但该内存 被来自哪里? 391 00:16:34,580 --> 00:16:38,440 如果我们回到这里的图片 从仅仅是一种应用的定义 392 00:16:38,440 --> 00:16:42,610 刚才,堆栈 内存去当函数被调用时, 393 00:16:42,610 --> 00:16:45,370 通过这种逻辑,当你需要调用getString 然后我输入 394 00:16:45,370 --> 00:16:50,900 D-A-V-I-D输入,是D-A-V-I-D 反斜杠零存储的基础上, 395 00:16:50,900 --> 00:16:53,480 我们的故事告诉我们多远? 396 00:16:53,480 --> 00:16:55,190 >> 这似乎是在 堆栈,对不对? 397 00:16:55,190 --> 00:16:58,120 当你调用得到的字符串,你会得到一个 小片内存堆栈。 398 00:16:58,120 --> 00:17:01,630 所以,按理说为D-A-V-I-D 反斜杠零被存储 399 00:17:01,630 --> 00:17:02,770 在堆栈中。 400 00:17:02,770 --> 00:17:07,680 但是且慢,形式返回 这个字符串,可以这么说,这意味着 401 00:17:07,680 --> 00:17:11,700 它的托盘从食堂 堆栈。 402 00:17:11,700 --> 00:17:14,560 和我们说最后一次,只要一 函数返回时,和你拿 403 00:17:14,560 --> 00:17:20,109 托盘,可以这么说,从堆栈什么 你可以假设一下残存的 404 00:17:20,109 --> 00:17:21,819 该内存? 405 00:17:21,819 --> 00:17:25,160 我有点重划为问号 因为他们有效地成为 406 00:17:25,160 --> 00:17:26,250 未知的值。 407 00:17:26,250 --> 00:17:29,500 它们可以被重用,当一些 下一个函数被调用。 408 00:17:29,500 --> 00:17:31,870 >> 换句话说,如果我们碰巧 存储 - 409 00:17:31,870 --> 00:17:34,350 我会画一个快速的图片 这里的堆栈。 410 00:17:34,350 --> 00:17:38,690 如果我们碰巧绘制底部 我的内存段,我们会说 411 00:17:38,690 --> 00:17:42,230 这是内存的地方 由主要可能ARG c和占用 412 00:17:42,230 --> 00:17:46,790 ARG v和别的程序, 被称为的GetString时, 413 00:17:46,790 --> 00:17:51,120 想必得到的getString 这里的内存块。 414 00:17:51,120 --> 00:17:53,940 D-A-V-I-D不知何故 在这个函数中结束了。 415 00:17:53,940 --> 00:17:55,320 我要简单化。 416 00:17:55,320 --> 00:18:00,050 但是,让我们假设,其D-A-V-I-D 反斜杠零。 417 00:18:00,050 --> 00:18:03,500 因此,这多少字节用于 GetString的框架。 418 00:18:03,500 --> 00:18:08,270 >> 但只要我们的形式返回, 说最后一次,这个内存超过 419 00:18:08,270 --> 00:18:11,340 在这里,一切都变得 - 哟嗬! - 420 00:18:11,340 --> 00:18:14,270 一切都变得有效擦除。 421 00:18:14,270 --> 00:18:17,220 我们可以认为现在问题 标记,因为谁知道 422 00:18:17,220 --> 00:18:18,720 这是怎么回事,成为该内存。 423 00:18:18,720 --> 00:18:22,130 事实上,我经常调用函数 以外的getString。 424 00:18:22,130 --> 00:18:24,750 而只要我调用其他一些 功能比的getString,也许不是在 425 00:18:24,750 --> 00:18:28,860 我们刚刚看到这个特定程序 但一些其他的,当然其他一些 426 00:18:28,860 --> 00:18:34,180 功能可能最终被定 这个堆栈中的下一个景点。 427 00:18:34,180 --> 00:18:39,410 >> 所以它不能说的GetString商店 D-A-V-I-D,因为我会在栈上 428 00:18:39,410 --> 00:18:41,040 立即失去对它的访问。 429 00:18:41,040 --> 00:18:43,720 但我们知道他们的GetString 只返回什么? 430 00:18:43,720 --> 00:18:47,220 它不回国 我六个字符。 431 00:18:47,220 --> 00:18:51,090 什么是真正回到根本 我们结束最后一次吗? 432 00:18:51,090 --> 00:18:52,480 地址的第一人。 433 00:18:52,480 --> 00:18:56,650 不知何故,当你打电话的GetString, 它分配的内存块 434 00:18:56,650 --> 00:18:59,620 字符串的用户类型和 然后它返回地址。 435 00:18:59,620 --> 00:19:02,930 事实证明,当你想 在这个函数来分配内存 436 00:19:02,930 --> 00:19:08,390 人谁打电话的方式和回报 该函数的地址 437 00:19:08,390 --> 00:19:11,870 该内存块,你绝对 不能把它在堆栈上 438 00:19:11,870 --> 00:19:14,750 底部,因为在功能上它只是 会不会成为你很 439 00:19:14,750 --> 00:19:17,800 很快,所以你大概可以猜测 我们可能会折腾 440 00:19:17,800 --> 00:19:20,130 相反,所谓的堆。 441 00:19:20,130 --> 00:19:25,290 >> 因此,你的记忆的底部之间 布局和你的内存的顶部 442 00:19:25,290 --> 00:19:26,820 布局段一大堆。 443 00:19:26,820 --> 00:19:29,270 一个是堆栈,和右 它上面的堆。 444 00:19:29,270 --> 00:19:33,680 和堆仅仅是一个不同的块 功能不用于内存 445 00:19:33,680 --> 00:19:34,770 当他们调用。 446 00:19:34,770 --> 00:19:38,100 它用于较长期的内存,当 你想一个函数来获取一些 447 00:19:38,100 --> 00:19:42,700 内存,能够挂到 而失去控制权。 448 00:19:42,700 --> 00:19:45,550 >> 现在,你也许可以立即 看看,这是不是 449 00:19:45,550 --> 00:19:48,060 不一定是完美的设计。 450 00:19:48,060 --> 00:19:51,350 当你的程序分配的内存 栈,或如你所说 451 00:19:51,350 --> 00:19:55,540 更多的功能,或作为您分配 用malloc销为堆内存 452 00:19:55,540 --> 00:20:00,690 GetString的是做什么,清楚 似乎是不可避免的问题? 453 00:20:00,690 --> 00:20:00,860 >> 右。 454 00:20:00,860 --> 00:20:03,150 喜欢的事实,这些箭头 指向对方 455 00:20:03,150 --> 00:20:04,380 并不是一个好兆头。 456 00:20:04,380 --> 00:20:08,630 事实上,我们可以非常迅速地崩溃 任何数目的方式中的程序。 457 00:20:08,630 --> 00:20:12,050 事实上,我认为我们可能有 这样做一次意外。 458 00:20:12,050 --> 00:20:14,020 如果没有,让我们做吧 现在故意。 459 00:20:14,020 --> 00:20:21,330 让我继续前进,超快速 了一项名为dontdothis.c。 460 00:20:21,330 --> 00:20:26,730 我现在就在这里和 不锋利包括stdio.h中。 461 00:20:26,730 --> 00:20:32,620 声明函数foo需要 没有参数​​,这是 462 00:20:32,620 --> 00:20:34,040 好记为无效。 463 00:20:34,040 --> 00:20:37,830 >> foo的是要干什么,唯一 调用foo,这可能是不 464 00:20:37,830 --> 00:20:39,100 最聪明的想法,但就这样吧。 465 00:20:39,100 --> 00:20:40,490 耳鼻喉科主无效。 466 00:20:40,490 --> 00:20:45,270 现在唯一的事情主要是去 要做的就是调用foo。 467 00:20:45,270 --> 00:20:51,050 只是踢,我要去 提前这里说的printf“你好从 468 00:20:51,050 --> 00:20:52,340 富。“ 469 00:20:52,340 --> 00:20:52,890 >> 确定。 470 00:20:52,890 --> 00:21:00,160 所以,如果我没有犯任何错误, 请点斜线dontdothis。 471 00:21:00,160 --> 00:21:01,960 让我们做一个更大的窗口 - 472 00:21:01,960 --> 00:21:03,210 点斜线,dontdothis。 473 00:21:03,210 --> 00:21:07,590 474 00:21:07,590 --> 00:21:08,840 来吧。 475 00:21:08,840 --> 00:21:10,940 476 00:21:10,940 --> 00:21:11,890 嗯哦。 477 00:21:11,890 --> 00:21:13,100 显然,你可以做到这一点。 478 00:21:13,100 --> 00:21:15,190 该死的。 479 00:21:15,190 --> 00:21:16,190 确定。 480 00:21:16,190 --> 00:21:16,580 等待。 481 00:21:16,580 --> 00:21:17,370 待机。 482 00:21:17,370 --> 00:21:18,270 难道我们 - 483 00:21:18,270 --> 00:21:20,110 我们没有使用它制作。 484 00:21:20,110 --> 00:21:22,050 >> [叹息] 485 00:21:22,050 --> 00:21:25,110 >> 我知道,但我想我们 刚删除。 486 00:21:25,110 --> 00:21:28,410 嗯,是啊。 487 00:21:28,410 --> 00:21:30,660 该死的。 488 00:21:30,660 --> 00:21:32,640 解决这个罗布。 489 00:21:32,640 --> 00:21:34,678 什么? 490 00:21:34,678 --> 00:21:35,928 这是非常简单的。 491 00:21:35,928 --> 00:21:43,820 492 00:21:43,820 --> 00:21:47,360 是啊,我们转向优化。 493 00:21:47,360 --> 00:21:48,970 OK,站在再见。 494 00:21:48,970 --> 00:21:49,950 现在我感觉好多了。 495 00:21:49,950 --> 00:21:51,390 确定。 496 00:21:51,390 --> 00:21:51,780 好的。 497 00:21:51,780 --> 00:21:53,430 >> 因此,让我们的编译 - 498 00:21:53,430 --> 00:21:55,880 让你dontdothis。 499 00:21:55,880 --> 00:22:00,090 您可能需要重命名为 只是一瞬间dothis.c。 500 00:22:00,090 --> 00:22:00,710 我们去那里。 501 00:22:00,710 --> 00:22:01,240 谢谢。 502 00:22:01,240 --> 00:22:02,050 确定。 503 00:22:02,050 --> 00:22:05,480 因此,事实上,我在打印 出来的东西实际上只是 504 00:22:05,480 --> 00:22:08,150 放缓的过程,我们 已经达到了这一点。 505 00:22:08,150 --> 00:22:08,510 确定。 506 00:22:08,510 --> 00:22:08,870 唷! 507 00:22:08,870 --> 00:22:11,180 >> 所以实际上是什么回事呢? 508 00:22:11,180 --> 00:22:14,440 之所以有,只是作为一个一边, 做任何输入 509 00:22:14,440 --> 00:22:17,270 输出往往要慢一些,因为你 写入字符 510 00:22:17,270 --> 00:22:18,600 屏幕,滚动。 511 00:22:18,600 --> 00:22:21,720 所以长话短说,其实我 发生等的不耐烦了,我们将不得不 512 00:22:21,720 --> 00:22:23,260 看到这个最终的结果也是如此。 513 00:22:23,260 --> 00:22:26,220 现在,我得到了乘坐的打印, 我们看到它的时候了。 514 00:22:26,220 --> 00:22:28,410 那么,为什么会出现这种情况。 515 00:22:28,410 --> 00:22:31,300 好吧,简单的解释,当然, 可能是,富不应该 516 00:22:31,300 --> 00:22:32,500 可以调用本身。 517 00:22:32,500 --> 00:22:34,470 >> 现在笼统, 这是递归。 518 00:22:34,470 --> 00:22:36,970 我们想了几个星期 前递归是好的。 519 00:22:36,970 --> 00:22:40,330 递归是这个神奇的方式 表达自己的超简洁。 520 00:22:40,330 --> 00:22:41,400 它只是工作。 521 00:22:41,400 --> 00:22:45,060 但有一个关键的功能,所有的 我们已经讨论过的递归程序 522 00:22:45,060 --> 00:22:48,260 因此,看着远, 是他们有什么? 523 00:22:48,260 --> 00:22:52,610 一个基本的情况,这是一些硬编码 情况下,在某些情况下,所述 524 00:22:52,610 --> 00:22:56,210 不叫富,这显然是 不是这里的情况。 525 00:22:56,210 --> 00:22:58,920 >> 那么,什么是真正发生的事情 在这幅画吗? 526 00:22:58,920 --> 00:23:01,790 那么,当主调用foo, 得到的片的内存。 527 00:23:01,790 --> 00:23:04,150 当foo调用foo,它就会 一个切片的内存。 528 00:23:04,150 --> 00:23:06,430 foo的调用foo时,它就会一片。 529 00:23:06,430 --> 00:23:07,080 它得到一个切片。 530 00:23:07,080 --> 00:23:08,120 它得到一个切片。 531 00:23:08,120 --> 00:23:09,460 因为foo是永远不会回来了。 532 00:23:09,460 --> 00:23:12,160 我们从来没有删除其中的一个 从堆栈帧。 533 00:23:12,160 --> 00:23:15,930 所以,我们正在吹遍堆,而不是 何况谁知道还有什么, 534 00:23:15,930 --> 00:23:19,600 我们正在超越我们的边界 所谓的内存段。 535 00:23:19,600 --> 00:23:21,790 错误去分割假。 536 00:23:21,790 --> 00:23:24,110 >> 因此,解决办法是 显然没有做到这一点。 537 00:23:24,110 --> 00:23:28,830 但是,更大的意义是,是的, 绝对是有一定的限制, 538 00:23:28,830 --> 00:23:32,470 即使它没有很好的定义,至于如何 很多功能,你可以调用一个 539 00:23:32,470 --> 00:23:34,970 程序,多少次的函数 可以调用本身。 540 00:23:34,970 --> 00:23:38,430 因此,即使我们做了宣讲递归 作为这种潜在的神奇的东西一 541 00:23:38,430 --> 00:23:41,870 几周前西格玛 功能,当我们得到的数据 542 00:23:41,870 --> 00:23:45,270 结构和CS50,你会看到其他 它的应用,它不是 543 00:23:45,270 --> 00:23:46,500 不一定是最好的事情。 544 00:23:46,500 --> 00:23:50,070 因为如果一个函数调用本身, 调用本身,即使有基地 545 00:23:50,070 --> 00:23:54,860 情况下,如果你不打,基本情况 1000电话或10000电话, 546 00:23:54,860 --> 00:23:58,800 那个时候,你可能已经运行的空间 你所谓的堆栈和命中 547 00:23:58,800 --> 00:24:00,400 一些其他的内存段。 548 00:24:00,400 --> 00:24:03,950 所以它也是一种设计权衡 优雅和之间 549 00:24:03,950 --> 00:24:06,920 您的特定的鲁棒性 实现。 550 00:24:06,920 --> 00:24:10,780 >> 所以还有另一个缺点或 另一个,这是我们的疑难杂症 551 00:24:10,780 --> 00:24:11,720 一直在做迄今。 552 00:24:11,720 --> 00:24:12,980 当我打电话的GetString - 553 00:24:12,980 --> 00:24:15,120 让我回去到2个招呼。 554 00:24:15,120 --> 00:24:18,170 请注意,我调用的getString 这是返回地址。 555 00:24:18,170 --> 00:24:20,730 我们要求今天地址 是从堆中。 556 00:24:20,730 --> 00:24:24,480 而现在,我打印出 在该地址的字符串。 557 00:24:24,480 --> 00:24:27,000 但是,我们从来没有所谓的 相反的getString。 558 00:24:27,000 --> 00:24:30,850 我们从来没有calll这样的函数 ungetstring,在那里你的手背 559 00:24:30,850 --> 00:24:31,610 该内存。 560 00:24:31,610 --> 00:24:33,250 但坦率地说,我们可能 应该是。 561 00:24:33,250 --> 00:24:37,390 因为如果我们继续问电脑 内存,有人喜欢的方式 562 00:24:37,390 --> 00:24:40,830 GetString的,但从来没有给它回来了,肯定 那也是必然导致 563 00:24:40,830 --> 00:24:42,970 据此,我们耗尽内存的问题。 564 00:24:42,970 --> 00:24:46,140 >> 而事实上,我们可以看看这些 用新的工具,其使用的问题 565 00:24:46,140 --> 00:24:47,640 是有点神秘输入。 566 00:24:47,640 --> 00:24:50,960 但是,让我继续前进,飞溅起来 在屏幕上一会儿就好了。 567 00:24:50,960 --> 00:24:56,940 我要继续运行Valgrind的 其第一个命令与参数 568 00:24:56,940 --> 00:25:00,260 行参数的名称是 ,程序HELLO-2。 569 00:25:00,260 --> 00:25:02,650 不幸的是,它是 输出残暴 570 00:25:02,650 --> 00:25:04,290 复杂,没有很好的理由。 571 00:25:04,290 --> 00:25:06,280 所以我们看到所有的烂摊子。 572 00:25:06,280 --> 00:25:07,530 大卫是说出我的名字。 573 00:25:07,530 --> 00:25:09,760 所以这是程序 实际运行。 574 00:25:09,760 --> 00:25:11,180 现在,我们得到如下的输出。 575 00:25:11,180 --> 00:25:13,400 >> 所以Valgrind是相似 精神GDB。 576 00:25:13,400 --> 00:25:14,950 这不是一个调试器本身。 577 00:25:14,950 --> 00:25:16,270 但它是一个内存检查。 578 00:25:16,270 --> 00:25:20,140 这是一个程序,将运行 编程,并告诉你,如果你问了 579 00:25:20,140 --> 00:25:23,860 计算机内存和从来没有把它递给 回来,因此这意味着你有 580 00:25:23,860 --> 00:25:24,570 内存泄漏。 581 00:25:24,570 --> 00:25:26,240 和内存泄漏往往是坏的。 582 00:25:26,240 --> 00:25:29,120 你是计算机用户 大概觉得这一点,你是否有一个 583 00:25:29,120 --> 00:25:30,300 Mac或PC。 584 00:25:30,300 --> 00:25:33,730 您是否曾​​经使用您的电脑 而在一些没有重新启动 585 00:25:33,730 --> 00:25:36,820 天,或者你刚刚得到了很多 程序运行,和那该死的东西 586 00:25:36,820 --> 00:25:42,360 减慢研磨停止,或者至少 超级讨厌使用,因为 587 00:25:42,360 --> 00:25:44,350 一切都只是得到了超慢。 588 00:25:44,350 --> 00:25:46,260 >> 现在,可以有任意数量的原因。 589 00:25:46,260 --> 00:25:49,600 这可能是一个无限循环,一个bug 某人的代码,或者更简单地说,它 590 00:25:49,600 --> 00:25:53,250 可能意味着你正在使用更多的 内存,或试图,比你 591 00:25:53,250 --> 00:25:54,920 电脑实际上有。 592 00:25:54,920 --> 00:25:57,770 也许有一些程序中的错误 保持内存要求。 593 00:25:57,770 --> 00:26:02,480 多年的浏览器是臭名远扬 这一点,要求越来越多的内存 594 00:26:02,480 --> 00:26:03,870 但从来没有将它送回。 595 00:26:03,870 --> 00:26:07,220 当然,如果你只有一个有限 内存量,你不能要求 596 00:26:07,220 --> 00:26:09,990 无限多次 一些该内存。 597 00:26:09,990 --> 00:26:13,070 >> 所以你在这里看到的,即使 再次Valgrind的输出是 598 00:26:13,070 --> 00:26:17,490 不必要的复杂瞥一眼 首先,这是最有趣的部分。 599 00:26:17,490 --> 00:26:18,890 堆 - 600 00:26:18,890 --> 00:26:20,060 在出口中使用。 601 00:26:20,060 --> 00:26:22,810 因此,这里是多大的内存 在使用于堆中 602 00:26:22,810 --> 00:26:24,300 我的程序退出 - 603 00:26:24,300 --> 00:26:27,280 显然在一个块中的6个字节。 604 00:26:27,280 --> 00:26:28,710 所以,我要挥挥手 在哪一个块。 605 00:26:28,710 --> 00:26:31,270 认为它就是一大块,更 技术字块。 606 00:26:31,270 --> 00:26:33,140 但六个字节 - 607 00:26:33,140 --> 00:26:36,870 什么是六个字节 仍在使用? 608 00:26:36,870 --> 00:26:37,390 >> 没错。 609 00:26:37,390 --> 00:26:41,520 D-A-V-I-D反斜杠零,五个字母 名称加上空结束。 610 00:26:41,520 --> 00:26:46,350 因此,这一计划的valgrind注意到,我 要求,很显然,由六个字节 611 00:26:46,350 --> 00:26:48,950 GetString的方式,但从来没有 给他们回来。 612 00:26:48,950 --> 00:26:52,030 而事实上,这可能不会是这样 很明显,如果我的程序并非三 613 00:26:52,030 --> 00:26:53,590 线,但它是300线。 614 00:26:53,590 --> 00:26:56,920 所以,我们其实可以给另一个命令 Valgrind的行参数 615 00:26:56,920 --> 00:26:58,290 使它更详细。 616 00:26:58,290 --> 00:26:59,760 要记住,这是一个有点恼人。 617 00:26:59,760 --> 00:27:01,580 但如果我这样做 - 618 00:27:01,580 --> 00:27:01,930 让我们来看看。 619 00:27:01,930 --> 00:27:03,540 泄漏 - 620 00:27:03,540 --> 00:27:05,030 被泄露 - 621 00:27:05,030 --> 00:27:07,580 即使我不记得 它是什么断手。 622 00:27:07,580 --> 00:27:08,550 >> - 泄漏检查等于已满。 623 00:27:08,550 --> 00:27:10,180 是的,谢谢你。 624 00:27:10,180 --> 00:27:12,520 - 泄漏检查等于已满。 625 00:27:12,520 --> 00:27:13,800 回车键。 626 00:27:13,800 --> 00:27:14,940 相同的程序正在运行。 627 00:27:14,940 --> 00:27:16,180 再次键入大卫。 628 00:27:16,180 --> 00:27:17,660 现在我看到的更详细一点。 629 00:27:17,660 --> 00:27:20,890 但堆下面总结, 四是相同的 - 啊, 630 00:27:20,890 --> 00:27:22,120 这是一种不错的。 631 00:27:22,120 --> 00:27:25,460 现在Valgrind是实际上是在寻找 在我的代码有点困难。 632 00:27:25,460 --> 00:27:29,580 和它的说,很显然, malloc的行 - 633 00:27:29,580 --> 00:27:30,580 我们缩小。 634 00:27:30,580 --> 00:27:31,980 行 - 635 00:27:31,980 --> 00:27:32,930 我们看不出它是什么线。 636 00:27:32,930 --> 00:27:35,110 但malloc的第一元凶。 637 00:27:35,110 --> 00:27:38,630 有一个博客中的malloc。 638 00:27:38,630 --> 00:27:39,810 >> 没事吧? 639 00:27:39,810 --> 00:27:40,450 OK,没。 640 00:27:40,450 --> 00:27:40,940 对吗? 641 00:27:40,940 --> 00:27:42,520 我叫GetString的。 642 00:27:42,520 --> 00:27:44,460 显然的getString调用malloc。 643 00:27:44,460 --> 00:27:47,800 那么,什么行代码显然是 有过错 644 00:27:47,800 --> 00:27:49,050 分配这个内存? 645 00:27:49,050 --> 00:27:51,560 646 00:27:51,560 --> 00:27:55,540 让我们假设,谁写的malloc 已经存在了足够长的时间,它是 647 00:27:55,540 --> 00:27:56,390 不是他们的错。 648 00:27:56,390 --> 00:27:57,520 因此,它可能是我的。 649 00:27:57,520 --> 00:28:02,000 的GetString cs50.c - 所以这是一个 文件在计算机上的某个地方 - 650 00:28:02,000 --> 00:28:05,210 在286行似乎是罪魁祸首。 651 00:28:05,210 --> 00:28:08,140 现在,让我们假设已经CS50 围绕体面的时间量,所以 652 00:28:08,140 --> 00:28:09,720 我们也有犯错误的。 653 00:28:09,720 --> 00:28:14,080 因此,它可能不是的GetString 错误在于,而是在 654 00:28:14,080 --> 00:28:17,810 HELLO-2.C线18。 655 00:28:17,810 --> 00:28:20,670 >> 因此,让我们一起来看看 该行18是什么。 656 00:28:20,670 --> 00:28:21,130 哦。 657 00:28:21,130 --> 00:28:27,130 不知怎的,这条线是不一定 越野车,本身,但它的原因是 658 00:28:27,130 --> 00:28:28,630 背后的内存泄漏。 659 00:28:28,630 --> 00:28:32,140 因此,超级简单,将直观地 这里的解决方案吗? 660 00:28:32,140 --> 00:28:34,710 如果我们要求内存,从来没有 给它,这似乎是一个 661 00:28:34,710 --> 00:28:37,940 的问题,因为随着时间的推移我的电脑 可能会耗尽内存,可能会减缓 662 00:28:37,940 --> 00:28:42,110 下来,不好的事情可能会发生,好了, 简单直观的解决方案是什么? 663 00:28:42,110 --> 00:28:43,140 只要给它回来。 664 00:28:43,140 --> 00:28:44,770 >> 你如何释放内存? 665 00:28:44,770 --> 00:28:49,970 嗯,幸好这是相当简单 只是说免费的名字。 666 00:28:49,970 --> 00:28:51,260 我们从来没有这样做过。 667 00:28:51,260 --> 00:28:55,890 但你基本上可以认为 相反的malloc。 668 00:28:55,890 --> 00:28:58,030 免费是相反的 分配内存。 669 00:28:58,030 --> 00:28:59,540 所以现在让我重新编译。 670 00:28:59,540 --> 00:29:02,050 “HELLO-2。 671 00:29:02,050 --> 00:29:04,620 让我再次运行它。 HELLO-2大卫。 672 00:29:04,620 --> 00:29:07,290 因此,它似乎工作 以完全相同的方式。 673 00:29:07,290 --> 00:29:11,180 但是,如果我回去Valgrind的,并重新运行 我新的相同命令 674 00:29:11,180 --> 00:29:14,720 编译后的程序,打字 在我的名字前 - 675 00:29:14,720 --> 00:29:15,370 不错。 676 00:29:15,370 --> 00:29:16,760 堆总结 - 677 00:29:16,760 --> 00:29:17,740 在出口中使用 - 678 00:29:17,740 --> 00:29:19,370 零字节的零块。 679 00:29:19,370 --> 00:29:21,840 这是超级好看,所有 堆块被释放。 680 00:29:21,840 --> 00:29:23,480 无泄漏是可能的。 681 00:29:23,480 --> 00:29:27,200 >> 因此,未来,不与习题集4 但与习题集5,取证 682 00:29:27,200 --> 00:29:30,740 起,这也将成为一个 措施的正确性的 683 00:29:30,740 --> 00:29:33,630 程序,不论你有 或者没有内存泄漏。 684 00:29:33,630 --> 00:29:36,900 但令人欣慰的是,你不仅可以理 通过它们很直观, 685 00:29:36,900 --> 00:29:40,430 可以说,是方便的小程序 但对于大型程序更难, 686 00:29:40,430 --> 00:29:43,860 Valgrind的,对于那些较大节目, 可以帮助您识别 687 00:29:43,860 --> 00:29:45,360 特别的问题。 688 00:29:45,360 --> 00:29:47,500 >> 但是,还有另外一个问题 可能出现的。 689 00:29:47,500 --> 00:29:51,245 让我在这里打开这个文件,这一点, 再次,有些简单的例子。 690 00:29:51,245 --> 00:29:53,760 但是,让我们的重点放在什么 这个程序。 691 00:29:53,760 --> 00:29:55,190 这就是所谓的memory.c。 692 00:29:55,190 --> 00:29:58,380 在今天稍后我们将发布 今天的源代码压缩。 693 00:29:58,380 --> 00:30:01,610 ,请注意,我有一个函数调用 f以不带任何参数和 694 00:30:01,610 --> 00:30:02,800 返回一无所获。 695 00:30:02,800 --> 00:30:07,240 在第20行,我显然声明 int和调用x的指针。 696 00:30:07,240 --> 00:30:09,570 我分配的是返回 值的malloc。 697 00:30:09,570 --> 00:30:14,590 只是要清楚,我多少字节 我大概从malloc 698 00:30:14,590 --> 00:30:17,080 在这种情况下呢? 699 00:30:17,080 --> 00:30:18,040 >> 大概40。 700 00:30:18,040 --> 00:30:18,840 你在哪儿? 701 00:30:18,840 --> 00:30:22,410 好吧,如果你还记得,往往是一个int 4个字节,它是在至少 702 00:30:22,410 --> 00:30:25,110 器具4的10倍,显然是40。 703 00:30:25,110 --> 00:30:28,920 所以malloc的返回地址 一大块的内存和存储 704 00:30:28,920 --> 00:30:30,800 在x最终解决。 705 00:30:30,800 --> 00:30:32,570 所以要明确, 然后发生了什么? 706 00:30:32,570 --> 00:30:34,990 好吧,让我切换回 我们这里的图片。 707 00:30:34,990 --> 00:30:38,150 让我不只是画出心底 计算机的内存,让我继续前进, 708 00:30:38,150 --> 00:30:42,990 绘制整个矩形, 代表我的内存。 709 00:30:42,990 --> 00:30:44,790 >> 我们会说,堆栈 是在底部。 710 00:30:44,790 --> 00:30:47,010 有一个文本段 未初始化的数据。 711 00:30:47,010 --> 00:30:49,880 但我只是去那些抽象 其他的东西远点,点的点。 712 00:30:49,880 --> 00:30:53,470 我只是指 随着堆在上面。 713 00:30:53,470 --> 00:30:57,070 然后在这幅画的底部, 代表主,我要去 714 00:30:57,070 --> 00:30:59,880 给它一个片内存 在堆栈中。 715 00:30:59,880 --> 00:31:03,150 F,我要去给它一个切片 内存堆栈。 716 00:31:03,150 --> 00:31:05,140 现在,我咨询了我 再次源代码。 717 00:31:05,140 --> 00:31:07,170 局部变量主要是什么? 718 00:31:07,170 --> 00:31:10,710 显然没有,所以该片 有效空的,或者甚至还不如大 719 00:31:10,710 --> 00:31:11,600 因为我已经画了。 720 00:31:11,600 --> 00:31:15,730 但在F,我有一个局部变量, 被称为X。 721 00:31:15,730 --> 00:31:20,410 所以我要继续前进,并得到F 一块内存,调用x。 722 00:31:20,410 --> 00:31:24,680 >> 现在malloc的10倍4, ,所以malloc的40,在哪里 723 00:31:24,680 --> 00:31:25,430 内存从何而来? 724 00:31:25,430 --> 00:31:27,530 我们还没有得出一个图片 像这个。 725 00:31:27,530 --> 00:31:31,140 但是让我们假设,它是有效的 从这里来的,所以, 726 00:31:31,140 --> 00:31:33,170 二,三,四,五。 727 00:31:33,170 --> 00:31:34,680 现在我需要40。 728 00:31:34,680 --> 00:31:37,540 所以我就做点,点,点建议 甚至更多的内存 729 00:31:37,540 --> 00:31:39,350 回来从堆中。 730 00:31:39,350 --> 00:31:40,710 现在的地址是什么? 731 00:31:40,710 --> 00:31:42,620 让我们选择我们的任意 解决一如既往 - 732 00:31:42,620 --> 00:31:46,310 Ox123,尽管它可能会 是完全不同的东西。 733 00:31:46,310 --> 00:31:50,420 这是的第一个字节的地址 内存,我要问的malloc。 734 00:31:50,420 --> 00:31:53,630 >> 因此,在短,一旦线20执行 字面意思是什么 735 00:31:53,630 --> 00:31:57,170 里面存放的x? 736 00:31:57,170 --> 00:31:58,730 Ox123。 737 00:31:58,730 --> 00:32:00,370 Ox123。 738 00:32:00,370 --> 00:32:01,550 牛年是无趣的。 739 00:32:01,550 --> 00:32:03,200 它只是意味着这里是一个 十六进制数。 740 00:32:03,200 --> 00:32:06,490 但关键的是,我的店 在x,它是一个局部变量。 741 00:32:06,490 --> 00:32:10,260 但它的数据类型,再次 是一个地址,一个int。 742 00:32:10,260 --> 00:32:12,710 好吧,我要存储Ox123。 743 00:32:12,710 --> 00:32:16,610 但是,如果这是一个有点太 不必要的复杂,如果我滚动 744 00:32:16,610 --> 00:32:21,490 背面,我们可以抽象送人相当 合理,只是说,x是一个 745 00:32:21,490 --> 00:32:23,910 该内存块的指针。 746 00:32:23,910 --> 00:32:24,070 >> 确定。 747 00:32:24,070 --> 00:32:26,230 现在的问题在手 - 748 00:32:26,230 --> 00:32:29,910 事实证明,21号线,是马车。 749 00:32:29,910 --> 00:32:31,160 为什么呢? 750 00:32:31,160 --> 00:32:34,890 751 00:32:34,890 --> 00:32:36,930 >> 对不起? 752 00:32:36,930 --> 00:32:38,640 它不具有 - 753 00:32:38,640 --> 00:32:40,390 说一次。 754 00:32:40,390 --> 00:32:41,240 那么,它不是免费的。 755 00:32:41,240 --> 00:32:42,350 所以这是第二个。 756 00:32:42,350 --> 00:32:45,000 因此,有另外一个,但具体 在第21行。 757 00:32:45,000 --> 00:32:49,480 758 00:32:49,480 --> 00:32:50,040 >> 没错。 759 00:32:50,040 --> 00:32:54,980 这个简单的一行代码仅仅是一个 缓冲区溢出,缓冲区溢出。 760 00:32:54,980 --> 00:32:57,050 只是意味着一个缓冲区的内存块。 761 00:32:57,050 --> 00:33:01,520 但是,内存块的大小为 10,10的整数,这意味着,如果我们 762 00:33:01,520 --> 00:33:05,350 索引使用语法糖 数组符号,广场 763 00:33:05,350 --> 00:33:09,220 括号中,你有机会获得 x支架0 X支架1个, 764 00:33:09,220 --> 00:33:10,390 支架点,点,点。 765 00:33:10,390 --> 00:33:13,270 9 x支架是最大的一个。 766 00:33:13,270 --> 00:33:17,680 所以,如果我做X支架10 实际上,我在内存中? 767 00:33:17,680 --> 00:33:19,120 >> 好吧,如果我有10个整数 - 768 00:33:19,120 --> 00:33:21,070 让我们实际绘制所有 这些在这里。 769 00:33:21,070 --> 00:33:22,700 所以这是第5位。 770 00:33:22,700 --> 00:33:24,660 这里的其他5个int。 771 00:33:24,660 --> 00:33:29,580 所以X支架0是在这里。 x支架1 在这里。 9 x支架是在这里。 x支架 772 00:33:29,580 --> 00:33:37,960 10,这意味着我告诉 在第21行中,计算机把 773 00:33:37,960 --> 00:33:39,400 号在哪里? 774 00:33:39,400 --> 00:33:42,010 数字0在哪里? 775 00:33:42,010 --> 00:33:43,380 嗯,这是0,是的。 776 00:33:43,380 --> 00:33:45,460 但是,仅仅一个事实,即其0 是一种巧合。 777 00:33:45,460 --> 00:33:47,140 它可能是数字 50,我们所关心的一切。 778 00:33:47,140 --> 00:33:50,480 但我们正在努力把它在x支架 10,这是这 779 00:33:50,480 --> 00:33:53,700 绘制问号, 是不是一件好事。 780 00:33:53,700 --> 00:33:57,070 这个程序可能会非常好 崩溃的结果。 781 00:33:57,070 --> 00:33:59,400 >> 现在,让我们继续前进,看看,如果这 的确,发生了什么。 782 00:33:59,400 --> 00:34:02,600 使存储器,因为该文件 被称为memory.c。 783 00:34:02,600 --> 00:34:05,950 让我们继续前进,并运行 程序存储器。 784 00:34:05,950 --> 00:34:08,239 所以我们很幸运,其实,它似乎。 785 00:34:08,239 --> 00:34:09,340 我们很幸运。 786 00:34:09,340 --> 00:34:11,060 但是,让我们来看看,如果我们现在运行Valgrind的。 787 00:34:11,060 --> 00:34:14,170 乍一看,我的程序可能 似乎是完全正确的。 788 00:34:14,170 --> 00:34:18,010 但让我与运行Valgrind的 - 等于内存泄漏检查。 789 00:34:18,010 --> 00:34:20,110 >> 而现在,当我运行这个 - 790 00:34:20,110 --> 00:34:21,030 有意思的。 791 00:34:21,030 --> 00:34:26,800 无效写大小为4 memory.c 21行。 792 00:34:26,800 --> 00:34:29,284 memory.c 21号线是哪一个? 793 00:34:29,284 --> 00:34:30,340 呵呵,有意思。 794 00:34:30,340 --> 00:34:31,080 但等待。 795 00:34:31,080 --> 00:34:32,389 尺寸4,是指什么? 796 00:34:32,389 --> 00:34:34,969 我只是一个写 但它的大小为4。 797 00:34:34,969 --> 00:34:36,889 为什么是4? 798 00:34:36,889 --> 00:34:39,280 这是因为它是一个整数, ,再四个字节。 799 00:34:39,280 --> 00:34:42,510 因此,Valgrind的,我发现了一个bug, 在我的代码一眼,没有。 800 00:34:42,510 --> 00:34:45,040 ,也许你的TF会或不会。 801 00:34:45,040 --> 00:34:48,469 但Valgrind的肯定发现 我们犯了一个错误,甚至 802 00:34:48,469 --> 00:34:52,719 虽然我们很幸运,和电脑 决定,诶,我不会崩溃 803 00:34:52,719 --> 00:34:57,470 只是因为你碰到一个字节,一个 int的内存价值,你没有 804 00:34:57,470 --> 00:34:58,550 实际上是自己的。 805 00:34:58,550 --> 00:35:00,380 >> 那么,还有什么是马车。 806 00:35:00,380 --> 00:35:01,180 地址 - 807 00:35:01,180 --> 00:35:03,190 这是一个疯狂的寻找地址 十六进制。 808 00:35:03,190 --> 00:35:06,890 这只是意味着在某处堆 零字节块大小为40后 809 00:35:06,890 --> 00:35:07,620 被分配。 810 00:35:07,620 --> 00:35:10,610 让我放大了这里,看看如果 这是一个多一点帮助。 811 00:35:10,610 --> 00:35:11,410 有趣。 812 00:35:11,410 --> 00:35:15,600 肯定失去40字节 1 1负的战绩。 813 00:35:15,600 --> 00:35:17,840 同样,更多的话比在这里是非常有用的。 814 00:35:17,840 --> 00:35:21,350 但基于高亮行, 我应该在哪里可能集中 815 00:35:21,350 --> 00:35:24,070 关注的另一个错误? 816 00:35:24,070 --> 00:35:26,570 看起来像memory.c 20行。 817 00:35:26,570 --> 00:35:30,990 >> 因此,如果我们回到20行,这就是 一个前面确定。 818 00:35:30,990 --> 00:35:33,030 它不一定是马车。 819 00:35:33,030 --> 00:35:35,160 但我们已经扭转其影响。 820 00:35:35,160 --> 00:35:38,790 所以,我怎么至少改正 这些错误? 821 00:35:38,790 --> 00:35:42,240 21号线后,我能做什么呢? 822 00:35:42,240 --> 00:35:47,110 我可以做免费的X,所以 给该内存。 823 00:35:47,110 --> 00:35:49,230 我怎么解决这个错误? 824 00:35:49,230 --> 00:35:52,120 我绝对应该去 距离不超过0。 825 00:35:52,120 --> 00:35:53,670 所以,让我尝试重新运行这个。 826 00:35:53,670 --> 00:35:56,080 对不起,肯定去 距离不超过9。 827 00:35:56,080 --> 00:35:57,510 使内存。 828 00:35:57,510 --> 00:36:00,650 让我重新运行Valgrind的 在一个更大的窗口。 829 00:36:00,650 --> 00:36:01,580 现在看。 830 00:36:01,580 --> 00:36:02,250 尼斯。 831 00:36:02,250 --> 00:36:03,270 所有的堆块被释放。 832 00:36:03,270 --> 00:36:04,270 无泄漏是可能的。 833 00:36:04,270 --> 00:36:07,520 上述这里,这里没有提到 任何无效的权利。 834 00:36:07,520 --> 00:36:09,820 >> 只是为了让贪婪,让我们 如果另一个示范 835 00:36:09,820 --> 00:36:11,050 不走的打算 - 836 00:36:11,050 --> 00:36:12,560 我没有得到幸运的时刻。 837 00:36:12,560 --> 00:36:15,530 的事实,这是0也许是 不必要的误导。 838 00:36:15,530 --> 00:36:20,650 让我们只是做50个,有点武断 电话号码,让记忆点阵斜线内存 - 839 00:36:20,650 --> 00:36:21,410 仍然得到幸运。 840 00:36:21,410 --> 00:36:22,510 没有崩溃。 841 00:36:22,510 --> 00:36:26,150 假设我只是做一些真正 愚蠢的,我做100个。 842 00:36:26,150 --> 00:36:30,360 让我重拍内存, 点斜线内存 - 843 00:36:30,360 --> 00:36:31,075 很幸运了。 844 00:36:31,075 --> 00:36:32,800 约1000如何? 845 00:36:32,800 --> 00:36:35,370 int的超越,大致 在那里我应该是什么? 846 00:36:35,370 --> 00:36:37,410 使存储器 - 847 00:36:37,410 --> 00:36:38,570 该死的。 848 00:36:38,570 --> 00:36:39,920 >> [笑] 849 00:36:39,920 --> 00:36:41,270 >> 确定。 850 00:36:41,270 --> 00:36:43,920 我们不是好惹的周围了。 851 00:36:43,920 --> 00:36:45,120 重新运行内存。 852 00:36:45,120 --> 00:36:45,840 我们去那里。 853 00:36:45,840 --> 00:36:46,410 好的。 854 00:36:46,410 --> 00:36:52,500 因此很明显,你100,000整数索引 超越你应该已经在 855 00:36:52,500 --> 00:36:54,410 内存,不好的事情发生。 856 00:36:54,410 --> 00:36:56,430 因此,这显然是不 一种坚硬,快速的规则。 857 00:36:56,430 --> 00:36:58,190 我是那种使用试验 和错误到那里。 858 00:36:58,190 --> 00:37:02,230 但是,这是因为,长话短说, 您的计算机的内存也划分 859 00:37:02,230 --> 00:37:03,580 这些事称为段。 860 00:37:03,580 --> 00:37:07,260 有时,电脑实际上 已经给你多一点的内存 861 00:37:07,260 --> 00:37:08,400 比你问。 862 00:37:08,400 --> 00:37:12,170 但为了提高效率,它只是更容易 获得更多的内存,但只能告诉你 863 00:37:12,170 --> 00:37:13,780 你得到它的一部分。 864 00:37:13,780 --> 00:37:16,370 >> 如果你幸运,有时, 因此,您可能能够触摸 865 00:37:16,370 --> 00:37:17,795 存储器中并不属于你。 866 00:37:17,795 --> 00:37:21,860 你有没有保证,什么样的价值 你放在那里将呆在那里,因为 867 00:37:21,860 --> 00:37:25,080 计算机仍然认为它不 你的,但它不一定要去 868 00:37:25,080 --> 00:37:29,910 打另一个段中的内存 计算机和诱导这样一个错误 869 00:37:29,910 --> 00:37:31,710 这一个在这里。 870 00:37:31,710 --> 00:37:32,060 好的。 871 00:37:32,060 --> 00:37:37,240 然后在内存中的任何问题吗? 872 00:37:37,240 --> 00:37:37,590 >> 好的。 873 00:37:37,590 --> 00:37:40,610 让我们来看看这里,然后, 我们一直在服用的东西 874 00:37:40,610 --> 00:37:48,361 授予相当长的一段时间, 在这个文件中称为cs50.h.的 875 00:37:48,361 --> 00:37:49,420 因此,这是一个文件。 876 00:37:49,420 --> 00:37:51,130 这些都只是一大堆 往上顶的意见。 877 00:37:51,130 --> 00:37:53,900 你可能已经看过这个,如果 你周围戳在设备上。 878 00:37:53,900 --> 00:37:57,000 但事实证明,所有的时间, 当我们使用字符串作为 879 00:37:57,000 --> 00:38:01,130 同义词,手段,我们宣布 这代名词 880 00:38:01,130 --> 00:38:03,990 关键字typedef的类型定义。 881 00:38:03,990 --> 00:38:07,500 我们本质上说, 串一个字符星级的代名词。 882 00:38:07,500 --> 00:38:11,190 的装置,通过该堆栈 这些培训车轮被称为 883 00:38:11,190 --> 00:38:12,040 的字符串。 884 00:38:12,040 --> 00:38:14,830 >> 现在,这里只是一个原型 getchar的。 885 00:38:14,830 --> 00:38:17,350 我们可能已经看到它之前,但是这 的确它做什么。用getchar 886 00:38:17,350 --> 00:38:19,070 不带任何参数,返回一个字符。 887 00:38:19,070 --> 00:38:21,340 getdouble不带任何参数, 返回一个double。 888 00:38:21,340 --> 00:38:24,440 getfloat不带任何参数,返回 float,并且依此类推。 889 00:38:24,440 --> 00:38:27,270 调用getInt是在这里。 getlonglong 是在这里。 890 00:38:27,270 --> 00:38:28,820 和GetString是在这里。 891 00:38:28,820 --> 00:38:29,420 就是这样。 892 00:38:29,420 --> 00:38:33,080 这紫色的线是另一个预处理 指令,因为 893 00:38:33,080 --> 00:38:35,550 包括hashtag在它的开始。 894 00:38:35,550 --> 00:38:35,870 >> 好的。 895 00:38:35,870 --> 00:38:38,380 所以,现在让我进入cs50.c. 896 00:38:38,380 --> 00:38:40,400 我们不会说话太长。 897 00:38:40,400 --> 00:38:43,280 但给你一个什么样的一瞥 这一切一直 898 00:38:43,280 --> 00:38:46,434 时间,让我去 - 899 00:38:46,434 --> 00:38:48,250 让我们做getchar的。 900 00:38:48,250 --> 00:38:51,050 所以getchar是主要意见。 901 00:38:51,050 --> 00:38:52,060 但它看起来是这样的。 902 00:38:52,060 --> 00:38:54,800 因此,这是实际的功能 我们一直用getchar 903 00:38:54,800 --> 00:38:56,055 理所当然的存在。 904 00:38:56,055 --> 00:38:59,370 即使我们不使用这一个 经常,如果有的话,它至少 905 00:38:59,370 --> 00:39:00,470 比较简单。 906 00:39:00,470 --> 00:39:02,580 因此,它是值得考虑 快看这里。 907 00:39:02,580 --> 00:39:06,540 >> 所以用getchar有一个无限循环, 显然是故意让。 908 00:39:06,540 --> 00:39:10,050 然后,它调用 - 这是怎样的一个 漂亮的代码重用,我们自己写。 909 00:39:10,050 --> 00:39:11,220 它调用的getString。 910 00:39:11,220 --> 00:39:12,460 因为它 意味着一个char? 911 00:39:12,460 --> 00:39:14,730 嗯,你不如尝试获得 从用户和整行文本 912 00:39:14,730 --> 00:39:16,940 然后就看一眼 这些字符。 913 00:39:16,940 --> 00:39:19,170 在60号线,这里有一个小 位神智检查。 914 00:39:19,170 --> 00:39:21,610 如果GetString的返回了空, 让我们无法继续。 915 00:39:21,610 --> 00:39:22,820 出了错。 916 00:39:22,820 --> 00:39:28,120 >> 现在,这是有点恼人,但 常规C.字符最大可能 917 00:39:28,120 --> 00:39:29,960 代表什么 基于它的名字吗? 918 00:39:29,960 --> 00:39:31,670 这是一个常数。 919 00:39:31,670 --> 00:39:36,040 这就像数值 最大的字符,你可以代表 920 00:39:36,040 --> 00:39:40,370 一咬,这大概是多少 255,这是最大的号码 921 00:39:40,370 --> 00:39:42,720 代表8位, 从零开始。 922 00:39:42,720 --> 00:39:47,460 所以,我已经使用这个,在这个函数时, 写这段代码,仅仅是因为 923 00:39:47,460 --> 00:39:51,753 如果出现错误,但在用getchar 在生活中,它的目的是返回一个 924 00:39:51,753 --> 00:39:54,830 字符,你需要以某种方式能 信号向用户表明 925 00:39:54,830 --> 00:39:55,840 出事了。 926 00:39:55,840 --> 00:39:56,970 我们不能返回null。 927 00:39:56,970 --> 00:39:58,480 null是一个指针。 928 00:39:58,480 --> 00:40:01,030 再次,用getchar 返回一个字符。 929 00:40:01,030 --> 00:40:04,760 >> 所以惯例,如果出现 错了,是你,程序员,或者 930 00:40:04,760 --> 00:40:08,160 这种情况下,我的图书馆,我不得不 一个公正的任意决定,如果 931 00:40:08,160 --> 00:40:12,230 不顺心的事,我要 返回数字255,这是真正的 932 00:40:12,230 --> 00:40:17,240 意味着我们不能,用户可以不输入 表示的字符 933 00:40:17,240 --> 00:40:21,410 255号,因为我们有一个偷 作为一个所谓的哨兵值 934 00:40:21,410 --> 00:40:23,410 表示出现了问题。 935 00:40:23,410 --> 00:40:27,010 现在事实证明,字符255 是不是,你可以输入 936 00:40:27,010 --> 00:40:28,380 你的键盘,所以它是没有什么大不了的。 937 00:40:28,380 --> 00:40:30,910 用户不会注意到, 我抢了这个人物。 938 00:40:30,910 --> 00:40:34,620 但是,如果你看到在手册页上 计算机系统中的一些参考 939 00:40:34,620 --> 00:40:38,560 帽不变,这样说, 案件中的错误这个恒定的威力 940 00:40:38,560 --> 00:40:42,720 被退回,这是所有做一些人类 几年前,擅自决定 941 00:40:42,720 --> 00:40:45,680 返回这个特殊的价值和 一个恒定的情况下 942 00:40:45,680 --> 00:40:46,840 出现错误。 943 00:40:46,840 --> 00:40:48,580 >> 现在发生的神奇在这里。 944 00:40:48,580 --> 00:40:52,600 首先,我声明在67行 两个字符,C1和C2。 945 00:40:52,600 --> 00:40:57,080 然后在第68行,实际上是有 一行代码,让人想起 946 00:40:57,080 --> 00:41:01,140 我们的朋友的printf,因为它 确实有百分之CS在引号中。 947 00:41:01,140 --> 00:41:06,490 但是请注意,这里发生了什么。 sscanf的表示字符串扫描 - 948 00:41:06,490 --> 00:41:11,690 扫描格式化 字符串,因此sscanf的。 949 00:41:11,690 --> 00:41:12,590 这是什么意思? 950 00:41:12,590 --> 00:41:16,310 这意味着你传递给sscanf的一个字符串。 951 00:41:16,310 --> 00:41:18,420 和线无论是 用户键入 952 00:41:18,420 --> 00:41:23,520 您传递给sscanf的一个格式字符串,如 这告诉scanf函数是什么 953 00:41:23,520 --> 00:41:25,870 你希望用户输入。 954 00:41:25,870 --> 00:41:29,730 然后,您可以通过两个地址 的内存块,在这种情况下, 955 00:41:29,730 --> 00:41:31,150 因为我有两个占位符。 956 00:41:31,150 --> 00:41:34,610 所以我要去给它的地址 C1和C2的地址。 957 00:41:34,610 --> 00:41:37,700 >> 记得你给一个函数 一些变量的地址,有什么 958 00:41:37,700 --> 00:41:38,950 意味着什么呢? 959 00:41:38,950 --> 00:41:41,400 960 00:41:41,400 --> 00:41:45,050 由于该功能可以做什么 给它的地址的情况 961 00:41:45,050 --> 00:41:48,170 可变的,而不是 变量本身? 962 00:41:48,170 --> 00:41:49,450 它可以改变它,对不对? 963 00:41:49,450 --> 00:41:53,250 如果你有某人映射到物理 地址,他们可以去那里做 964 00:41:53,250 --> 00:41:54,750 无论他们想在该地址。 965 00:41:54,750 --> 00:41:55,800 同样的想法在这里。 966 00:41:55,800 --> 00:41:59,950 如果我们传递给sscanf的,两个地址 大块的内存,即使是这些微小的 967 00:41:59,950 --> 00:42:03,585 小的块存储器,C1和C2,但是 我们告诉它的地址, 968 00:42:03,585 --> 00:42:05,170 sscanf的可以改变它。 969 00:42:05,170 --> 00:42:08,530 >> 所以sscanf的生活的目的,如果我们读 手册页是读什么 970 00:42:08,530 --> 00:42:13,420 键入的用户,希望用户 键入一个字符,也许 971 00:42:13,420 --> 00:42:16,470 另外一个角色,无论用户 键入的第一个字符进入 972 00:42:16,470 --> 00:42:19,310 在这里,第二个字符到这里。 973 00:42:19,310 --> 00:42:22,470 现在,顺便说一句,这,你会 只知道这个文档, 974 00:42:22,470 --> 00:42:25,570 事实上,我在那里放一个空白空间 只是意味着我不关心,如果 975 00:42:25,570 --> 00:42:28,440 用户点击空格键几 次之前,他或她需要 976 00:42:28,440 --> 00:42:30,400 性格,我要忽略 任何空白。 977 00:42:30,400 --> 00:42:32,510 所以,我知道,从 文档。 978 00:42:32,510 --> 00:42:36,570 >> 事实上,还有第二个%C 其次是白色空间实际上是 979 00:42:36,570 --> 00:42:37,410 经过深思熟虑的。 980 00:42:37,410 --> 00:42:41,190 我想如果用户能够检测 搞砸了或不配合。 981 00:42:41,190 --> 00:42:45,630 所以,我希望用户仅键入 在一个字符,因此我希望 982 00:42:45,630 --> 00:42:50,640 sscanf的是只打算返回 值1,因为再次,如果我读 983 00:42:50,640 --> 00:42:55,400 文档,sscanf的目的 生活是返回的数目 984 00:42:55,400 --> 00:42:59,170 充满变量 用户输入。 985 00:42:59,170 --> 00:43:02,270 >> 我通过两个变量 地址,C1和C2。 986 00:43:02,270 --> 00:43:06,420 我希望,虽然,只有一个 他们被杀害,因为如果sscanf的 987 00:43:06,420 --> 00:43:11,130 返回2,什么是推测 逻辑的含义? 988 00:43:11,130 --> 00:43:14,600 用户不只是给我一个 性格就像我告诉他或她。 989 00:43:14,600 --> 00:43:17,860 他们可能输入 至少有两个字符。 990 00:43:17,860 --> 00:43:22,430 所以,如果我不是没有第二 %C,我只是有一个, 991 00:43:22,430 --> 00:43:25,370 坦率地说会更直观 的做法,我觉得乍一看, 992 00:43:25,370 --> 00:43:30,220 你不会是能够检测 如果用户已经给你更多 993 00:43:30,220 --> 00:43:31,780 输入比你居然想。 994 00:43:31,780 --> 00:43:34,100 所以这是一个隐含的形式 错误检查。 995 00:43:34,100 --> 00:43:35,640 >> 但是请注意,我在这里做什么。 996 00:43:35,640 --> 00:43:39,970 我敢肯定,一旦用户给了我一个 性格,我释放就行了,做 997 00:43:39,970 --> 00:43:44,450 GetString的相反,而这又 使用malloc,然后我返回 998 00:43:44,450 --> 00:43:51,030 C1,我希望的字符 用户提供的,只提供了。 999 00:43:51,030 --> 00:43:54,680 所以简单,但瞥见 getchar的任何问题? 1000 00:43:54,680 --> 00:43:57,450 1001 00:43:57,450 --> 00:43:59,590 我们会回来的一些其他。 1002 00:43:59,590 --> 00:44:03,770 >> 好吧,让我继续前进,这样做 - 现在假设,只是为了激励我们 1003 00:44:03,770 --> 00:44:08,910 一个星期的讨论,加上时间,这 是一个名为structs.h。 1004 00:44:08,910 --> 00:44:11,440 再次强调,这仅仅是一个滋味 是摆在面前的东西。 1005 00:44:11,440 --> 00:44:13,090 但是请注意,很多 这是注释。 1006 00:44:13,090 --> 00:44:17,440 所以,我要强调只有 现在有趣的部分。 1007 00:44:17,440 --> 00:44:18,020 typedef的 - 1008 00:44:18,020 --> 00:44:19,700 再次,相同的关键字。 1009 00:44:19,700 --> 00:44:23,100 我们使用的typedef声明串 作为一种特殊的数据类型。 1010 00:44:23,100 --> 00:44:27,490 您可以使用typedef创建新品牌 数据类型时不存在 1011 00:44:27,490 --> 00:44:28,570 C的发明。 1012 00:44:28,570 --> 00:44:32,520 例如,INT与C字符 C.双与C但 1013 00:44:32,520 --> 00:44:34,000 有没有一个学生的概念。 1014 00:44:34,000 --> 00:44:37,230 然而,这将是非常有用的 能够写一个程序,存储 1015 00:44:37,230 --> 00:44:40,440 在一个变量中,一个学生的身份证号码, 他们的名字,他们的房子。 1016 00:44:40,440 --> 00:44:42,890 换句话说,三块 数据,就像一个int和一个 1017 00:44:42,890 --> 00:44:44,420 字符串和另一个字符串。 1018 00:44:44,420 --> 00:44:48,220 >> 用typedef,什么是非常强大的 有关这个关键字sturct的 1019 00:44:48,220 --> 00:44:53,660 结构,你的程序员在2013年, 实际上可以定义你自己的 1020 00:44:53,660 --> 00:44:57,530 数据类型并不存在多年 前,但适合你的目的。 1021 00:44:57,530 --> 00:45:01,910 所以在这里,在13至19线, 我们宣布一个新的数据类型,如 1022 00:45:01,910 --> 00:45:04,320 int,但是调用它的学生。 1023 00:45:04,320 --> 00:45:09,310 这个变量里面去 有三样东西 - 一个int,一个字符串, 1024 00:45:09,310 --> 00:45:09,930 和一个字符串。 1025 00:45:09,930 --> 00:45:13,040 所以,你能想到什么是真正 这里发生的事情,即使这是一个 1026 00:45:13,040 --> 00:45:17,160 位的简化今天, 学生基本上 1027 00:45:17,160 --> 00:45:19,450 这个样子。 1028 00:45:19,450 --> 00:45:22,580 它的将是一大块 存储器与一个ID,一个名字 1029 00:45:22,580 --> 00:45:25,580 场,和房子的领域。 1030 00:45:25,580 --> 00:45:30,670 我们就可以使用这些块 记忆和访问它们,就像如下。 1031 00:45:30,670 --> 00:45:38,870 >> 如果我去成struct0.c,这里是一个 比较长,但后 1032 00:45:38,870 --> 00:45:42,630 柄的代码 使用这种新的伎俩。 1033 00:45:42,630 --> 00:45:45,790 因此,首先让我提请您注意 有趣的部分往上顶。 1034 00:45:45,790 --> 00:45:49,670 夏普定义学生3,宣告了一个 常数,称为学生和受让人 1035 00:45:49,670 --> 00:45:53,450 任意3号,只是 所以我有三个学生使用 1036 00:45:53,450 --> 00:45:54,830 现在这个程序。 1037 00:45:54,830 --> 00:45:55,960 这里主要的。 1038 00:45:55,960 --> 00:45:58,860 通知,我怎么申报 一个阵列学生? 1039 00:45:58,860 --> 00:46:00,480 好吧,我只是使用相同的语法。 1040 00:46:00,480 --> 00:46:02,110 “学生”这个词显然是新的。 1041 00:46:02,110 --> 00:46:04,790 但是,学生类,支架的学生。 1042 00:46:04,790 --> 00:46:06,720 >> 不幸的是,有很多 这里的重用。 1043 00:46:06,720 --> 00:46:07,660 这仅仅是一个数字。 1044 00:46:07,660 --> 00:46:09,040 因此,这是喜欢说三。 1045 00:46:09,040 --> 00:46:11,430 类正是我想要的 调用该变量。 1046 00:46:11,430 --> 00:46:12,840 我可以打电话给学生。 1047 00:46:12,840 --> 00:46:15,880 但类,这是不是一类的 面向对象的Java的一种方式。 1048 00:46:15,880 --> 00:46:17,220 这只是一个班的学生。 1049 00:46:17,220 --> 00:46:20,590 和数据类型中的每一个元素 该数组中是学生。 1050 00:46:20,590 --> 00:46:23,040 因此,这是一个有点不同 说什么 1051 00:46:23,040 --> 00:46:25,250 这样,它只是 - 1052 00:46:25,250 --> 00:46:29,500 我说给我三个学生 并调用该数组类。 1053 00:46:29,500 --> 00:46:29,800 >> 好的。 1054 00:46:29,800 --> 00:46:30,680 现在,这里是一个四循环。 1055 00:46:30,680 --> 00:46:33,480 这家伙的熟悉 - 迭代 从零开始向上增加为三个。 1056 00:46:33,480 --> 00:46:35,160 而这里的新语法。 1057 00:46:35,160 --> 00:46:37,710 程序会提示我, 人类,给它一个学生 1058 00:46:37,710 --> 00:46:39,200 ID,这是一个int。 1059 00:46:39,200 --> 00:46:44,650 而这里的语法,您可以 在ID字段中存储的东西 1060 00:46:44,650 --> 00:46:48,630 位置类支架。所以 这个语法是不是新的。 1061 00:46:48,630 --> 00:46:51,450 这只是意味着给我的第八 学生在课堂上。 1062 00:46:51,450 --> 00:46:52,940 但这个符号是新的。 1063 00:46:52,940 --> 00:46:56,320 到现在为止,我们已经不能用点, 至少在这样的代码。 1064 00:46:56,320 --> 00:47:01,490 这意味着结构被称为 一个学生,把东西放在那里。 1065 00:47:01,490 --> 00:47:05,670 同样,在这下一行,31日去 来吧,把任何用户类型 1066 00:47:05,670 --> 00:47:10,530 这里的名字,为他们做什么 房子,同样的事情,继续前进, 1067 00:47:10,530 --> 00:47:13,230 把它的房子。 1068 00:47:13,230 --> 00:47:15,955 >> 那么,这是什么节目 最终怎么办? 1069 00:47:15,955 --> 00:47:17,220 你可以看到有一点点传情。 1070 00:47:17,220 --> 00:47:24,780 让我继续前进,做结构0 斜线结构,学生的ID 1 0点, 1071 00:47:24,780 --> 00:47:28,250 大卫·马瑟说,学生证2。 1072 00:47:28,250 --> 00:47:32,070 罗布·柯克兰,学生证3。 1073 00:47:32,070 --> 00:47:35,010 劳伦Leverit - 1074 00:47:35,010 --> 00:47:38,380 而唯一做这个程序, 这只是完全是任意的, 1075 00:47:38,380 --> 00:47:40,980 我想,做一些与此数据, 现在,我已经教我们如何 1076 00:47:40,980 --> 00:47:43,450 使用结构,是我刚 这个额外的循环。 1077 00:47:43,450 --> 00:47:45,260 我遍历数组的学生。 1078 00:47:45,260 --> 00:47:49,170 我用了我们,也许是现在熟悉的朋友, 字符串比较,stircomp 1079 00:47:49,170 --> 00:47:53,780 检查第八届学生的家 等于奥美? 1080 00:47:53,780 --> 00:47:56,760 如果是这样,只是打印的东西 随意想,是的,它是。 1081 00:47:56,760 --> 00:47:59,430 但同样,只要给我机会 使用和重用, 1082 00:47:59,430 --> 00:48:02,270 重用这个新的点符号。 1083 00:48:02,270 --> 00:48:03,250 >> 那么,谁在乎呢,对不对? 1084 00:48:03,250 --> 00:48:06,270 即将与学生程序是 有些武断,但事实证明, 1085 00:48:06,270 --> 00:48:09,800 我们可以做的有用的东西 这一点,例如,如下所示。 1086 00:48:09,800 --> 00:48:14,600 这是一个更复杂的结构 C.它得到了一打或更多的领域, 1087 00:48:14,600 --> 00:48:15,880 有些若有所思地命名。 1088 00:48:15,880 --> 00:48:20,110 但是,如果你曾经听说过的一个图形 称为位图文件格式,BMP, 1089 00:48:20,110 --> 00:48:22,830 原来,位图文件格式 相当多,这看起来像。 1090 00:48:22,830 --> 00:48:24,200 这是一个愚蠢的小笑脸。 1091 00:48:24,200 --> 00:48:27,840 这是一个小的形象,我已经放大 相当大的,所以,我可以看到每个 1092 00:48:27,840 --> 00:48:30,410 的单个点或像素。 1093 00:48:30,410 --> 00:48:33,800 现在,事实证明,我们可以代表一个 黑点,说,数字0。 1094 00:48:33,800 --> 00:48:35,520 和一个白点的数量1。 1095 00:48:35,520 --> 00:48:39,140 >> 所以,换句话说,如果你想画一个 笑脸,并保存在该图像 1096 00:48:39,140 --> 00:48:42,680 的计算机,它足以存储“0”和 那些看起来像这样的,在那里, 1097 00:48:42,680 --> 00:48:45,250 再次,那些都是白色的 零是黑色的。 1098 00:48:45,250 --> 00:48:48,290 并在一起,如果你有效 一个网格的1和0,你有一个 1099 00:48:48,290 --> 00:48:51,030 的像素网格,如果你躺在 出来,你有一个可爱的 1100 00:48:51,030 --> 00:48:52,560 小笑脸。 1101 00:48:52,560 --> 00:48:58,150 现在,位图文件格式,BMP, 有效的引擎盖下, 1102 00:48:58,150 --> 00:49:00,970 但随着更多的像素SOT 实际上可以代表颜色。 1103 00:49:00,970 --> 00:49:05,170 >> 但是,当你有更复杂的 如B​​MP,JPEG和GIF文件格式 1104 00:49:05,170 --> 00:49:09,360 你可能熟悉,那些 磁盘上的文件通常不会只 1105 00:49:09,360 --> 00:49:13,760 具有零和一的像素,但 他们有一些元数据,以及 - 1106 00:49:13,760 --> 00:49:16,960 荟萃在这个意义上是不是真的 的数据,但它是非常有用的。 1107 00:49:16,960 --> 00:49:21,370 因此,这些领域的暗示, 我们会看到更详细的P-集合 1108 00:49:21,370 --> 00:49:25,810 5,前的零点和那些 表示图像中的像素, 1109 00:49:25,810 --> 00:49:29,110 有一堆的元数据,如 的图像的大小和 1110 00:49:29,110 --> 00:49:30,250 的图像的宽度。 1111 00:49:30,250 --> 00:49:32,910 注意到我采摘了一些 任意的东西在这里 - 1112 00:49:32,910 --> 00:49:34,260 宽度和高度。 1113 00:49:34,260 --> 00:49:36,160 比特数和其他一些东西。 1114 00:49:36,160 --> 00:49:37,840 因此,有一些在一个文件中的元数据。 1115 00:49:37,840 --> 00:49:41,470 >> 但是,通过了解文件规定 在这种方式,实际上,你可以 1116 00:49:41,470 --> 00:49:45,890 然后处理图像,图像恢复 从盘面看,调整图像。 1117 00:49:45,890 --> 00:49:47,560 但是,你可不一定 增强他们。 1118 00:49:47,560 --> 00:49:48,480 我需要的照片。 1119 00:49:48,480 --> 00:49:52,840 于是我又回到这里到RJ,你看到了谁 前一段时间在屏幕上。 1120 00:49:52,840 --> 00:49:57,160 如果我打开了主题演讲,这是 会发生什么,如果你尝试放大 1121 00:49:57,160 --> 00:49:59,380 加强RJ。 1122 00:49:59,380 --> 00:50:01,480 他没有得到任何好转真的。 1123 00:50:01,480 --> 00:50:06,240 现在的主题是一种模糊它 点点,只是粉饰 1124 00:50:06,240 --> 00:50:11,040 事实上,RJ没有得到特别 增强,当你放大。 1125 00:50:11,040 --> 00:50:13,310 而且如果这样做, 看到广场? 1126 00:50:13,310 --> 00:50:15,490 是的,你绝对可以看到 在投影机上的正方形。 1127 00:50:15,490 --> 00:50:17,690 >> 这是什么时候,你得到提升。 1128 00:50:17,690 --> 00:50:22,570 但在如何理解我们的RJ或 笑脸的实施将让我们 1129 00:50:22,570 --> 00:50:24,950 其实写代码操纵 这些东西。 1130 00:50:24,950 --> 00:50:29,970 我想我会结束这说明, 55秒的提升的, 1131 00:50:29,970 --> 00:50:31,230 我不敢说,很容易误导。 1132 00:50:31,230 --> 00:50:32,990 >> [视频回放] 1133 00:50:32,990 --> 00:50:34,790 >> - 他在说谎。 1134 00:50:34,790 --> 00:50:38,310 关于什么,我不知道。 1135 00:50:38,310 --> 00:50:41,200 >> 所以我们知道什么? 1136 00:50:41,200 --> 00:50:45,280 >> 这在9:15雷Santoya 在ATM。 1137 00:50:45,280 --> 00:50:47,830 >> 那么问题是什么 他在9:16做? 1138 00:50:47,830 --> 00:50:50,750 >> 拍摄9毫米 的东西。 1139 00:50:50,750 --> 00:50:52,615 也许他看到了狙击手。 1140 00:50:52,615 --> 00:50:54,760 >> 或与他一起工作。 1141 00:50:54,760 --> 00:50:56,120 >> - 等待。 1142 00:50:56,120 --> 00:50:57,450 回到之一。 1143 00:50:57,450 --> 00:50:58,700 >> 你看到了什么? 1144 00:50:58,700 --> 00:51:05,530 1145 00:51:05,530 --> 00:51:09,490 >> 把他的脸,全屏。 1146 00:51:09,490 --> 00:51:09,790 >> 他的眼镜。 1147 00:51:09,790 --> 00:51:11,040 >> 有一种体现。 1148 00:51:11,040 --> 00:51:21,790 1149 00:51:21,790 --> 00:51:23,520 >> -这是Neuvitas的棒球队。 1150 00:51:23,520 --> 00:51:24,530 这是他们的标志。 1151 00:51:24,530 --> 00:51:27,040 >> 他说谁 穿着那件夹克。 1152 00:51:27,040 --> 00:51:27,530 >> [END视频播放] 1153 00:51:27,530 --> 00:51:29,180 >> DAVID J.马兰:这将 习题集5。 1154 00:51:29,180 --> 00:51:30,720 我们将看到你下周。 1155 00:51:30,720 --> 00:51:32,330 >> 男扬声器:在未来CS50。 1156 00:51:32,330 --> 00:51:39,240 >> [蟋蟀的鸣叫] 1157 00:51:39,240 --> 00:51:41,270 >> [音乐播放]