1 00:00:00,000 --> 00:00:03,381 >> [音乐播放] 2 00:00:03,381 --> 00:00:10,626 3 00:00:10,626 --> 00:00:11,610 >> [视频回放] 4 00:00:11,610 --> 00:00:13,640 >> - 他在说谎。 5 00:00:13,640 --> 00:00:14,380 >> -关于什么? 6 00:00:14,380 --> 00:00:17,182 >> -我不知道。 7 00:00:17,182 --> 00:00:19,990 >> - 所以我们怎么知道? 8 00:00:19,990 --> 00:00:23,145 >> - 即在9:15,雷 Santoya是在自动取款机。 9 00:00:23,145 --> 00:00:23,644 - 是啊。 10 00:00:23,644 --> 00:00:27,030 所以,问题是,什么样 是他在9:16做什么? 11 00:00:27,030 --> 00:00:29,720 >> -Shooting的9毫米的东西。 12 00:00:29,720 --> 00:00:31,540 也许他看到了狙击手。 13 00:00:31,540 --> 00:00:33,412 >> - 或者是和他一起工作。 14 00:00:33,412 --> 00:00:34,340 >> -Wait。 15 00:00:34,340 --> 00:00:36,200 回到之一。 16 00:00:36,200 --> 00:00:36,975 >> -你看到了什么? 17 00:00:36,975 --> 00:00:44,400 18 00:00:44,400 --> 00:00:47,805 >> -Bring脸上了整个屏幕。 19 00:00:47,805 --> 00:00:48,680 >> -His眼镜。 20 00:00:48,680 --> 00:00:50,060 >> - 存在的一种反映。 21 00:00:50,060 --> 00:01:00,455 22 00:01:00,455 --> 00:01:02,280 >> - 它是在努埃维塔斯棒球队。 23 00:01:02,280 --> 00:01:03,110 这是他们的标志。 24 00:01:03,110 --> 00:01:05,820 >> - 和他交谈 谁穿着那件夹克衫。 25 00:01:05,820 --> 00:01:06,670 >> [结束播放] 26 00:01:06,670 --> 00:01:07,628 >> DAVID马兰:好的。 27 00:01:07,628 --> 00:01:11,210 这是CS50,这是一个有点多 的[听不清]与你 28 00:01:11,210 --> 00:01:12,890 有问题的涉足设4。 29 00:01:12,890 --> 00:01:16,606 今天我们先来了解一下多一点 深入这些东西叫做三分球, 30 00:01:16,606 --> 00:01:18,480 这即使它 一个非常神秘的话题, 31 00:01:18,480 --> 00:01:20,813 事实证明,这是怎么回事 是通过何种途径,我们 32 00:01:20,813 --> 00:01:24,320 可以开始构建和组装 更复杂的方案。 33 00:01:24,320 --> 00:01:28,150 但是我们做到了上周三 一些粘土动画的第一种方式。 34 00:01:28,150 --> 00:01:30,190 所以这一点,召回,是 宾基,我们用他 35 00:01:30,190 --> 00:01:33,148 要看一看一个程序, 真的没有做什么有趣的事, 36 00:01:33,148 --> 00:01:34,950 但它确实揭示了一些问题。 37 00:01:34,950 --> 00:01:38,570 因此,为了从今天开始,我们为什么不走 快速通过几个步骤, 38 00:01:38,570 --> 00:01:41,920 尝试提炼到人的方面 什么是怎么回事 39 00:01:41,920 --> 00:01:45,410 为什么这是不好的,然后继续前进 而真正开始构建的东西 40 00:01:45,410 --> 00:01:46,309 这种技术? 41 00:01:46,309 --> 00:01:48,350 因此,这些是第一 该程序中的两行 42 00:01:48,350 --> 00:01:51,340 在通俗地说,是什么 在这两条线在做什么? 43 00:01:51,340 --> 00:01:55,600 有人谁是相当舒适 用什么屏幕上的声明? 44 00:01:55,600 --> 00:01:58,340 45 00:01:58,340 --> 00:02:00,120 什么是这两条线在做什么? 46 00:02:00,120 --> 00:02:02,070 这还不是所有的 从一周不同, 47 00:02:02,070 --> 00:02:03,611 但有一些新的特殊符号。 48 00:02:03,611 --> 00:02:04,152 是吗? 49 00:02:04,152 --> 00:02:05,628 回到那里。 50 00:02:05,628 --> 00:02:07,092 >> 听众:声明指针? 51 00:02:07,092 --> 00:02:08,050 DAVID马兰:再说一遍吗? 52 00:02:08,050 --> 00:02:08,860 听众:声明指针? 53 00:02:08,860 --> 00:02:11,776 DAVID马兰:声明指针和 让我们来完善它多一点点。 54 00:02:11,776 --> 00:02:14,050 听众:[听不清] 地址X,那么y。 55 00:02:14,050 --> 00:02:15,300 DAVID马兰:然后解决。 56 00:02:15,300 --> 00:02:18,550 那么具体是什么,我们正在做 是我们宣布的两个变量。 57 00:02:18,550 --> 00:02:21,252 这些变量,虽然,将会 是int类型的明星,哪 58 00:02:21,252 --> 00:02:23,210 更具体地指 他们将要存储 59 00:02:23,210 --> 00:02:26,450 一个int的地址, 分别使用x和y。 60 00:02:26,450 --> 00:02:27,660 现在还有什么价值? 61 00:02:27,660 --> 00:02:32,621 有没有在这些任何实际地址 两个变量在这个时间点? 62 00:02:32,621 --> 00:02:33,120 第 63 00:02:33,120 --> 00:02:35,030 这只是所谓的垃圾值。 64 00:02:35,030 --> 00:02:38,120 如果你不实际分配 变量,无论是在RAM中 65 00:02:38,120 --> 00:02:42,224 以前是要填补零 和那些这两个变量。 66 00:02:42,224 --> 00:02:44,140 但是,我们还不知道 它们是什么,这就是 67 00:02:44,140 --> 00:02:47,060 将是关键,为什么宾基 上周失去了他的头。 68 00:02:47,060 --> 00:02:49,980 >> 因此,这是粘土动画 这个化身 69 00:02:49,980 --> 00:02:53,580 因此你只有两个变量, 小环形件粘土, 70 00:02:53,580 --> 00:02:57,330 可以存储的变量,但作为 该包裹起来箭头提示, 71 00:02:57,330 --> 00:03:00,640 他们不是真正指向 到任何地方本身已知。 72 00:03:00,640 --> 00:03:03,670 于是,我们有这条线,这 是新的,上周的malloc内存 73 00:03:03,670 --> 00:03:07,130 分配,这仅仅是一个奇特的方式 告诉操作系统,Linux的的 74 00:03:07,130 --> 00:03:09,750 或Mac OS或Windows, 嘿,给我一些记忆, 75 00:03:09,750 --> 00:03:11,780 而你要告诉 操作系统 76 00:03:11,780 --> 00:03:14,699 就是要求它的内存时。 77 00:03:14,699 --> 00:03:16,990 它不会去关心什么 你会用它做什么, 78 00:03:16,990 --> 00:03:19,786 但你需要告诉工作 什么系统由malloc的方式。 79 00:03:19,786 --> 00:03:20,286 是吗? 80 00:03:20,286 --> 00:03:21,078 >> 听众:多少钱? 81 00:03:21,078 --> 00:03:21,994 DAVID马兰:多少钱? 82 00:03:21,994 --> 00:03:25,280 多少字节,所以,这再次 一个人为的例子,只是说, 83 00:03:25,280 --> 00:03:27,360 给我一个int的大小。 84 00:03:27,360 --> 00:03:30,550 一个int现在,大小 是四字节或32位。 85 00:03:30,550 --> 00:03:32,850 因此,这只是一种方式 他说,嘿,操作系统, 86 00:03:32,850 --> 00:03:37,290 给我4个字节的内存 我可以用在我手上, 87 00:03:37,290 --> 00:03:40,560 具体有哪些呢 malloc的收益相对于 88 00:03:40,560 --> 00:03:41,795 以四个字节块? 89 00:03:41,795 --> 00:03:44,110 90 00:03:44,110 --> 00:03:44,860 听众:地址? 91 00:03:44,860 --> 00:03:45,901 DAVID马兰:地址。 92 00:03:45,901 --> 00:03:47,580 四个字节块的地址。 93 00:03:47,580 --> 00:03:48,190 没错。 94 00:03:48,190 --> 00:03:51,430 所以这就是所储存的最终 在x和这就是为什么我们真的不 95 00:03:51,430 --> 00:03:55,240 关心的是,数 地址是,无论是OX1或OX2 96 00:03:55,240 --> 00:03:57,110 或者一些神秘的十六进制地址。 97 00:03:57,110 --> 00:03:59,850 我们只关心形象化 那该变量x是现在 98 00:03:59,850 --> 00:04:01,630 指向的内存块。 99 00:04:01,630 --> 00:04:05,570 这样的箭头表示的指针,或 更具体地说,存储器地址。 100 00:04:05,570 --> 00:04:09,120 但是再次,我们并不关心通常 什么样的实际地址。 101 00:04:09,120 --> 00:04:11,780 现在,这条线说: 什么通俗地说? 102 00:04:11,780 --> 00:04:14,330 星x被42分号。 103 00:04:14,330 --> 00:04:17,390 这是什么意思? 104 00:04:17,390 --> 00:04:18,200 你想去? 105 00:04:18,200 --> 00:04:20,102 不要划伤你的脖子。 106 00:04:20,102 --> 00:04:22,360 >> 听众:x的地址是在42。 107 00:04:22,360 --> 00:04:24,300 >> DAVID马兰:x的地址是42位。 108 00:04:24,300 --> 00:04:25,190 不太。 109 00:04:25,190 --> 00:04:28,485 如此接近,但并不完全,因为有 多数民众赞成这个前缀X中的明星。 110 00:04:28,485 --> 00:04:29,860 因此,我们需要调整一点点。 111 00:04:29,860 --> 00:04:31,032 是吗? 112 00:04:31,032 --> 00:04:36,044 >> 听众:值了 指针x被指向的是42。 113 00:04:36,044 --> 00:04:36,710 DAVID马兰:OK。 114 00:04:36,710 --> 00:04:40,840 的值,该指针x是 指着,让我们说,应是42, 115 00:04:40,840 --> 00:04:44,165 或者换一种方式,星 x说,去到任何地址 116 00:04:44,165 --> 00:04:48,340 在X,无论是1牛津 街或33牛津街 117 00:04:48,340 --> 00:04:51,850 或OX1或ox33,无论 该数字地址, 118 00:04:51,850 --> 00:04:54,380 明星x是x的间接引用。 119 00:04:54,380 --> 00:04:57,297 所以去该地址并 然后把数字42出现。 120 00:04:57,297 --> 00:04:59,380 因此,这将是一个 的话说,相当于途径。 121 00:04:59,380 --> 00:05:01,860 所以这一切都很好,然后 我们将代表图象 122 00:05:01,860 --> 00:05:05,370 如下所示,我们已经添加 42到四个是块 123 00:05:05,370 --> 00:05:09,370 字节上的右手边,但 这条线是那里的东西去了歪 124 00:05:09,370 --> 00:05:11,120 和宾基的头部弹出 关于这一点, 125 00:05:11,120 --> 00:05:15,290 因为不好的事情发生时, 取消引用垃圾值 126 00:05:15,290 --> 00:05:18,210 或取消引用无效 指针和我说无效 127 00:05:18,210 --> 00:05:21,020 因为在这一点上,在 故事,什么是Y的内部? 128 00:05:21,020 --> 00:05:24,440 什么是Y的基础价值 在过去的几个步骤? 129 00:05:24,440 --> 00:05:25,360 是吗? 130 00:05:25,360 --> 00:05:26,115 那是什么? 131 00:05:26,115 --> 00:05:26,990 >> 听众:一个地址。 132 00:05:26,990 --> 00:05:28,460 DAVID马兰:地址。 133 00:05:28,460 --> 00:05:31,910 它应是一个地址 但我初始化呢? 134 00:05:31,910 --> 00:05:32,800 所以我还没有。 135 00:05:32,800 --> 00:05:35,430 那么,什么是已知的在那里? 136 00:05:35,430 --> 00:05:37,590 这只是一些垃圾的价值。 137 00:05:37,590 --> 00:05:41,500 它可以是从零到任何地址 2十亿,如果你的RAM 2演出, 138 00:05:41,500 --> 00:05:44,289 或零4个十亿,如果你已经 有4 GB的RAM。 139 00:05:44,289 --> 00:05:46,080 这是一些垃圾的价值, 但问题是 140 00:05:46,080 --> 00:05:48,200 操作系统, 如果没有给你 141 00:05:48,200 --> 00:05:51,140 该内存块专 你试图去, 142 00:05:51,140 --> 00:05:54,650 它通常会导致什么 我们已经看到了一个分段错误。 143 00:05:54,650 --> 00:05:57,810 所以,事实上,任何你们谁 在挣扎于办公时间问题 144 00:05:57,810 --> 00:06:00,393 或者问题,更 通常,试图找出 145 00:06:00,393 --> 00:06:02,150 段错误, 这通常意味着 146 00:06:02,150 --> 00:06:05,017 你触摸的段 内存,你不应该。 147 00:06:05,017 --> 00:06:07,350 你触摸内存 操作系统有不 148 00:06:07,350 --> 00:06:10,450 让你触摸,无论是 通过去太远阵列 149 00:06:10,450 --> 00:06:12,870 或者从现在开始,无论是 那是因为你接触 150 00:06:12,870 --> 00:06:14,780 内存仅仅是一些垃圾的价值。 151 00:06:14,780 --> 00:06:18,230 >> 这样算下来星X这里是 那种不确定的行为。 152 00:06:18,230 --> 00:06:22,030 你不应该这样做,因为赔率 是,该方案只是将崩溃, 153 00:06:22,030 --> 00:06:24,050 因为你说, 去这个地址 154 00:06:24,050 --> 00:06:27,000 你不知道在哪里 该地址实际上是。 155 00:06:27,000 --> 00:06:30,300 因此操作系统很可能 将你的程序崩溃 156 00:06:30,300 --> 00:06:33,840 因此,事实上,这是 那里发生的事情来宾基。 157 00:06:33,840 --> 00:06:37,210 所以,最后,宾基固定 此问题与此。 158 00:06:37,210 --> 00:06:38,909 这样程序本身是有缺陷的。 159 00:06:38,909 --> 00:06:41,450 但是,如果你之类的锐意进取 并执行此行,而不是, 160 00:06:41,450 --> 00:06:45,580 Ÿ度等于x只是意味着什么 地址是一个X,也把它的年。 161 00:06:45,580 --> 00:06:48,740 >> 因此形象化,我们已经 有两个箭头表示这 162 00:06:48,740 --> 00:06:51,570 从x和从y中指点 同一个地方。 163 00:06:51,570 --> 00:06:55,760 因此语义,x等于 为y,因为这两项的 164 00:06:55,760 --> 00:07:00,300 都存储相同 地址,ERGO指着42, 165 00:07:00,300 --> 00:07:04,910 而现在,当你说明星 Y,转到地址Y, 166 00:07:04,910 --> 00:07:06,790 这有一个有趣的副作用。 167 00:07:06,790 --> 00:07:10,320 因此,在y中的地址是 同样的事情在X中的地址。 168 00:07:10,320 --> 00:07:15,060 所以,如果你说去地址 在Y和值更改为13, 169 00:07:15,060 --> 00:07:17,140 还有谁受影响? 170 00:07:17,140 --> 00:07:21,100 X的,点D,可以这么说, 应该受到影响。 171 00:07:21,100 --> 00:07:24,340 >> 事实上,尼克怎么画了这幅画 在粘土动画正是这一点。 172 00:07:24,340 --> 00:07:28,665 即使我们按照指针 Y,我们结束了在同一个地方, 173 00:07:28,665 --> 00:07:32,780 所以,如果我们要打印 出X或Y的指针对象, 174 00:07:32,780 --> 00:07:35,720 那么我们将看到13的值。 175 00:07:35,720 --> 00:07:37,927 现在,我说指针对象是 与视频一致。 176 00:07:37,927 --> 00:07:39,760 程序员,我 知识,从来没有真正 177 00:07:39,760 --> 00:07:42,460 说一句话指针对象, 这是尖 178 00:07:42,460 --> 00:07:44,650 在,但对于一致性 与视频,实现 179 00:07:44,650 --> 00:07:47,520 这一切,这是 意味着在这种情况下。 180 00:07:47,520 --> 00:07:54,190 因此,对粘土动画有任何疑问 或指针或malloc的,只是还没有? 181 00:07:54,190 --> 00:07:54,850 没有? 182 00:07:54,850 --> 00:07:55,470 好吧。 183 00:07:55,470 --> 00:07:58,560 >> 因此,没有进一步的 废话不多说,让我们一起来看看 184 00:07:58,560 --> 00:08:00,700 在其中,这实际上已经 已经使用了一段时间。 185 00:08:00,700 --> 00:08:03,580 因此,我们有这个CS50库 这得到了所有这些功能。 186 00:08:03,580 --> 00:08:06,810 我们使用调用getInt很多,GetString的, 也许更早GetLongLong 187 00:08:06,810 --> 00:08:09,840 在我的PSET一左右,但 什么实际已经持续? 188 00:08:09,840 --> 00:08:12,920 好吧,让我们快速浏览一下 罩在一个程序下方那 189 00:08:12,920 --> 00:08:17,017 激励我们为什么给你CS50 图书馆,实际上截至上周, 190 00:08:17,017 --> 00:08:18,850 我们开始采取这些 训练车轮关闭。 191 00:08:18,850 --> 00:08:21,080 因此,这是现在排序 一个死后是什么 192 00:08:21,080 --> 00:08:23,690 已经持续 在CS50库中, 193 00:08:23,690 --> 00:08:27,250 即使我们现在将开始移动 远离它对于大多数程序。 194 00:08:27,250 --> 00:08:29,460 >> 因此,这是一个名为scanf函数0的程序。 195 00:08:29,460 --> 00:08:30,510 它的超级短。 196 00:08:30,510 --> 00:08:33,909 它只是这些行,但它 引入了一个函数调用scanf函数 197 00:08:33,909 --> 00:08:36,909 那我们究竟要看到 片刻CS50库里面, 198 00:08:36,909 --> 00:08:38,600 尽管在一个稍微不同的形式。 199 00:08:38,600 --> 00:08:41,330 所以这个方案行16 正在申报一个变量x。 200 00:08:41,330 --> 00:08:43,150 所以给我四个字节为一个int。 201 00:08:43,150 --> 00:08:45,750 它在告诉用户, 号码请,然后 202 00:08:45,750 --> 00:08:49,010 这是一个有趣的行 上周实际联系在一起 203 00:08:49,010 --> 00:08:49,790 和这个。 204 00:08:49,790 --> 00:08:53,230 scanf函数,然后发现它需要一个 格式字符串,就像printf的, 205 00:08:53,230 --> 00:08:57,480 %我是指一个int,然后它需要一个 这看起来有点第二个参数 206 00:08:57,480 --> 00:08:58,260 时髦。 207 00:08:58,260 --> 00:09:01,880 它的符号x和召回, 我们只有这一次看到上周。 208 00:09:01,880 --> 00:09:03,465 这是什么符号的x代表? 209 00:09:03,465 --> 00:09:06,210 210 00:09:06,210 --> 00:09:08,450 C语言是什么符号呢? 211 00:09:08,450 --> 00:09:08,950 是吗? 212 00:09:08,950 --> 00:09:10,024 >> 听众:地址。 213 00:09:10,024 --> 00:09:11,190 DAVID马兰:的地址。 214 00:09:11,190 --> 00:09:13,190 因此,它是相反的 星运营商, 215 00:09:13,190 --> 00:09:17,270 而明星接线员说,去 这个地址,符号运算符 216 00:09:17,270 --> 00:09:20,280 说,计算出 这个变量的地址, 217 00:09:20,280 --> 00:09:23,530 所以这是关键,因为 scanf函数的人生目标 218 00:09:23,530 --> 00:09:26,320 是扫描用户的 从键盘输入, 219 00:09:26,320 --> 00:09:29,970 根据不管他或她 类型,然后读取该用户的输入 220 00:09:29,970 --> 00:09:32,970 成可变的,但我们 在过去两个星期看到 221 00:09:32,970 --> 00:09:36,080 这是交换功能,我们 试图轻松实现 222 00:09:36,080 --> 00:09:37,110 刚刚打破。 223 00:09:37,110 --> 00:09:42,470 回想一下,与交换功能, 如果我们只是宣布A和B为整数, 224 00:09:42,470 --> 00:09:47,040 我们也成功地交换 互换中的两个变量 225 00:09:47,040 --> 00:09:50,080 只是想用牛奶和OJ, 但只要换回来了, 226 00:09:50,080 --> 00:09:55,200 结果是什么就 x和y,原始值? 227 00:09:55,200 --> 00:09:55,700 什么也没有。 228 00:09:55,700 --> 00:09:56,200 是啊。 229 00:09:56,200 --> 00:09:59,754 什么都没有发生的时候,因为 掉期只改变它的本地副本, 230 00:09:59,754 --> 00:10:01,670 这就是说,所有 这个时候,每当我们已经 231 00:10:01,670 --> 00:10:04,010 被传入的参数 到功能,我们 232 00:10:04,010 --> 00:10:05,939 刚好路过的那些参数的拷贝。 233 00:10:05,939 --> 00:10:07,980 你可以用那些 无论你想和他们在一起, 234 00:10:07,980 --> 00:10:10,890 但他们将不得不无 上的原始值影响。 235 00:10:10,890 --> 00:10:13,650 因此,这是有问题的,如果你 想拥有像scanf函数的函数 236 00:10:13,650 --> 00:10:17,170 在生活中,其目的是要扫描 用户的从键盘输入 237 00:10:17,170 --> 00:10:22,010 然后填补空白,所以 说话,就是给如x变量 238 00:10:22,010 --> 00:10:25,410 一个值,因为如果我是 只是传递X到scanf函数, 239 00:10:25,410 --> 00:10:28,790 如果你考虑最后的逻辑 本周,scanf函数可以为所欲为 240 00:10:28,790 --> 00:10:33,100 与x的拷贝,但它不能 永久x更改,除非我们放弃 241 00:10:33,100 --> 00:10:37,120 scanf的藏宝图,可以这么说, 因此,其中的X标记的位置, 242 00:10:37,120 --> 00:10:41,860 我们通过x的地址,以便 scanf函数可以去那里其实是一个改变 243 00:10:41,860 --> 00:10:42,920 x的值。 244 00:10:42,920 --> 00:10:45,080 所以,事实上,所有的 这个程序会 245 00:10:45,080 --> 00:10:53,180 如果我做的scanf 0,在我的源代码 5米目录,使scanf函数0, 246 00:10:53,180 --> 00:10:57,730 点斜线scanf函数,数 请50,感谢50。 247 00:10:57,730 --> 00:11:01,020 >> 因此,它不是那么有趣, 但什么是确实发生的事情 248 00:11:01,020 --> 00:11:04,820 是,只要我打电话 的scanf这里,x的值 249 00:11:04,820 --> 00:11:06,410 被永久改变。 250 00:11:06,410 --> 00:11:08,335 现在,这似乎不错, 好,而且,事实上,它 251 00:11:08,335 --> 00:11:11,200 看起来我们并不真正需要的 在CS50库在所有了。 252 00:11:11,200 --> 00:11:13,960 例如,让我们运行 这一次在这里。 253 00:11:13,960 --> 00:11:15,750 让我重新打开第二个。 254 00:11:15,750 --> 00:11:20,600 让我们尝试了一些,请与 而不是说50像以前一样, 255 00:11:20,600 --> 00:11:22,810 我们只能说没有。 256 00:11:22,810 --> 00:11:24,000 OK,这是一个有点怪异。 257 00:11:24,000 --> 00:11:25,270 行。 258 00:11:25,270 --> 00:11:28,680 而只是一些废话这里。 259 00:11:28,680 --> 00:11:31,170 因此,它似乎并没有 处理错误的情况。 260 00:11:31,170 --> 00:11:33,620 因此,我们需要最小的开始 加入一些错误检查 261 00:11:33,620 --> 00:11:37,460 以确保用户具有 键入的实​​际数目的像50, 262 00:11:37,460 --> 00:11:40,720 因为很明显打字的话 不被检测为有问题的, 263 00:11:40,720 --> 00:11:42,020 但它可能应该是。 264 00:11:42,020 --> 00:11:46,450 >> 让我们来看看这个版本现在是 我试图重新实现的GetString。 265 00:11:46,450 --> 00:11:48,437 如果scanf函数有这一切 功能内置, 266 00:11:48,437 --> 00:11:51,270 为什么我们已经涉足这些 培训车轮状的GetString? 267 00:11:51,270 --> 00:11:55,450 好了,下面也许是我自己 简单的GetString版本 268 00:11:55,450 --> 00:12:00,766 因此一个星期前,我可能会说, 给我一个字符串,并将其命名为缓冲区。 269 00:12:00,766 --> 00:12:03,390 今天,我要开始只是 话说焦明星,其中,召回, 270 00:12:03,390 --> 00:12:04,400 它只是代名词。 271 00:12:04,400 --> 00:12:06,629 它看起来可怕,但它 同样的事情。 272 00:12:06,629 --> 00:12:09,420 所以给我一个变量叫做缓冲 那将存放的字符串, 273 00:12:09,420 --> 00:12:12,780 告诉用户字符串请 然后,就像以前一样, 274 00:12:12,780 --> 00:12:17,760 让我们尝试借用这一课的scanf %S这个时候再通过缓冲区。 275 00:12:17,760 --> 00:12:19,310 现在,一个快速的完整性检查。 276 00:12:19,310 --> 00:12:22,120 为什么我不能说 符号缓冲这段时间? 277 00:12:22,120 --> 00:12:25,190 278 00:12:25,190 --> 00:12:26,625 从前面的例子推断。 279 00:12:26,625 --> 00:12:28,000 听众:字符明星是一个指针。 280 00:12:28,000 --> 00:12:29,920 DAVID马兰:没错, 因为这个时候,炭 281 00:12:29,920 --> 00:12:34,080 星已经是一个指针,一个地址, 由明星在那里的定义。 282 00:12:34,080 --> 00:12:37,530 并且如果scanf的期望一个地址, 它足以只是为了打发在缓冲区中。 283 00:12:37,530 --> 00:12:39,260 我不需要说了连字符缓冲区。 284 00:12:39,260 --> 00:12:42,177 对于好奇的,你可以 做这样的事情。 285 00:12:42,177 --> 00:12:43,510 它将有不同的意义。 286 00:12:43,510 --> 00:12:47,240 这会给你一个指针 一个指针,它实际上是 287 00:12:47,240 --> 00:12:50,050 一个有效的东西在C中,但对于 现在,让我们保持简单 288 00:12:50,050 --> 00:12:51,750 和保持故事的连贯。 289 00:12:51,750 --> 00:12:54,100 我只是要传递 缓冲,这就是正确的。 290 00:12:54,100 --> 00:12:56,487 这个问题虽然是这样的。 291 00:12:56,487 --> 00:12:58,820 让我继续前进,运行这个 编译后的程序。 292 00:12:58,820 --> 00:13:00,902 让scanf函数1。 293 00:13:00,902 --> 00:13:02,610 该死的,我的编译器 抓住我的错误。 294 00:13:02,610 --> 00:13:04,090 给我一秒钟。 295 00:13:04,090 --> 00:13:05,460 锵。 296 00:13:05,460 --> 00:13:06,990 比方说,scanf函数,1.C。 297 00:13:06,990 --> 00:13:10,880 298 00:13:10,880 --> 00:13:11,380 行。 299 00:13:11,380 --> 00:13:12,720 在那里,我们走了。 300 00:13:12,720 --> 00:13:14,280 我需要它。 301 00:13:14,280 --> 00:13:16,750 CS50 ID有不同 配置设置 302 00:13:16,750 --> 00:13:18,280 保护您免受自己。 303 00:13:18,280 --> 00:13:21,300 我需要禁用那些 手动运行铛这个时候。 304 00:13:21,300 --> 00:13:22,140 所以字符串请。 305 00:13:22,140 --> 00:13:25,560 我要继续前进,并键入 在我最喜欢的Hello World。 306 00:13:25,560 --> 00:13:26,490 OK,空。 307 00:13:26,490 --> 00:13:27,700 这不是我所输入的。 308 00:13:27,700 --> 00:13:29,690 因此,它指示 什么是错的。 309 00:13:29,690 --> 00:13:33,920 让我继续前进,键入 在很长的字符串。 310 00:13:33,920 --> 00:13:37,210 感谢您的空,我不知道 如果我将能够让它崩溃。 311 00:13:37,210 --> 00:13:40,240 让我们试着一点点副本 粘贴,看看这会有所帮助。 312 00:13:40,240 --> 00:13:43,290 刚贴了很多本。 313 00:13:43,290 --> 00:13:47,310 这绝对是一个更大的 字符串比平常。 314 00:13:47,310 --> 00:13:51,450 让我们真的把它写。 315 00:13:51,450 --> 00:13:51,950 第 316 00:13:51,950 --> 00:13:52,650 该死的。 317 00:13:52,650 --> 00:13:53,480 找不到命令。 318 00:13:53,480 --> 00:13:54,550 所以这是不相关的。 319 00:13:54,550 --> 00:13:56,440 那是因为我粘贴 一些不好的字, 320 00:13:56,440 --> 00:13:59,780 但事实证明这是行不通的。 321 00:13:59,780 --> 00:14:03,510 >> 让我们试试这个曾经多,因为 它更多的乐趣,如果我们真的崩溃了。 322 00:14:03,510 --> 00:14:09,116 让我们输入这个,现在,我 要复制一个很长的字符串 323 00:14:09,116 --> 00:14:10,990 现在就让如果我们看看 可能会崩溃这件事。 324 00:14:10,990 --> 00:14:14,235 请注意,我省略了空间和 新的生产线和分号 325 00:14:14,235 --> 00:14:16,035 和所有时髦的人物。 326 00:14:16,035 --> 00:14:16,535 输入。 327 00:14:16,535 --> 00:14:21,090 328 00:14:21,090 --> 00:14:22,880 而现在的网络只是正在缓慢。 329 00:14:22,880 --> 00:14:27,460 我按住Command-V键太长,清晰。 330 00:14:27,460 --> 00:14:28,190 该死的! 331 00:14:28,190 --> 00:14:29,260 找不到命令。 332 00:14:29,260 --> 00:14:29,780 >> 行。 333 00:14:29,780 --> 00:14:32,240 那么,问题是 尽管如此以下。 334 00:14:32,240 --> 00:14:36,910 那么什么是真正会 与此声明 335 00:14:36,910 --> 00:14:39,240 的第16行字符星缓冲? 336 00:14:39,240 --> 00:14:41,820 所以,我是什么让 当我宣布一个指针? 337 00:14:41,820 --> 00:14:47,440 所有我得到是一个四字节的值 所谓的缓冲区,但什么是它的内部 338 00:14:47,440 --> 00:14:49,540 眼下? 339 00:14:49,540 --> 00:14:50,930 这只是一些垃圾的价值。 340 00:14:50,930 --> 00:14:54,170 因为任何时候你声明一个变量 在C,它只是一些垃圾的价值, 341 00:14:54,170 --> 00:14:56,220 我们已经开始 绊倒这个现实。 342 00:14:56,220 --> 00:14:59,720 现在,当我告诉scanf函数, 去这个地址 343 00:14:59,720 --> 00:15:01,520 并把在不管用户类型。 344 00:15:01,520 --> 00:15:06,400 如果在用户键入你好 世界上,还有,我在哪里放呢? 345 00:15:06,400 --> 00:15:07,750 缓冲区是一个垃圾的价值。 346 00:15:07,750 --> 00:15:11,510 >> 所以这有点像一个箭头 该指针谁知道在哪里。 347 00:15:11,510 --> 00:15:13,880 也许它指向 这里在我的记忆中。 348 00:15:13,880 --> 00:15:16,560 因此,当用户 类型的hello world, 349 00:15:16,560 --> 00:15:22,380 该计划试图把 字符串的hello world反斜线0 350 00:15:22,380 --> 00:15:23,910 该内存块。 351 00:15:23,910 --> 00:15:27,070 但是高概率,但 显然不是100%的概率, 352 00:15:27,070 --> 00:15:30,440 计算机将要然后崩溃 程序,因为这不是 353 00:15:30,440 --> 00:15:32,490 内存我应该被允许触摸。 354 00:15:32,490 --> 00:15:36,330 因此,在短期,这一计划是 有缺陷的正是这个原因。 355 00:15:36,330 --> 00:15:38,070 我根本没有做什么的? 356 00:15:38,070 --> 00:15:42,366 有哪些步骤我省略了,就像 我们省略了与宾基的第一个例子? 357 00:15:42,366 --> 00:15:42,866 是吗? 358 00:15:42,866 --> 00:15:43,710 >> 听众:内存分配? 359 00:15:43,710 --> 00:15:45,001 >> DAVID马兰:内存分配。 360 00:15:45,001 --> 00:15:48,400 我还没有实际分配 任何内存该字符串。 361 00:15:48,400 --> 00:15:50,270 所以我们可以在几个方式解决这个问题。 362 00:15:50,270 --> 00:15:52,700 第一,我们可以保持简单 而事实上,现在你 363 00:15:52,700 --> 00:15:55,116 将开始看到一个模糊 之间有什么行 364 00:15:55,116 --> 00:15:58,520 数组是什么,一个字符串是什么 炭明星,字符什么数组 365 00:15:58,520 --> 00:15:59,020 是。 366 00:15:59,020 --> 00:16:02,450 下面是第二个例子 涉及字符串和通知 367 00:16:02,450 --> 00:16:05,690 所有我已经在网上做了 16是不是说, 368 00:16:05,690 --> 00:16:09,530 该缓冲区将是一个char 明星,一个指向一个内存块, 369 00:16:09,530 --> 00:16:14,057 我会很主动地给 我自己一个缓冲的16个字符, 370 00:16:14,057 --> 00:16:16,390 而事实上,如果你熟悉 与术语缓冲, 371 00:16:16,390 --> 00:16:20,570 大概从影片的世界里, 其中,一个视频缓冲,缓冲, 372 00:16:20,570 --> 00:16:21,175 缓冲。 373 00:16:21,175 --> 00:16:22,550 那么,什么是连接这里? 374 00:16:22,550 --> 00:16:24,960 YouTube的嘛,里面 和视频播放器内 375 00:16:24,960 --> 00:16:27,200 通常是一个数组 这是大于16。 376 00:16:27,200 --> 00:16:30,340 它可能是大小为一的阵列 兆字节,也许10兆, 377 00:16:30,340 --> 00:16:34,330 进入该数组做您的浏览器 下载一个一大堆字节, 378 00:16:34,330 --> 00:16:37,500 一大堆的兆字节 视频和视频播放器, 379 00:16:37,500 --> 00:16:40,930 YouTube的还是谁的,开始 从阵列读取的字节数, 380 00:16:40,930 --> 00:16:43,530 任何时候你看到的 字缓冲,缓冲, 381 00:16:43,530 --> 00:16:46,350 这意味着该播放器具有 得到该数组的末尾。 382 00:16:46,350 --> 00:16:50,430 该网络是如此缓慢,它并没有 回填数组有更多的字节 383 00:16:50,430 --> 00:16:55,610 所以你出位 以显示给用户。 384 00:16:55,610 --> 00:16:59,430 >> 因此,缓冲区是一个恰当的词在这里是 它只是一个数组,一个内存块。 385 00:16:59,430 --> 00:17:02,530 这将解决这个问题 因为事实证明 386 00:17:02,530 --> 00:17:07,410 你可以把数组,就好像 他们的地址,即使缓冲区 387 00:17:07,410 --> 00:17:10,710 仅仅是一个符号,它是一个 字符序列,缓冲液, 388 00:17:10,710 --> 00:17:14,760 这对我来说是非常有用的,程序员, 你可以通过周围的名字 389 00:17:14,760 --> 00:17:17,079 就好像它是一个 指针,就好像它 390 00:17:17,079 --> 00:17:21,000 是一个组块的地址 内存为16个字符。 391 00:17:21,000 --> 00:17:24,530 所以这是说,我可以通过 scanf函数正是那个词 392 00:17:24,530 --> 00:17:30,670 所以现在,如果我做这个节目, 让scanf函数2,点斜线scanf函数2, 393 00:17:30,670 --> 00:17:35,386 和类型的hello world, 回车,即时间 - 394 00:17:35,386 --> 00:17:37,590 >> 嗯,什么事? 395 00:17:37,590 --> 00:17:39,340 字符串请。 396 00:17:39,340 --> 00:17:41,430 我做了什么错? 397 00:17:41,430 --> 00:17:43,800 世界您好,缓冲区。 398 00:17:43,800 --> 00:17:44,705 你好世界。 399 00:17:44,705 --> 00:17:48,201 400 00:17:48,201 --> 00:17:49,420 嗯,我知道它在做什么。 401 00:17:49,420 --> 00:17:49,920 行。 402 00:17:49,920 --> 00:17:51,628 因此,它的读了 直到第一空间。 403 00:17:51,628 --> 00:17:55,680 因此,让我们骗了就一下 说我只是想输入的东西 404 00:17:55,680 --> 00:18:01,408 真的长的很像,这是一个长句子 这是一个,两个,三个,四个,五个, 405 00:18:01,408 --> 00:18:04,420 六,七,八,九, 10,11,12,13,14,15,16。 406 00:18:04,420 --> 00:18:05,300 行。 407 00:18:05,300 --> 00:18:07,600 这的确是一个长句子。 408 00:18:07,600 --> 00:18:10,710 所以,这句话是 长度超过16个字符 409 00:18:10,710 --> 00:18:13,670 所以当我按下回车键, 什么会发生? 410 00:18:13,670 --> 00:18:16,940 那么,在的这种情况下, 故事,我宣布缓冲区 411 00:18:16,940 --> 00:18:22,190 实际上是一个数组 有16个字符蓄势待发。 412 00:18:22,190 --> 00:18:27,426 这样一,二,三,四,五,六, 七,八,九,十,十一,十二,十三,十四, 413 00:18:27,426 --> 00:18:29,440 15,16。 414 00:18:29,440 --> 00:18:34,410 所以16个字符,而现在,当我 读这样的事情是一个长期的 415 00:18:34,410 --> 00:18:43,950 一句话,是什么将要发生的 那我要读这是一个漫长 416 00:18:43,950 --> 00:18:49,660 S-E-N-T-E-N-C-E,句子。 417 00:18:49,660 --> 00:18:52,270 >> 因此,这是故意 一件坏事,我 418 00:18:52,270 --> 00:18:55,060 不断书写超越 我的数组的边界, 419 00:18:55,060 --> 00:18:56,660 超出了我缓冲器的边界。 420 00:18:56,660 --> 00:19:00,100 我能得到幸运和程序 将继续运行,并没有在意, 421 00:19:00,100 --> 00:19:03,450 但一般来说,这 确实会崩溃我的程序, 422 00:19:03,450 --> 00:19:06,440 它是在一个错误我 代码的那一刻,我一步 423 00:19:06,440 --> 00:19:08,576 超越界限 该数组的,因为我 424 00:19:08,576 --> 00:19:10,450 不知道这是否是 必然要崩溃 425 00:19:10,450 --> 00:19:12,120 或者,如果我只是要得到幸运。 426 00:19:12,120 --> 00:19:15,750 因此,这是有问题的,因为在 这种情况下,它似乎工作 427 00:19:15,750 --> 00:19:20,931 让我们铤而走险这里,即使 在IDE似乎容忍了不少 428 00:19:20,931 --> 00:19:21,430 of-- 429 00:19:21,430 --> 00:19:22,040 >> 在那里,我们走了。 430 00:19:22,040 --> 00:19:23,240 最后。 431 00:19:23,240 --> 00:19:26,470 所以我能看到这唯一的一个。 432 00:19:26,470 --> 00:19:29,630 所以,我只是有很多好玩的打字 出了很长的实际短语 433 00:19:29,630 --> 00:19:32,800 它肯定超过 16个字节,因为我 434 00:19:32,800 --> 00:19:38,050 输入在这个疯狂的长期多线 短语,然后看到发生了什么。 435 00:19:38,050 --> 00:19:41,110 该程序试图在打印 然后得到一个分段错误 436 00:19:41,110 --> 00:19:44,430 和段错误是当 这样的事情发生 437 00:19:44,430 --> 00:19:47,650 和操作系统说 不,不能触摸的记忆。 438 00:19:47,650 --> 00:19:49,570 我们会杀了 该方案完全。 439 00:19:49,570 --> 00:19:51,180 >> 因此,这似乎是有问题的。 440 00:19:51,180 --> 00:19:54,540 我已经提高了该计划的实施 至少有一些记忆, 441 00:19:54,540 --> 00:19:58,000 但是这似乎局限 该函数的GetString,这是让 442 00:19:58,000 --> 00:20:00,780 一些有限的长度为16的字符串。 443 00:20:00,780 --> 00:20:04,200 所以,如果你想支持更长 句子超过16个字符, 444 00:20:04,200 --> 00:20:04,880 你是做什么? 445 00:20:04,880 --> 00:20:07,970 那么,你可以增加 此缓冲器32的大小 446 00:20:07,970 --> 00:20:09,190 或者说似乎有点短。 447 00:20:09,190 --> 00:20:12,260 为什么我们不只是做 它1000,但推回。 448 00:20:12,260 --> 00:20:17,100 什么是直觉的反应 只是通过避免这种问题 449 00:20:17,100 --> 00:20:20,660 我的缓冲更大,像1000字符? 450 00:20:20,660 --> 00:20:23,470 通过实施GetString的这种方式。 451 00:20:23,470 --> 00:20:27,130 什么是好还是坏吗? 452 00:20:27,130 --> 00:20:28,033 是吗? 453 00:20:28,033 --> 00:20:30,574 听众:如果你绑定了很多 的空间,你不使用它, 454 00:20:30,574 --> 00:20:33,500 那么你就不能重新分配空间。 455 00:20:33,500 --> 00:20:34,500 DAVID马兰:没错。 456 00:20:34,500 --> 00:20:38,480 这是浪费的,只要你不 实际上需要那些字节的900 457 00:20:38,480 --> 00:20:41,057 可是你要求 1000共无论如何, 458 00:20:41,057 --> 00:20:44,140 你只是占用更多的内存 比你需要到用户的计算机上, 459 00:20:44,140 --> 00:20:45,740 毕竟,一些 你已经遇到 460 00:20:45,740 --> 00:20:47,620 在生活中,当你 运行很多程序 461 00:20:47,620 --> 00:20:50,470 和他们吃了大量的内存, 这实际上可能会影响性能 462 00:20:50,470 --> 00:20:52,220 和用户的经验 在电脑上面。 463 00:20:52,220 --> 00:20:56,090 所以这是一种懒的解决方案, 可以肯定,相反, 464 00:20:56,090 --> 00:21:00,140 这不仅造成浪费,什么问题 仍然存在,即使我让我的缓冲区 465 00:21:00,140 --> 00:21:02,100 1000? 466 00:21:02,100 --> 00:21:02,600 是吗? 467 00:21:02,600 --> 00:21:04,475 >> 听众:字符串的长度为1001。 468 00:21:04,475 --> 00:21:05,350 DAVID马兰:没错。 469 00:21:05,350 --> 00:21:08,280 如果字符串的长度为1001, 你有相同的问题, 470 00:21:08,280 --> 00:21:10,705 和我的观点,我会 就在这时,使其2000年, 471 00:21:10,705 --> 00:21:12,830 但你不知道 推进它应该多大, 472 00:21:12,830 --> 00:21:16,890 然而,我必须编译我的程序 之前,让人们使用和下载 473 00:21:16,890 --> 00:21:17,390 它。 474 00:21:17,390 --> 00:21:21,490 因此,这也正是那种 东东的CS50库尝试 475 00:21:21,490 --> 00:21:24,750 帮助我们,我们将只一瞥 一些底层实现的 476 00:21:24,750 --> 00:21:29,790 这里,但这是CS50点C.这 是一直在CS50 IDE文件 477 00:21:29,790 --> 00:21:31,420 所有这几个星期你一直在使用。 478 00:21:31,420 --> 00:21:34,280 这是预编译的。而你 一直在使用它自动 479 00:21:34,280 --> 00:21:38,780 由具有的性质 冲大号CS50标志铿锵, 480 00:21:38,780 --> 00:21:42,300 但如果我向下滚动,通过所有的 这些功能,这里是GetString的, 481 00:21:42,300 --> 00:21:44,636 而只给你一个 什么样的味道是怎么回事, 482 00:21:44,636 --> 00:21:46,760 让我们快速浏览一下 的相对复杂性。 483 00:21:46,760 --> 00:21:48,870 这不是一个超长 功能,但我们没有 484 00:21:48,870 --> 00:21:52,530 必须考虑所有的硬盘约 如何去得到的字符串。 485 00:21:52,530 --> 00:21:55,660 >> 因此,这里是我的缓冲区和我 显然初始化为null。 486 00:21:55,660 --> 00:21:57,990 当然,这是在 同样的事情为char明星, 487 00:21:57,990 --> 00:22:00,585 但我决定 实施CS50库 488 00:22:00,585 --> 00:22:02,460 如果我们要 是完全动态的, 489 00:22:02,460 --> 00:22:05,770 我事先不知道有多大的根本 字符串用户会希望得到的。 490 00:22:05,770 --> 00:22:08,140 所以我要开始 只有一个空字符串 491 00:22:08,140 --> 00:22:11,507 我要去建立尽可能多 记忆,因为我需要适合用户字符串 492 00:22:11,507 --> 00:22:13,340 如果我没有 够了,我要去问 493 00:22:13,340 --> 00:22:15,010 操作系统为更多的内存。 494 00:22:15,010 --> 00:22:17,510 我打算把他们的串 成的存储器的更大的块 495 00:22:17,510 --> 00:22:21,847 我要去释放或释放 内存不够大块 496 00:22:21,847 --> 00:22:23,680 我们正要 反复地做到这一点。 497 00:22:23,680 --> 00:22:25,570 >> 因此,快速浏览, 这里只是一个变量 498 00:22:25,570 --> 00:22:28,780 与我要去跟踪 的我的缓冲器的容量。 499 00:22:28,780 --> 00:22:30,071 我多少字节可以装? 500 00:22:30,071 --> 00:22:32,070 这里有一个变量n与 而我要继续 501 00:22:32,070 --> 00:22:36,200 跟踪有多少字节实际上是 缓冲器或用户已键入。 502 00:22:36,200 --> 00:22:39,900 如果你还没有见过这个,你 可以指定就像一个int变量 503 00:22:39,900 --> 00:22:46,370 是无符号的,它顾名思义, 意味着它的非负的,为什么会 504 00:22:46,370 --> 00:22:50,590 我曾经想打扰指定 即一个int不只是一个int, 505 00:22:50,590 --> 00:22:52,540 但它是一个unsigned int? 506 00:22:52,540 --> 00:22:55,064 这是一个非负的int。 507 00:22:55,064 --> 00:22:56,355 什么是[听不清]是什么意思? 508 00:22:56,355 --> 00:22:58,910 >> 听众:它描述了一个量 内存,可以[听不清]。 509 00:22:58,910 --> 00:22:59,660 >> DAVID马兰:是的。 510 00:22:59,660 --> 00:23:03,710 所以,如果我说的符号,这其实是 给你一个额外的内存一位 511 00:23:03,710 --> 00:23:07,440 它似乎有点傻,但如果你 拥有更多的内存一位,那 512 00:23:07,440 --> 00:23:09,940 意味着你有两倍多 你可以代表值, 513 00:23:09,940 --> 00:23:11,570 因为它可以是一个0或1。 514 00:23:11,570 --> 00:23:14,660 因此,在默认情况下,一个int可以大致 负2十亿一路 515 00:23:14,660 --> 00:23:16,030 达正2十亿。 516 00:23:16,030 --> 00:23:18,540 这些都是大的范围,但 它是一种浪费还是 517 00:23:18,540 --> 00:23:21,280 如果你只关心 尺寸,这只是直觉 518 00:23:21,280 --> 00:23:24,620 应该是非负或 正或0,那么, 519 00:23:24,620 --> 00:23:28,884 你为什么要浪费2十亿 为负数的可能值 520 00:23:28,884 --> 00:23:30,300 如果你从来没有打算使用它们? 521 00:23:30,300 --> 00:23:35,350 所以说无符号的,现在我的INT可以 介于0和约4十亿。 522 00:23:35,350 --> 00:23:39,280 >> 因此,这里只是一个int下原因 我们不会进入刚才的 523 00:23:39,280 --> 00:23:42,280 为什么它是一个int,而不是 一个char,但这里是 524 00:23:42,280 --> 00:23:44,630 发生了什么事情的要点 上,并且一些你 525 00:23:44,630 --> 00:23:48,340 可能使用,例如,在 即使在PSET 4龟etc功能 526 00:23:48,340 --> 00:23:51,580 或之后,我们会看到它 又在问题设置五, 527 00:23:51,580 --> 00:23:55,410 龟etc是不错的,因为作为名称 那种,有点arcanely表明, 528 00:23:55,410 --> 00:23:57,940 这是一个函数, 获取一个字符等等, 529 00:23:57,940 --> 00:24:00,690 有什么本质上的区别 什么,我们正在做的GetString的 530 00:24:00,690 --> 00:24:03,110 是我们没有使用 scanf的以相同的方式。 531 00:24:03,110 --> 00:24:07,550 我们沿着一步一步的只是爬行 以上的任何用户已键入中, 532 00:24:07,550 --> 00:24:10,970 因为我们总是可以分配一个 字符,所以我们总能安全地 533 00:24:10,970 --> 00:24:15,599 看一个字符的时间,和 神奇的开始发生在这里。 534 00:24:15,599 --> 00:24:17,890 我要向下滚动到 此功能的中间 535 00:24:17,890 --> 00:24:20,360 只是简单介绍一下这个功能。 536 00:24:20,360 --> 00:24:22,670 就像有一个 malloc函数,有 537 00:24:22,670 --> 00:24:27,740 一个realloc函数,其中的realloc 让你重新分配一块内存 538 00:24:27,740 --> 00:24:29,570 并使它更大或更小。 539 00:24:29,570 --> 00:24:33,060 所以长话短说,并与 一波我的手今天, 540 00:24:33,060 --> 00:24:35,620 知道什么样的GetString 正在做的是它的排序 541 00:24:35,620 --> 00:24:39,720 的神奇成长或 缓冲收缩作为用户 542 00:24:39,720 --> 00:24:41,440 类型在他或她的字符串。 543 00:24:41,440 --> 00:24:43,962 >> 因此,如果用户键入一个 短字符串,该代码 544 00:24:43,962 --> 00:24:45,920 仅分配足够 存储器以适应串。 545 00:24:45,920 --> 00:24:48,086 如果用户保持打字 我一次又一次做到了 546 00:24:48,086 --> 00:24:50,330 又一次,好吧,如果 缓冲区的最初这个大 547 00:24:50,330 --> 00:24:53,310 和程序实现,对 等一下,我的空间, 548 00:24:53,310 --> 00:24:55,410 这将增加一倍 缓冲区的大小 549 00:24:55,410 --> 00:24:59,110 然后加倍缓冲区的大小 而且确实增加一倍代码, 550 00:24:59,110 --> 00:25:03,170 如果我们看一下在这里,它是 只是这个聪明的一班轮。 551 00:25:03,170 --> 00:25:06,830 你可能没见过这种语法 之前,但如果你说明星等于, 552 00:25:06,830 --> 00:25:10,470 这是同样的事情, 说产能的2倍。 553 00:25:10,470 --> 00:25:13,390 因此,它只是不断翻番 所述缓冲器的容量 554 00:25:13,390 --> 00:25:17,480 然后告诉realloc的给 本身更多的内存。 555 00:25:17,480 --> 00:25:19,720 >> 现在,顺便说一句,有 在这里等功能 556 00:25:19,720 --> 00:25:23,680 我们不会考虑任何细节 比其他的调用getInt显示, 557 00:25:23,680 --> 00:25:26,150 我们使用的GetString的调用getInt。 558 00:25:26,150 --> 00:25:28,192 我们检查,这不是 空,其中,召回, 559 00:25:28,192 --> 00:25:30,400 是特殊的值, 意味着出事了。 560 00:25:30,400 --> 00:25:31,233 我们是内存不足。 561 00:25:31,233 --> 00:25:32,310 更好地检查了。 562 00:25:32,310 --> 00:25:33,710 而我们返回的警戒值。 563 00:25:33,710 --> 00:25:37,850 但我会推迟到的意见,以 为什么然后我们用这个表弟scanf函数的 564 00:25:37,850 --> 00:25:42,100 所谓sscanf的和原来 该sscanf的,或字符串scanf函数, 565 00:25:42,100 --> 00:25:45,310 让你看看就行了 用户键入,让你 566 00:25:45,310 --> 00:25:49,610 本质上分析它,就是我 这里做的是我要告诉sscanf的, 567 00:25:49,610 --> 00:25:54,440 分析任何用户具有 键入并确保%我, 568 00:25:54,440 --> 00:25:59,250 有在它的整数,并且我们不会 进入今天究竟为什么有还 569 00:25:59,250 --> 00:26:03,760 一%C在这里,但简而言之允许 我们检测是否用户已键入 570 00:26:03,760 --> 00:26:06,050 在一些号码后伪造的。 571 00:26:06,050 --> 00:26:11,766 因此原因,调用getInt和GetString 告诉你重试,重试,重试 572 00:26:11,766 --> 00:26:13,640 是因为所有的 我们编写的代码, 573 00:26:13,640 --> 00:26:17,900 它种在看用户的输入 在确保它完全数字 574 00:26:17,900 --> 00:26:21,700 或者它是一个真正的浮动 点值等, 575 00:26:21,700 --> 00:26:24,233 这取决于什么样的价值 您正在使用的功能。 576 00:26:24,233 --> 00:26:25,060 >> 呼。 577 00:26:25,060 --> 00:26:25,710 行。 578 00:26:25,710 --> 00:26:27,592 这是一个拗口 但问题在这里 579 00:26:27,592 --> 00:26:29,550 我们有原因 这些培训车轮 580 00:26:29,550 --> 00:26:32,880 是因为在最低水平, 还有就是这么多的事情 581 00:26:32,880 --> 00:26:35,674 可以去错了,我们想 抢先处理 582 00:26:35,674 --> 00:26:38,090 这些东西肯定是在 最早的几个星期之类的, 583 00:26:38,090 --> 00:26:42,230 但现在PSET四个PSET五 以后你会发现它更对 584 00:26:42,230 --> 00:26:45,570 你还要你更强大 对解决这些类型的问题 585 00:26:45,570 --> 00:26:47,180 你自己。 586 00:26:47,180 --> 00:26:51,770 上的GetString或调用getInt有问题吗? 587 00:26:51,770 --> 00:26:52,630 是吗? 588 00:26:52,630 --> 00:26:55,130 >> 听众:你为什么会增加一倍 所述缓冲器的容量 589 00:26:55,130 --> 00:26:57,630 而不是仅仅增加 它的具体数额? 590 00:26:57,630 --> 00:26:58,100 >> DAVID马兰:好问题。 591 00:26:58,100 --> 00:27:00,474 为什么我们的身份倍增 缓冲器的相 592 00:27:00,474 --> 00:27:02,800 只是增加它 一些常数值? 593 00:27:02,800 --> 00:27:03,900 这是一个设计决策。 594 00:27:03,900 --> 00:27:08,590 我们刚刚决定,因为它往往 有点贵的时间,聪明的问 595 00:27:08,590 --> 00:27:10,440 操作系统 内存,我们没有 596 00:27:10,440 --> 00:27:13,210 要最终进入 这种情况对于大串 597 00:27:13,210 --> 00:27:14,960 我们被要求 连连操作系统 598 00:27:14,960 --> 00:27:17,500 一次又一次的 快速连续的内存。 599 00:27:17,500 --> 00:27:20,387 因此,我们刚刚决定,多少有些 任意但我们希望合理, 600 00:27:20,387 --> 00:27:22,720 如此,你知道吗,让我们 试图获得超越自我 601 00:27:22,720 --> 00:27:25,520 而只是一味增加了一倍它使 我们最小化的倍量 602 00:27:25,520 --> 00:27:29,010 我们必须调用malloc或 realloc的,但总的判断 603 00:27:29,010 --> 00:27:31,820 在没有知道的调用 什么样的用户可能需要输入内容。 604 00:27:31,820 --> 00:27:33,600 这两种方式可能是值得商榷的。 605 00:27:33,600 --> 00:27:35,430 可以说不错。 606 00:27:35,430 --> 00:27:39,240 >> 因此,让我们来看看一对夫妇 的内存等副作用, 607 00:27:39,240 --> 00:27:41,610 事情可能出错 和工具,你可以 608 00:27:41,610 --> 00:27:43,880 用它来捕获这些类型的错误。 609 00:27:43,880 --> 00:27:47,800 原来大家,即使 check50没有告诉你一样多, 610 00:27:47,800 --> 00:27:50,050 一直在写越野车 因为一个星期代码, 611 00:27:50,050 --> 00:27:53,630 即使所有check50测试 过去了,即使你和你的TF 612 00:27:53,630 --> 00:27:56,010 超级信心 你的代码按预期工作。 613 00:27:56,010 --> 00:27:59,190 您的代码已被马车或 有缺陷的,所有的你, 614 00:27:59,190 --> 00:28:02,540 在使用CS50库 被泄漏内存。 615 00:28:02,540 --> 00:28:06,040 你一直在问的操作系统 对于存储器在大多数的节目 616 00:28:06,040 --> 00:28:08,850 你写的,但你 从来没有真正赋予它回来。 617 00:28:08,850 --> 00:28:12,110 你所谓的GetString 和调用getInt和GetFloat, 618 00:28:12,110 --> 00:28:15,270 但GetString的,你 从来没有所谓unGetString或给 619 00:28:15,270 --> 00:28:19,890 返回的字符串或类似的,但我们已经看到 是的GetString确实分配内存 620 00:28:19,890 --> 00:28:22,810 由malloc或方式这 功能realloc的,这仅仅是 621 00:28:22,810 --> 00:28:25,670 在精神上非常相似, 然而,我们已经 622 00:28:25,670 --> 00:28:28,629 询问操作系统以 存储器和存储器连连 623 00:28:28,629 --> 00:28:29,670 但从来没有给它回来。 624 00:28:29,670 --> 00:28:33,550 >> 现在,顺便说一句,事实证明, 当程序退出,所有内存 625 00:28:33,550 --> 00:28:34,870 自动释放。 626 00:28:34,870 --> 00:28:36,150 所以它没有一个巨大的交易。 627 00:28:36,150 --> 00:28:38,590 它不会打破 IDE或放慢改革的步伐, 628 00:28:38,590 --> 00:28:40,670 但是当程序执行 一般内存泄漏 629 00:28:40,670 --> 00:28:42,170 而他们正在运行很长一段时间。 630 00:28:42,170 --> 00:28:45,640 如果你见过那些愚蠢的小 在Mac OS或沙漏沙滩球 631 00:28:45,640 --> 00:28:51,160 在Windows上它是一种 减缓或思考或思维 632 00:28:51,160 --> 00:28:53,770 或者只是真正开始 慢如蜗牛, 633 00:28:53,770 --> 00:28:56,960 它很可能可以 内存泄漏的结果。 634 00:28:56,960 --> 00:28:59,970 谁写的程序员 您正在使用的软件 635 00:28:59,970 --> 00:29:03,570 要求对内存的操作系统 每隔几分钟,每隔一小时。 636 00:29:03,570 --> 00:29:05,570 但是,如果你正在运行的 软件,即使是 637 00:29:05,570 --> 00:29:08,680 最小化您的电脑 几个小时或几天, 638 00:29:08,680 --> 00:29:11,980 你可能会问了越来越多 内存和从来没有真正使用它 639 00:29:11,980 --> 00:29:15,180 所以你的代码可能是,或 程序可能泄漏内存, 640 00:29:15,180 --> 00:29:18,350 如果你开始泄漏内存, 还有其他程序内存少, 641 00:29:18,350 --> 00:29:21,220 而且其效果是 慢都记录下来。 642 00:29:21,220 --> 00:29:23,600 >> 现在,这是迄今为止的一个 最残暴的方案 643 00:29:23,600 --> 00:29:26,350 你将有机会 在CS50运行,只要 644 00:29:26,350 --> 00:29:31,650 作为其输出甚至比更深奥 铿锵的或做的或任何命令 645 00:29:31,650 --> 00:29:35,930 我们之前已经运行线方案,但 值得庆幸的是,镶嵌在其输出 646 00:29:35,930 --> 00:29:39,810 一些超有用的技巧, 将是有益的无论是PSET 4 647 00:29:39,810 --> 00:29:41,510 不然肯定P设定五位。 648 00:29:41,510 --> 00:29:44,250 所以Valgrind是一个工具, 可用于看 649 00:29:44,250 --> 00:29:46,930 程序中的内存泄漏。 650 00:29:46,930 --> 00:29:48,570 这是相对简单的运行。 651 00:29:48,570 --> 00:29:51,420 你跑Valgrind的,然后,连 虽然这是一个有点冗长, 652 00:29:51,420 --> 00:29:54,440 短跑冲刺泄漏检查 等于满,然后点 653 00:29:54,440 --> 00:29:56,320 斜线和你的程序的名称。 654 00:29:56,320 --> 00:30:00,010 因此,Valgrind的会后运行程序 并在程序的最后 655 00:30:00,010 --> 00:30:02,240 运行它退出前, 为您提供了另一个提示, 656 00:30:02,240 --> 00:30:04,980 它会分析你的 虽然它已经正在运行的程序 657 00:30:04,980 --> 00:30:07,740 并告诉你你泄露 任何内存和更好的是, 658 00:30:07,740 --> 00:30:10,610 你触碰内存 不属于你? 659 00:30:10,610 --> 00:30:13,700 它无法赶上一切,但它的 在最醒目的东西很不错。 660 00:30:13,700 --> 00:30:19,700 >> 因此,这里是有经营我的一个例子 这个节目,有跑Valgrind的, 661 00:30:19,700 --> 00:30:21,470 在调用程序 记忆,我要去 662 00:30:21,470 --> 00:30:24,730 以突出的线条 最终我们感兴趣的。 663 00:30:24,730 --> 00:30:27,690 因此,有更多的分心 我已经从幻灯片中删除。 664 00:30:27,690 --> 00:30:30,930 但是,让我们只看看这是什么 程序能够告诉我们的。 665 00:30:30,930 --> 00:30:34,800 它能够告诉我们的东西 像大小为4无效写。 666 00:30:34,800 --> 00:30:38,020 换句话说,如果你触碰到内存, 特别是4字节的内存 667 00:30:38,020 --> 00:30:40,350 你不应该有, 的valgrind可以告诉你。 668 00:30:40,350 --> 00:30:41,660 无效的写大小为4。 669 00:30:41,660 --> 00:30:43,640 你感动了四个字节 你不应该有。 670 00:30:43,640 --> 00:30:44,840 你在哪儿做的? 671 00:30:44,840 --> 00:30:45,900 这是美。 672 00:30:45,900 --> 00:30:50,000 记忆点C线21就是你 搞砸了,这就是为什么它是有帮助的。 673 00:30:50,000 --> 00:30:53,410 就像GDB,它可以帮助 点你在实际的错误。 674 00:30:53,410 --> 00:30:57,170 >> 现在,这一个多一点 冗长的,如果不是混乱。 675 00:30:57,170 --> 00:31:01,307 在1块40个字节肯定 在负的战绩1 1的丢失。 676 00:31:01,307 --> 00:31:02,140 这意味着什么? 677 00:31:02,140 --> 00:31:05,920 嗯,这只是意味着你问 40个字节,你从来没有给它回来。 678 00:31:05,920 --> 00:31:08,930 你叫的malloc,或者您叫 GetString的和操作系统 679 00:31:08,930 --> 00:31:12,450 给你40个字节,但你永远不 释放或者释放内存, 680 00:31:12,450 --> 00:31:15,400 而公平地说,我们从来没有展示 你如何回馈内存。 681 00:31:15,400 --> 00:31:17,910 原来有一个超 所谓的自由简单的功能。 682 00:31:17,910 --> 00:31:21,170 有一个参数的东西 你想免费或给予回复, 683 00:31:21,170 --> 00:31:23,430 但40个字节,显然, 这个方案 684 00:31:23,430 --> 00:31:27,300 已经失去了线 内存20 C点。 685 00:31:27,300 --> 00:31:28,650 >> 因此,让我们看到这个计划。 686 00:31:28,650 --> 00:31:31,020 这是超级没用。 687 00:31:31,020 --> 00:31:33,980 它不仅展现 此特定错误。 688 00:31:33,980 --> 00:31:34,920 因此,让我们一起来看看。 689 00:31:34,920 --> 00:31:39,920 下面是主要的和主要的,通知,电话 一个函数调用f和再返回。 690 00:31:39,920 --> 00:31:41,550 所以不是那么有趣。 691 00:31:41,550 --> 00:31:42,664 什么是f执行? 692 00:31:42,664 --> 00:31:44,330 请注意,我并​​没有原型麻烦。 693 00:31:44,330 --> 00:31:46,520 我想保持代码 尽可能小。 694 00:31:46,520 --> 00:31:49,530 所以我把F时上部主 这很好,当然, 695 00:31:49,530 --> 00:31:51,500 对于这样的短期课程。 696 00:31:51,500 --> 00:31:56,910 因此,F不返回任何东西和做 不能带什么,但它确实做到这一点。 697 00:31:56,910 --> 00:31:59,620 它声明,很像 在宾基例如, 698 00:31:59,620 --> 00:32:02,682 一个名为x的指针是怎么回事 存储一个int的地址。 699 00:32:02,682 --> 00:32:03,890 所以这是左手侧。 700 00:32:03,890 --> 00:32:07,230 在英语中,什么是 右手边做什么? 701 00:32:07,230 --> 00:32:09,770 有人吗? 702 00:32:09,770 --> 00:32:13,665 这是什么做的我们呢? 703 00:32:13,665 --> 00:32:14,651 是吗? 704 00:32:14,651 --> 00:32:16,623 >> 听众:[听不清] 倍int的大小 705 00:32:16,623 --> 00:32:19,175 它是10倍,[听不清] 706 00:32:19,175 --> 00:32:20,800 DAVID马兰:好,让我来总结。 707 00:32:20,800 --> 00:32:25,480 因此,分配足够的空间为10整数 或10,什么是一个int的大小, 708 00:32:25,480 --> 00:32:29,340 它的四个字节,所以10次4 40,使右手边,我已经 709 00:32:29,340 --> 00:32:33,930 高亮显示的是给我40个字节, 存储第一字节的地址 710 00:32:33,930 --> 00:32:34,940 成X个。 711 00:32:34,940 --> 00:32:38,380 而现在最后,而这里的地方 这个程序有错误,什么是 712 00:32:38,380 --> 00:32:41,540 错线21基于该逻辑是什么? 713 00:32:41,540 --> 00:32:45,197 714 00:32:45,197 --> 00:32:46,280 有什么不对线21? 715 00:32:46,280 --> 00:32:46,780 是吗? 716 00:32:46,780 --> 00:32:49,550 听众:你不能 索引X [听不清]。 717 00:32:49,550 --> 00:32:50,300 DAVID马兰:是的。 718 00:32:50,300 --> 00:32:52,270 我不该指数成X个这样的。 719 00:32:52,270 --> 00:32:53,850 所以语法,没关系。 720 00:32:53,850 --> 00:32:56,990 什么是好的是,就像你 可以把一个数组名 721 00:32:56,990 --> 00:33:01,080 就好像它是一个指针,同样 你可以把一个指针,仿佛它是 722 00:33:01,080 --> 00:33:06,425 一个数组,这样我就可以在语法 例如x支架的东西,X架我, 723 00:33:06,425 --> 00:33:07,800 但10是有问题的。 724 00:33:07,800 --> 00:33:09,096 为什么呢? 725 00:33:09,096 --> 00:33:10,910 >> 听众:因为它不是内。 726 00:33:10,910 --> 00:33:12,390 >> DAVID马兰:这不是 里面的内存块。 727 00:33:12,390 --> 00:33:15,306 什么是最大的价值,我应该 可以把这些方括号? 728 00:33:15,306 --> 00:33:16,870 9,0到9。 729 00:33:16,870 --> 00:33:18,160 因为零索引。 730 00:33:18,160 --> 00:33:20,190 因此,从0到9就可以了。 731 00:33:20,190 --> 00:33:23,960 支架10是不好的, 但是,每一次回忆,虽然 732 00:33:23,960 --> 00:33:27,017 我似乎尽量让CS50的IDE 坠毁通过键入假值, 733 00:33:27,017 --> 00:33:29,100 它并不总是合作, 而事实上,你经常 734 00:33:29,100 --> 00:33:31,460 幸运只是因为 操作系统不 735 00:33:31,460 --> 00:33:35,467 请注意,您可以轻微 通过一些内存块, 736 00:33:35,467 --> 00:33:38,300 因为你住在技术上 您的段,但更多介绍 737 00:33:38,300 --> 00:33:40,940 在一个操作系统类, 所以像这样 738 00:33:40,940 --> 00:33:43,000 可以很容易被忽视。 739 00:33:43,000 --> 00:33:48,120 你的程序永远不会崩溃 持续但也许曾经在一段时间。 740 00:33:48,120 --> 00:33:50,610 >> 因此,让我们尝试的valgrind 这一点,和这里的 741 00:33:50,610 --> 00:33:52,870 在这里,我们会变得不知所措 通过瞬间的输出。 742 00:33:52,870 --> 00:34:00,810 因此,请Valgrind的内存泄漏检查 等于全点斜线内存。 743 00:34:00,810 --> 00:34:03,040 这里就是为什么我保证 这将压倒。 744 00:34:03,040 --> 00:34:05,700 以下是Valgrind的,下面是 一个程序员,有些年份ago- 745 00:34:05,700 --> 00:34:08,469 决定这将是一个好主意 为输出的样子。 746 00:34:08,469 --> 00:34:09,750 因此,让我们理解这一点。 747 00:34:09,750 --> 00:34:13,120 因此,所有对左手的方式 侧面没有很好的理由 748 00:34:13,120 --> 00:34:16,620 是程序的进程ID 我们只需运行,唯一标识符 749 00:34:16,620 --> 00:34:18,030 对于该方案,我们只是跑。 750 00:34:18,030 --> 00:34:19,738 我们删除了从 滑动,但也有 751 00:34:19,738 --> 00:34:22,190 在这里一些有用的信息。 752 00:34:22,190 --> 00:34:24,684 >> 让我们向上滚动到顶部。 753 00:34:24,684 --> 00:34:25,600 这里就是我们的开始。 754 00:34:25,600 --> 00:34:27,040 因此,它不是所有的东西输出。 755 00:34:27,040 --> 00:34:30,429 下面是无效的写 对21行大小4。 756 00:34:30,429 --> 00:34:31,760 那么,什么是第21行? 757 00:34:31,760 --> 00:34:34,500 第21行正是 这一点,这是有道理的 758 00:34:34,500 --> 00:34:37,290 我是在有效 写4个字节,因为我 759 00:34:37,290 --> 00:34:40,389 试图把这个整数, 它可以是任何东西, 760 00:34:40,389 --> 00:34:42,370 这恰好是 零,但是我想 761 00:34:42,370 --> 00:34:44,940 把它在一个位置 这不属于我。 762 00:34:44,940 --> 00:34:50,900 此外,到这里,40在一个字节 块肯定是失去了在创纪录的1。 763 00:34:50,900 --> 00:34:56,500 这是因为当我调用malloc 在这里,我从来没有真正释放内存。 764 00:34:56,500 --> 00:34:58,140 >> 那么,如何才能解决这个问题? 765 00:34:58,140 --> 00:35:02,970 让我继续前进,是一个小更安全 并做9那儿​​,让我在这里免费的X。 766 00:35:02,970 --> 00:35:04,820 这是新的功能,为今天。 767 00:35:04,820 --> 00:35:11,520 如果我现在重新运行使内存点斜线, 让我们在其上运行的valgrind再次, 768 00:35:11,520 --> 00:35:14,990 最大限度地发挥我的窗口,然后按Enter。 769 00:35:14,990 --> 00:35:16,900 现在,这是很好的。 770 00:35:16,900 --> 00:35:19,590 他们埋葬好消息 在这一切的输出。 771 00:35:19,590 --> 00:35:20,810 所有堆块是免费的。 772 00:35:20,810 --> 00:35:23,604 我们会回来的东西堆 是,但无泄漏是可能的。 773 00:35:23,604 --> 00:35:25,520 因此,这只是另一种 工具的工具箱 774 00:35:25,520 --> 00:35:30,220 使用它可以开始 现在发现这样的错误。 775 00:35:30,220 --> 00:35:34,532 >> 但是让我们看看有什么 更可以去错在这里。 776 00:35:34,532 --> 00:35:38,890 现在让我们来转变 其实解决问题。 777 00:35:38,890 --> 00:35:42,440 顺便说一句,如果这将缓解一 混乱或紧张一点, 778 00:35:42,440 --> 00:35:43,430 这是现在好笑。 779 00:35:43,430 --> 00:35:46,400 780 00:35:46,400 --> 00:35:46,900 是啊。 781 00:35:46,900 --> 00:35:49,040 这是相当不错的。 782 00:35:49,040 --> 00:35:50,890 因为指针 地址和地址 783 00:35:50,890 --> 00:35:53,098 一般都是按照惯例 写的十六进制。 784 00:35:53,098 --> 00:35:54,650 哈,哈,这个现在好笑。 785 00:35:54,650 --> 00:35:58,390 总之,让我们现在 其实解决的一个问题。 786 00:35:58,390 --> 00:36:00,840 这一直是超级, 超低水平迄今为止, 787 00:36:00,840 --> 00:36:03,950 而我们实际上可以做有益 事情与这些低级别的细节。 788 00:36:03,950 --> 00:36:06,710 >> 因此,我们介绍了几个星期 前的阵列的概念。 789 00:36:06,710 --> 00:36:09,177 数组是不错的,因为 很难清理我们的代码 790 00:36:09,177 --> 00:36:11,760 因为如果我们想写 程序有多个学生 791 00:36:11,760 --> 00:36:15,270 或多个名称和房屋及 宿舍,学院和所有这一切, 792 00:36:15,270 --> 00:36:19,430 我们可以存储的一切更 干净的阵列的内部。 793 00:36:19,430 --> 00:36:23,039 但提出一个缺点 阵列的迄今。 794 00:36:23,039 --> 00:36:26,080 即使你没有自己遭受它 在一个程序,只是本能地, 795 00:36:26,080 --> 00:36:30,870 什么是坏事 有关阵列,也许? 796 00:36:30,870 --> 00:36:32,337 我听到一些杂音。 797 00:36:32,337 --> 00:36:34,170 听众:这很难 改变大小。 798 00:36:34,170 --> 00:36:36,128 DAVID马兰:这很难 改变大小。 799 00:36:36,128 --> 00:36:38,660 你不能改变大小 阵列的,实际上,本身 800 00:36:38,660 --> 00:36:43,040 在C.你可以分配另一个数组, 从旧的移动一切 801 00:36:43,040 --> 00:36:45,380 到新的,现在 有一些额外的空间, 802 00:36:45,380 --> 00:36:47,469 但它不喜欢 如Java或Python语言 803 00:36:47,469 --> 00:36:49,760 或任何数目的其他的 与语言的一些你 804 00:36:49,760 --> 00:36:52,070 可能是熟悉的,你 可以只保留添加的东西 805 00:36:52,070 --> 00:36:53,930 令人作呕到数组的结尾。 806 00:36:53,930 --> 00:36:57,880 当你有一个数组 大小6,这是它的大小, 807 00:36:57,880 --> 00:37:01,970 和这么多喜欢这个主意更早 具有一定大小的缓冲区, 808 00:37:01,970 --> 00:37:05,940 你必须猜测出大门 你想要什么尺寸它是什么? 809 00:37:05,940 --> 00:37:07,880 如果你猜过大, 你就是在浪费空间。 810 00:37:07,880 --> 00:37:10,950 如果你猜过小, 不能存储的数据,至少 811 00:37:10,950 --> 00:37:12,940 没有更多的工作。 812 00:37:12,940 --> 00:37:18,180 >> 所以今天,多亏了指针,我们可以 开始拼接起来自己的自定义 813 00:37:18,180 --> 00:37:20,989 数据结构,以及在 其实,这里的东西 814 00:37:20,989 --> 00:37:23,030 看起来有点多 神秘的第一眼, 815 00:37:23,030 --> 00:37:26,440 但是这就是我们会打电话给一个链接 列表,它的名字样的总结 816 00:37:26,440 --> 00:37:26,940 它。 817 00:37:26,940 --> 00:37:29,550 它的号码的列表,或者在 这种情况下,数字的列表, 818 00:37:29,550 --> 00:37:33,480 但它可能是任何一个列表,但 它连接在一起的箭头的方式, 819 00:37:33,480 --> 00:37:36,380 而只是采取一种猜测 有什么方法 820 00:37:36,380 --> 00:37:38,310 我们要能 缝合在一起, 821 00:37:38,310 --> 00:37:42,540 有点像爆米花用线, 一个链表矩形吗? 822 00:37:42,540 --> 00:37:43,936 它的数字? 823 00:37:43,936 --> 00:37:45,560 什么是底层语言功能? 824 00:37:45,560 --> 00:37:46,350 >> 听众:一个指针。 825 00:37:46,350 --> 00:37:47,308 >> DAVID马兰:一个指针。 826 00:37:47,308 --> 00:37:51,700 所以,每一个箭在这里代表 指针或只是一个地址。 827 00:37:51,700 --> 00:37:54,590 因此,换句话说,如果我想 来存储数字列表, 828 00:37:54,590 --> 00:37:59,040 我不能只保存它,如果我想 增长和收缩的能力 829 00:37:59,040 --> 00:38:00,990 我的数据结构中的阵列。 830 00:38:00,990 --> 00:38:03,000 因此,我需要有一点 更复杂, 831 00:38:03,000 --> 00:38:05,720 但是请注意,这 图片一种暗示 832 00:38:05,720 --> 00:38:08,650 如果你拿到的小线程 一切都连接在一起, 833 00:38:08,650 --> 00:38:13,100 也许并不难,以腾出空间 其中的两个矩形之间 834 00:38:13,100 --> 00:38:16,750 两个这些节点,因为我们将开始 美其名曰,放入一个新的节点, 835 00:38:16,750 --> 00:38:19,547 然后用一些新的线程,只 沟三个节点一起, 836 00:38:19,547 --> 00:38:22,880 第一个,最后一个,并且所述一个 您刚刚插入中间。 837 00:38:22,880 --> 00:38:26,000 >> 事实上链表, 一个数组不同的,是动态的。 838 00:38:26,000 --> 00:38:27,840 它可以成长,它可以 收缩而你不知道 839 00:38:27,840 --> 00:38:32,434 有知道或关心提前如何 你要多少数据被存储, 840 00:38:32,434 --> 00:38:35,600 但事实证明,我们是一个小 小心如何实现这一点。 841 00:38:35,600 --> 00:38:39,070 因此,首先让我们来看看我们如何实现 其中一个小矩形。 842 00:38:39,070 --> 00:38:40,690 这很容易实现一个int。 843 00:38:40,690 --> 00:38:44,000 你刚才说INT n和再 你得到的4个字节为一个int, 844 00:38:44,000 --> 00:38:49,089 但我怎么得到一个int,正调用它, 再一个指针,让我们称之为下一个。 845 00:38:49,089 --> 00:38:50,880 我们可以把这些 什么东西我们要 846 00:38:50,880 --> 00:38:53,590 但我需要一个自定义的数据结构。 847 00:38:53,590 --> 00:38:54,257 是吗? 848 00:38:54,257 --> 00:38:57,020 >> 听众:&符号[听不清]。 849 00:38:57,020 --> 00:39:00,940 >> DAVID马兰:所以符号,我们将用它来 获得一个节点的地址可能。 850 00:39:00,940 --> 00:39:02,740 但是,我们需要另一个 C的顺序功能 851 00:39:02,740 --> 00:39:06,700 给我创造的能力 这个自定义的矩形,这种风俗 852 00:39:06,700 --> 00:39:08,919 变量,如果你愿意,在内存中。 853 00:39:08,919 --> 00:39:09,710 听众:一个结构。 854 00:39:09,710 --> 00:39:10,626 DAVID马兰:一个结构。 855 00:39:10,626 --> 00:39:14,310 从上周还记得,我们推出 结构,这种相对简单的关键词 856 00:39:14,310 --> 00:39:16,254 这让我们做这样的事情。 857 00:39:16,254 --> 00:39:18,420 Ç没有配备数据 结构被称为学生。 858 00:39:18,420 --> 00:39:22,190 它配备了int和float和char和 这样,但它不来学生, 859 00:39:22,190 --> 00:39:26,750 但我们可以创建一个学生数据类型, 学生结构,这种语法 860 00:39:26,750 --> 00:39:27,250 这里。 861 00:39:27,250 --> 00:39:28,350 你会一次又一次地看到这一点。 862 00:39:28,350 --> 00:39:30,426 所以不要担心 记忆中的关键字, 863 00:39:30,426 --> 00:39:33,300 但关键字,重要的是 只是一个事实,即我们所说的结构 864 00:39:33,300 --> 00:39:37,590 然后我们把它称为学生和内 学生的是一个名字和一个房子 865 00:39:37,590 --> 00:39:39,390 或者宿舍等。 866 00:39:39,390 --> 00:39:41,980 >> 所以现在的今天,让我们提出这一点。 867 00:39:41,980 --> 00:39:45,240 我加了几句话,但是如果我想 实现这个矩形的 868 00:39:45,240 --> 00:39:48,440 既得到了一个int和 指针,你知道吗,我 869 00:39:48,440 --> 00:39:51,540 要声明一个叫做节点结构。 870 00:39:51,540 --> 00:39:55,630 我也是,在它的内部,会说 一个节点,这个矩形,有一个int 871 00:39:55,630 --> 00:39:59,730 我们将称之为n和 它具有一个下一个指针。 872 00:39:59,730 --> 00:40:02,540 这是一个有点冗长, 但如果你仔细想想, 873 00:40:02,540 --> 00:40:07,300 那些出现在画面中的箭头 刚才是什么数据类型? 874 00:40:07,300 --> 00:40:12,330 每个这些箭头的指向 数据结构是什么类型? 875 00:40:12,330 --> 00:40:14,332 这不是指着刚本身一个int。 876 00:40:14,332 --> 00:40:16,165 它指向 整个矩形的事情 877 00:40:16,165 --> 00:40:18,720 那长方形的东西, 我们说,被称为一个节点。 878 00:40:18,720 --> 00:40:21,720 所以,我们种得 递归定义该这样 879 00:40:21,720 --> 00:40:26,270 一个节点,我们会说, 将包含一个名为-n的INT 880 00:40:26,270 --> 00:40:31,070 并呼吁下及指针 数据结构的类型向其中 881 00:40:31,070 --> 00:40:35,770 该指针指向显然是 将是结构节点。 882 00:40:35,770 --> 00:40:41,550 >> 因此,这是烦人详细 而刚需迂腐, 883 00:40:41,550 --> 00:40:44,100 我们之所以不能 只是这么一说,坦率地说 884 00:40:44,100 --> 00:40:46,860 看起来很多更具可读性, 是因为回想一下,C了解 885 00:40:46,860 --> 00:40:48,710 东西从上到下,从左到右。 886 00:40:48,710 --> 00:40:54,120 这不是直到我们得到了分号 该关键字的节点确实存在。 887 00:40:54,120 --> 00:40:57,980 因此,如果我们希望有这样的 数据的内部循环参考 888 00:40:57,980 --> 00:41:02,120 结构,我们不得不这样做,在哪里 我们说结构节点在顶部,这 889 00:41:02,120 --> 00:41:06,770 给我们描述了这样一个更长的路 的事情,然后在里面我们说结构节点, 890 00:41:06,770 --> 00:41:09,560 然后在最后一行 我们说,没事,C,顺便说一下, 891 00:41:09,560 --> 00:41:12,060 只需拨打这个整个该死 事情的一个节点,并停止 892 00:41:12,060 --> 00:41:14,360 共使用关键字结构。 893 00:41:14,360 --> 00:41:18,030 因此,这只是有点句法 伎俩,最终让我们创造 894 00:41:18,030 --> 00:41:21,370 一些看起来完全一样。 895 00:41:21,370 --> 00:41:25,010 >> 因此,如果我们现在假设我们可以 用C实现这个东西, 896 00:41:25,010 --> 00:41:28,040 我们如何做实际上 开始遍历这个? 897 00:41:28,040 --> 00:41:32,360 唉,其实,我们所要做的就是 遍历从左至右,只是 898 00:41:32,360 --> 00:41:35,960 一种插入节点或删除节点 或搜索东西的地方,我们希望, 899 00:41:35,960 --> 00:41:39,560 但要做到这一点,让我们继续前进,使 事情变得更真实,因为这 900 00:41:39,560 --> 00:41:42,560 已经超低水平迄今。 901 00:41:42,560 --> 00:41:45,700 会有人从字面上想成为第一个? 902 00:41:45,700 --> 00:41:46,200 行。 903 00:41:46,200 --> 00:41:47,092 上来吧。 904 00:41:47,092 --> 00:41:47,800 你叫什么名字? 905 00:41:47,800 --> 00:41:48,499 >> 大卫:大卫。 906 00:41:48,499 --> 00:41:49,290 DAVID马兰:大卫。 907 00:41:49,290 --> 00:41:49,998 很高兴认识你。 908 00:41:49,998 --> 00:41:50,960 我也是。 909 00:41:50,960 --> 00:41:52,450 好吧。 910 00:41:52,450 --> 00:41:53,990 我们需要一个9号。 911 00:41:53,990 --> 00:41:55,240 还不如先,也许是。 912 00:41:55,240 --> 00:41:56,430 OK,号码9。 913 00:41:56,430 --> 00:41:59,667 一个数字17,请。 914 00:41:59,667 --> 00:42:01,000 让我回去远了一点。 915 00:42:01,000 --> 00:42:03,980 22号,请和 怎么样靠后 916 00:42:03,980 --> 00:42:06,344 如果我能看到任何的手 与所有的光或没有。 917 00:42:06,344 --> 00:42:08,010 有人正在被自愿在那里。 918 00:42:08,010 --> 00:42:08,968 难道你要来了? 919 00:42:08,968 --> 00:42:10,450 你的前臂用力往上走。 920 00:42:10,450 --> 00:42:12,340 OK,17。 921 00:42:12,340 --> 00:42:13,690 22。 922 00:42:13,690 --> 00:42:15,120 26下来。 923 00:42:15,120 --> 00:42:18,450 谁都想 forcefully--上来吧。 924 00:42:18,450 --> 00:42:21,030 一个实际的志愿者。 925 00:42:21,030 --> 00:42:23,330 >> 所以很快,如果 你们可以安排 926 00:42:23,330 --> 00:42:26,550 自己只是喜欢 屏幕上的节点。 927 00:42:26,550 --> 00:42:27,510 谢谢。 928 00:42:27,510 --> 00:42:29,234 你会是26。 929 00:42:29,234 --> 00:42:30,650 好吧,快速推出。 930 00:42:30,650 --> 00:42:32,139 所以,我是大卫,你也是? 931 00:42:32,139 --> 00:42:32,680 大卫:大卫。 932 00:42:32,680 --> 00:42:33,721 DAVID马兰:你是谁? 933 00:42:33,721 --> 00:42:34,229 杰克:杰克。 934 00:42:34,229 --> 00:42:34,729 苏:苏。 935 00:42:34,729 --> 00:42:35,229 亚历克斯:亚历克斯。 936 00:42:35,229 --> 00:42:36,475 拉斐尔:拉斐尔。 937 00:42:36,475 --> 00:42:37,100 泰勒:泰勒。 938 00:42:37,100 --> 00:42:37,466 DAVID马兰:泰勒。 939 00:42:37,466 --> 00:42:37,590 优秀的。 940 00:42:37,590 --> 00:42:39,810 所以,这些都是我们的志愿者 今天和前进 941 00:42:39,810 --> 00:42:43,090 和转移一点的方式, 而只是继续前进,保持 942 00:42:43,090 --> 00:42:47,024 牵着你的号码,你的或你的 第一个迹象,用你的左手, 943 00:42:47,024 --> 00:42:48,940 继续前进,只是实施 这些箭头,只是 944 00:42:48,940 --> 00:42:51,360 让你的左手是名副其实 指着无论你应该点 945 00:42:51,360 --> 00:42:54,610 在,给自己一些空间,以便 我们可以直观地看到你的手臂居然 946 00:42:54,610 --> 00:42:58,120 指点,你可以只点 那种在地面罚款。 947 00:42:58,120 --> 00:43:03,040 >> 所以在这里我们有一个链表, 两个,三个,四个,五个节点最初 948 00:43:03,040 --> 00:43:05,860 并请注意,我们有这个特殊的 指针一开始谁的 949 00:43:05,860 --> 00:43:09,770 关键,因为我们必须跟踪 全长列表莫名其妙。 950 00:43:09,770 --> 00:43:13,590 这些家伙,即使他们离开 以对,背靠背在内存中, 951 00:43:13,590 --> 00:43:15,950 他们实际上可以在任何地方 在计算机的存储器中。 952 00:43:15,950 --> 00:43:18,240 因此,这些人可能是 在舞台上的任何地方静置 953 00:43:18,240 --> 00:43:20,960 这很好,只要他们 实际上指着对方, 954 00:43:20,960 --> 00:43:22,770 但为了方便, 干净简洁,我们将 955 00:43:22,770 --> 00:43:25,728 只是吸引他们从左到右像 这一点,但可能有大量的空白 956 00:43:25,728 --> 00:43:26,790 在这些节点之间。 957 00:43:26,790 --> 00:43:30,710 >> 现在,如果我想实际插入一些 新的价值,让我们继续前进,做到这一点。 958 00:43:30,710 --> 00:43:33,720 我们有机会现 选择另一个节点。 959 00:43:33,720 --> 00:43:39,820 说让我们与mallocing 55开始。 960 00:43:39,820 --> 00:43:41,320 会有人介意的malloc? 961 00:43:41,320 --> 00:43:42,280 好了,上来吧。 962 00:43:42,280 --> 00:43:42,992 你叫什么名字? 963 00:43:42,992 --> 00:43:43,700 彩虹:彩虹。 964 00:43:43,700 --> 00:43:44,050 DAVID马兰:彩虹? 965 00:43:44,050 --> 00:43:44,810 好吧。 966 00:43:44,810 --> 00:43:46,600 malloc的彩虹。 967 00:43:46,600 --> 00:43:47,450 上来吧。 968 00:43:47,450 --> 00:43:51,610 所以,现在我们要问自己, 算法,我们可以把55。 969 00:43:51,610 --> 00:43:53,610 所以,我们都知道, 显然,她很可能 970 00:43:53,610 --> 00:43:55,401 所属如果我们尝试 保持这个排序 971 00:43:55,401 --> 00:43:58,299 如果你们能带一个 退一步所以我们不脱落 972 00:43:58,299 --> 00:43:59,590 舞台上,那将是巨大的。 973 00:43:59,590 --> 00:44:01,420 所以实际上,彩虹, 从这里开始了我, 974 00:44:01,420 --> 00:44:04,200 因为我们的电脑现在可以 只看到一个变量的时间。 975 00:44:04,200 --> 00:44:05,190 因此,如果这是第一个节点。 976 00:44:05,190 --> 00:44:07,160 请注意,他不是一个节点, 他只是一个指针, 977 00:44:07,160 --> 00:44:10,270 这就是为什么他的画是 指针只大小,不 978 00:44:10,270 --> 00:44:11,780 其中的一个完整的矩形。 979 00:44:11,780 --> 00:44:16,650 因此,我们要检查每个 迭代比9 55少? 980 00:44:16,650 --> 00:44:17,150 第 981 00:44:17,150 --> 00:44:19,060 比17 55少了呢? 982 00:44:19,060 --> 00:44:19,720 第 983 00:44:19,720 --> 00:44:20,800 比22少? 984 00:44:20,800 --> 00:44:22,020 比26少? 985 00:44:22,020 --> 00:44:23,390 比34少? 986 00:44:23,390 --> 00:44:25,890 所以现在,很明显 彩虹所属的结尾。 987 00:44:25,890 --> 00:44:27,270 所以要明确,什么 是你的名字,泰勒? 988 00:44:27,270 --> 00:44:27,895 >> 泰勒:泰勒。 989 00:44:27,895 --> 00:44:32,510 DAVID马兰:所以之中泰勒 左手和彩虹的手在这里, 990 00:44:32,510 --> 00:44:38,324 谁的手需要在什么指向 为了将55进这个名单? 991 00:44:38,324 --> 00:44:39,240 什么是我们需要做什么? 992 00:44:39,240 --> 00:44:39,700 是吗? 993 00:44:39,700 --> 00:44:41,140 >> 听众:泰勒的手 需要指向左边。 994 00:44:41,140 --> 00:44:41,680 >> DAVID马兰:没错。 995 00:44:41,680 --> 00:44:43,800 所以插入一个节点 成列表的末尾 996 00:44:43,800 --> 00:44:47,140 很简单,因为泰勒刚 必须指向,而不是在地面 997 00:44:47,140 --> 00:44:49,640 或者我们叫它空, null是那种没有 998 00:44:49,640 --> 00:44:51,640 指针或特 零指针,你 999 00:44:51,640 --> 00:44:53,740 要指向用你的左手 手彩虹,然后彩虹, 1000 00:44:53,740 --> 00:44:55,910 其中,如果你的左 一方面可能是点? 1001 00:44:55,910 --> 00:44:56,570 向下。 1002 00:44:56,570 --> 00:45:00,140 这并不好,如果她的手是排序 在这里或排序的任何指点过的 1003 00:45:00,140 --> 00:45:00,640 哪一条路。 1004 00:45:00,640 --> 00:45:02,407 这将被视为 垃圾值, 1005 00:45:02,407 --> 00:45:04,240 但如果她指向 一些已知的价值,我们将 1006 00:45:04,240 --> 00:45:07,360 称之为零或零,这是确定 因为我们在这一个术语 1007 00:45:07,360 --> 00:45:09,390 我们知道名单现在就完成了。 1008 00:45:09,390 --> 00:45:11,550 >> 那么,什么是另一种 比较简单的情况下? 1009 00:45:11,550 --> 00:45:13,125 难道我们的malloc 5? 1010 00:45:13,125 --> 00:45:14,010 上来吧。 1011 00:45:14,010 --> 00:45:14,782 你叫什么名字? 1012 00:45:14,782 --> 00:45:15,490 蒂芬妮:蒂芙尼。 1013 00:45:15,490 --> 00:45:16,000 DAVID马兰:对不起? 1014 00:45:16,000 --> 00:45:16,470 蒂芬妮:蒂芙尼。 1015 00:45:16,470 --> 00:45:16,880 DAVID马兰:蒂芙尼。 1016 00:45:16,880 --> 00:45:17,110 好吧。 1017 00:45:17,110 --> 00:45:19,071 蒂芙尼一直malloced 用值5。 1018 00:45:19,071 --> 00:45:19,570 上来吧。 1019 00:45:19,570 --> 00:45:23,820 这一次是比较容易过,但 让我们考虑为了操作了。 1020 00:45:23,820 --> 00:45:25,820 这是很容易 与泰勒在末端。 1021 00:45:25,820 --> 00:45:30,302 号码5是当然小于9, 所以,我们有大卫,我们有蒂芙尼, 1022 00:45:30,302 --> 00:45:31,260 什么是你的名字吗? 1023 00:45:31,260 --> 00:45:31,680 >> 杰克:杰克。 1024 00:45:31,680 --> 00:45:32,470 >> DAVID马兰:杰克。 1025 00:45:32,470 --> 00:45:34,300 蒂芙尼,杰克和大卫。 1026 00:45:34,300 --> 00:45:36,580 谁的手,应该首先更新? 1027 00:45:36,580 --> 00:45:39,260 1028 00:45:39,260 --> 00:45:40,590 你想在这里做? 1029 00:45:40,590 --> 00:45:45,244 有一对夫妇可能的方式,但 另外还有一个或多个错误的方法。 1030 00:45:45,244 --> 00:45:46,620 >> 听众:先从最左边。 1031 00:45:46,620 --> 00:45:47,800 >> DAVID马兰:先从最左边。 1032 00:45:47,800 --> 00:45:49,008 谁是最左边的位置呢? 1033 00:45:49,008 --> 00:45:49,700 听众:第一。 1034 00:45:49,700 --> 00:45:50,366 >> DAVID马兰:OK。 1035 00:45:50,366 --> 00:45:53,781 因此,开始与第一,你在哪里 要更新大卫的手中呢? 1036 00:45:53,781 --> 00:45:54,780 听众:迈向5。 1037 00:45:54,780 --> 00:45:55,446 DAVID马兰:OK。 1038 00:45:55,446 --> 00:45:59,026 于是,大卫点五 或蒂芙尼在这里,现在呢? 1039 00:45:59,026 --> 00:46:01,072 >> 听众:蒂​​芙尼指向9? 1040 00:46:01,072 --> 00:46:04,030 DAVID马兰:完美的,除了宾基的 正中下怀头掉了下来,对不对? 1041 00:46:04,030 --> 00:46:06,820 因为这有什么错 这幅画从字面上? 1042 00:46:06,820 --> 00:46:08,070 听众:没有指向。 1043 00:46:08,070 --> 00:46:09,945 DAVID马兰:没有什么是 指着杰克了。 1044 00:46:09,945 --> 00:46:13,360 我们已经从字面上孤立9 17,我们已经从字面上 1045 00:46:13,360 --> 00:46:18,450 泄漏的这一切的记忆,因为 首先更新大卫的手,这是 1046 00:46:18,450 --> 00:46:21,660 精细因为它是正确的 现在在蒂凡尼指出, 1047 00:46:21,660 --> 00:46:25,410 但如果没有人有 深谋远虑地指向杰克, 1048 00:46:25,410 --> 00:46:27,490 那么,我们已经失去了 全部的列表。 1049 00:46:27,490 --> 00:46:28,200 因此,让我们撤消。 1050 00:46:28,200 --> 00:46:30,950 所以这是一件好事, 绊倒,但现在,让我们纠正。 1051 00:46:30,950 --> 00:46:33,624 我们应该怎么做第一呢? 1052 00:46:33,624 --> 00:46:34,124 是吗? 1053 00:46:34,124 --> 00:46:35,791 >> 听众:蒂​​芙尼应指向在9? 1054 00:46:35,791 --> 00:46:37,582 DAVID马兰:我不能 得到这个机会给你。 1055 00:46:37,582 --> 00:46:38,720 谁应该指向的9? 1056 00:46:38,720 --> 00:46:39,220 >> 听众:蒂​​芙尼。 1057 00:46:39,220 --> 00:46:39,390 >> DAVID马兰:好的。 1058 00:46:39,390 --> 00:46:41,200 因此蒂芙尼应在9第一点。 1059 00:46:41,200 --> 00:46:43,550 因此,蒂芙尼应 在一个相同的值 1060 00:46:43,550 --> 00:46:45,820 大卫,这似乎 多余的了片刻, 1061 00:46:45,820 --> 00:46:48,820 但是这很好,因为现在,第二 步骤中,我们可以更新大卫的手 1062 00:46:48,820 --> 00:46:52,680 为指向凡尼,然后如果 只是一种清洁我们的东西了 1063 00:46:52,680 --> 00:46:55,740 好像这是一种春天般的, 现在这是一个正确的插入。 1064 00:46:55,740 --> 00:46:56,700 所以,优秀的。 1065 00:46:56,700 --> 00:46:57,970 所以,现在我们快到了。 1066 00:46:57,970 --> 00:47:01,075 让我们插入一个决赛 值就像值20。 1067 00:47:01,075 --> 00:47:03,010 如果我们能malloc的最后一个志愿? 1068 00:47:03,010 --> 00:47:04,140 上来吧。 1069 00:47:04,140 --> 00:47:06,224 所以这一块是一个有点棘手。 1070 00:47:06,224 --> 00:47:08,390 但实际上,该代码我们 写作,尽管口头上, 1071 00:47:08,390 --> 00:47:10,610 就像有一群 如果现在的条件下,对​​不对? 1072 00:47:10,610 --> 00:47:12,318 我们有一个条件 若属于检查 1073 00:47:12,318 --> 00:47:13,840 在最后,也许是开始。 1074 00:47:13,840 --> 00:47:15,940 我们需要某种形式循环到 发现在中间的地方。 1075 00:47:15,940 --> 00:47:17,400 因此,让我们做到这一点与你叫什么名字? 1076 00:47:17,400 --> 00:47:17,700 >> 艾瑞克:埃里克。 1077 00:47:17,700 --> 00:47:18,340 >> DAVID马兰:埃里克? 1078 00:47:18,340 --> 00:47:18,660 埃里克。 1079 00:47:18,660 --> 00:47:19,368 很高兴认识你。 1080 00:47:19,368 --> 00:47:20,490 因此,我们有20个。 1081 00:47:20,490 --> 00:47:21,220 超过五少? 1082 00:47:21,220 --> 00:47:21,530 第 1083 00:47:21,530 --> 00:47:22,160 超过九少? 1084 00:47:22,160 --> 00:47:22,410 第 1085 00:47:22,410 --> 00:47:23,050 比17少? 1086 00:47:23,050 --> 00:47:23,550 第 1087 00:47:23,550 --> 00:47:23,740 行。 1088 00:47:23,740 --> 00:47:25,701 他属于这里 你的名字又是什么? 1089 00:47:25,701 --> 00:47:26,200 苏:苏。 1090 00:47:26,200 --> 00:47:26,880 DAVID马兰:苏。 1091 00:47:26,880 --> 00:47:27,379 亚历克斯:亚历克斯。 1092 00:47:27,379 --> 00:47:28,790 DAVID马兰:苏,亚历克斯和? 1093 00:47:28,790 --> 00:47:29,290 艾瑞克:埃里克。 1094 00:47:29,290 --> 00:47:30,120 DAVID马兰:埃里克。 1095 00:47:30,120 --> 00:47:32,140 谁的手先获取更新? 1096 00:47:32,140 --> 00:47:32,930 >> 听众:埃里克。 1097 00:47:32,930 --> 00:47:33,429 行。 1098 00:47:33,429 --> 00:47:35,200 因此,Eric的应指向哪里? 1099 00:47:35,200 --> 00:47:35,930 在22。 1100 00:47:35,930 --> 00:47:36,430 好。 1101 00:47:36,430 --> 00:47:38,180 现在,下一步是什么? 1102 00:47:38,180 --> 00:47:40,800 然后苏可指向埃里克 而现在,如果你们只是 1103 00:47:40,800 --> 00:47:44,077 使一些空间,这是罚款 在视觉上,现在我们所做的插入。 1104 00:47:44,077 --> 00:47:47,160 现在让我们考虑一个问题,但 非常感谢你对我们的志愿者。 1105 00:47:47,160 --> 00:47:48,090 非常出色地完成。 1106 00:47:48,090 --> 00:47:50,831 您可以保留这些,如果你喜欢。 1107 00:47:50,831 --> 00:47:54,140 我们有一个可爱的临别礼物,如果 你每次想借此压力球。 1108 00:47:54,140 --> 00:47:56,030 让我传递下来。 1109 00:47:56,030 --> 00:47:58,430 那么,什么是这个外卖? 1110 00:47:58,430 --> 00:48:02,430 这似乎是惊人的 只要我们现在有 1111 00:48:02,430 --> 00:48:06,360 引入了一个替代的 阵列事实并非如此局限 1112 00:48:06,360 --> 00:48:07,780 到一些固定尺寸的阵列。 1113 00:48:07,780 --> 00:48:09,380 他们可以动态地增长。 1114 00:48:09,380 --> 00:48:13,220 >> 但是,就像我们已经看到在周 过去,我们从来没有得到任何东西是免费的, 1115 00:48:13,220 --> 00:48:15,740 喜欢肯定有一个权衡在这里。 1116 00:48:15,740 --> 00:48:18,890 因此,与一个链接的上涨空间 列表,是这种活力? 1117 00:48:18,890 --> 00:48:21,590 这种能力成长,坦率地说, 我们可以做删除 1118 00:48:21,590 --> 00:48:23,570 并根据需要,我们有可能缩小。 1119 00:48:23,570 --> 00:48:24,710 是我们付出什么样的代价? 1120 00:48:24,710 --> 00:48:28,510 1121 00:48:28,510 --> 00:48:30,340 两倍的空间,首先。 1122 00:48:30,340 --> 00:48:34,010 如果你看一下图片,不再 我是存储整数列表。 1123 00:48:34,010 --> 00:48:36,740 我存储的列表 整数加指针。 1124 00:48:36,740 --> 00:48:38,240 所以我加倍的空间量。 1125 00:48:38,240 --> 00:48:40,740 现在,也许这不是这样的 什么大不了的4个字节,8个字节, 1126 00:48:40,740 --> 00:48:43,160 但它当然可以加 弥补大型数据集。 1127 00:48:43,160 --> 00:48:45,570 什么是另一个缺点? 1128 00:48:45,570 --> 00:48:46,070 是吗? 1129 00:48:46,070 --> 00:48:48,010 >> 听众:我们要 遍历它们一个接酮。 1130 00:48:48,010 --> 00:48:48,760 DAVID马兰:是的。 1131 00:48:48,760 --> 00:48:50,260 我们必须遍历它们一个接一个。 1132 00:48:50,260 --> 00:48:53,860 你知道吗,我们放弃了这个超级 括号的方便的功能, 1133 00:48:53,860 --> 00:48:57,240 符号,更恰当 称为随机存取, 1134 00:48:57,240 --> 00:48:59,280 在这里我们可以自己跳 到单个元素 1135 00:48:59,280 --> 00:49:01,470 但现在,如果我仍然有 我的志愿者在这里, 1136 00:49:01,470 --> 00:49:04,660 如果我想找到 22号,我不能只 1137 00:49:04,660 --> 00:49:06,620 跳转到支架上一些东西。 1138 00:49:06,620 --> 00:49:10,530 我要看看在列表中,多 像我们的搜索例子线, 1139 00:49:10,530 --> 00:49:12,260 找到数22。 1140 00:49:12,260 --> 00:49:14,340 因此,我们似乎已经付出了代价那里。 1141 00:49:14,340 --> 00:49:16,430 但是,我们还是能够 解决其他问题。 1142 00:49:16,430 --> 00:49:18,587 >> 其实,我来介绍一下 只是一对夫妇的视觉效果。 1143 00:49:18,587 --> 00:49:20,920 所以,如果你已经下降到 马瑟饭堂最近, 1144 00:49:20,920 --> 00:49:23,320 你还记得自己 栈这样的托盘, 1145 00:49:23,320 --> 00:49:26,300 我们从借来的这些 课前安嫩伯格。 1146 00:49:26,300 --> 00:49:28,930 所以这个栈托盘,不过, 代表实际 1147 00:49:28,930 --> 00:49:30,860 一个计算机科学的数据结构。 1148 00:49:30,860 --> 00:49:32,910 有一个数据结构 在计算机科学 1149 00:49:32,910 --> 00:49:38,010 被称为栈非常漂亮 适合于正是这种视觉。 1150 00:49:38,010 --> 00:49:41,380 因此,如果每一个托盘的是不是一个 托盘但像一些,我想 1151 00:49:41,380 --> 00:49:45,010 存储的数字,我 可以放一到这里, 1152 00:49:45,010 --> 00:49:48,320 我可以把另一个倒在这里, 并不断堆积号码 1153 00:49:48,320 --> 00:49:53,180 对彼此,什么是顶部 这个可能有帮助 1154 00:49:53,180 --> 00:49:55,450 是什么含义 这种数据结构? 1155 00:49:55,450 --> 00:49:58,045 哪个号码,我可以拉出来 第一个最方便? 1156 00:49:58,045 --> 00:50:00,640 1157 00:50:00,640 --> 00:50:03,030 最近期看跌的存在。 1158 00:50:03,030 --> 00:50:06,430 >> 所以,这就是我们所说的 计算机科学后进先出的数据结构。 1159 00:50:06,430 --> 00:50:08,070 后进先出。 1160 00:50:08,070 --> 00:50:10,800 我们将不久为什么看 现在可能是有用的,但对于, 1161 00:50:10,800 --> 00:50:12,200 只是考虑物业。 1162 00:50:12,200 --> 00:50:15,158 而且它是一种愚蠢的,如果你想 有关如何食堂做的。 1163 00:50:15,158 --> 00:50:17,910 他们每次清洁托盘 把最新鲜的人之上, 1164 00:50:17,910 --> 00:50:22,160 你可以有一个以前干净 但最终很脏乱,尘土飞扬 1165 00:50:22,160 --> 00:50:24,360 托盘在最底层 如果你从来没有真正 1166 00:50:24,360 --> 00:50:26,820 得到的,该底部 堆栈,因为你 1167 00:50:26,820 --> 00:50:29,380 不断把新的, 干净的人在它的上面。 1168 00:50:29,380 --> 00:50:31,840 同样的事情可能会发生 在一家超市了。 1169 00:50:31,840 --> 00:50:35,450 如果你有一个陈列柜 牛奶每次CVS 1170 00:50:35,450 --> 00:50:37,610 或者谁得到更多的牛奶, 你刚才推的牛奶 1171 00:50:37,610 --> 00:50:39,880 你已经拥有的背部和 你把新的锋线, 1172 00:50:39,880 --> 00:50:43,088 你将有一些非常讨厌 牛奶在数据结构的末尾, 1173 00:50:43,088 --> 00:50:46,390 因为它总是在底部或 等效它总是在后面。 1174 00:50:46,390 --> 00:50:50,407 >> 但还有另一种方式来思考 排队的数据和例如,此。 1175 00:50:50,407 --> 00:50:53,490 如果你是其中的一个人谁喜欢 排队的苹果专卖店外 1176 00:50:53,490 --> 00:50:55,610 当一个新的产品来 出来,你可能 1177 00:50:55,610 --> 00:50:58,780 不使用堆栈数据 结构,因为你 1178 00:50:58,780 --> 00:51:03,070 会疏远其他人谁是 排队购买一些新的玩具。 1179 00:51:03,070 --> 00:51:06,610 相反,你可能使用 什么样的数据结构的 1180 00:51:06,610 --> 00:51:10,050 或者是什么样的制度 在现实世界? 1181 00:51:10,050 --> 00:51:13,493 希望这是一条线,或更多 正确或更多的英国状,一个队列。 1182 00:51:13,493 --> 00:51:17,700 而事实证明队列也是 数据结构,计算机科学, 1183 00:51:17,700 --> 00:51:19,700 但一个队列具有一个非常 不同的属性。 1184 00:51:19,700 --> 00:51:20,820 这不是后进先出法。 1185 00:51:20,820 --> 00:51:21,990 后进先出。 1186 00:51:21,990 --> 00:51:22,800 上帝保佑。 1187 00:51:22,800 --> 00:51:24,280 这是不是FIFO。 1188 00:51:24,280 --> 00:51:26,110 先入先出。 1189 00:51:26,110 --> 00:51:27,970 这是一件好事 为公平起见 1190 00:51:27,970 --> 00:51:30,428 当然,当你排队 早上起来的超级早。 1191 00:51:30,428 --> 00:51:33,400 如果你第一次那里,你 想要得到第一个为好。 1192 00:51:33,400 --> 00:51:35,880 >> 所以,所有的这些数据, 结构,队列,栈 1193 00:51:35,880 --> 00:51:39,220 和其他人一束束,原来你 可以认为这是只是一个数组。 1194 00:51:39,220 --> 00:51:41,820 这是一个数组,也许 一个固定大小为4,但它会 1195 00:51:41,820 --> 00:51:44,990 是种不错的,如果我们可以只堆 托盘几乎可以无限高的,如果我们 1196 00:51:44,990 --> 00:51:46,780 有那么多的托盘或数字。 1197 00:51:46,780 --> 00:51:48,840 因此,也许我们要 使用链表这里, 1198 00:51:48,840 --> 00:51:51,800 但权衡将是 可能我们需要更多的内存, 1199 00:51:51,800 --> 00:51:55,930 需要多一点的时间,但我们 不限制叠层的高度, 1200 00:51:55,930 --> 00:51:59,550 就像奥美的陈列柜 可能限制堆栈的大小, 1201 00:51:59,550 --> 00:52:03,117 等等这些都是设计决策或 可供我们选择大势所趋。 1202 00:52:03,117 --> 00:52:04,950 因此,这些数据 结构,我们已经开始 1203 00:52:04,950 --> 00:52:09,360 看到新的上限可能 什么以前是超级快 1204 00:52:09,360 --> 00:52:11,260 当我们将离开 今天关在哪里 1205 00:52:11,260 --> 00:52:13,200 我们希望能得到 上周三,我们将 1206 00:52:13,200 --> 00:52:15,740 开始看数据 结构让我们搜索 1207 00:52:15,740 --> 00:52:18,260 通过日志结束时间的数据了。 1208 00:52:18,260 --> 00:52:21,470 并且我们看到了,记得,在零一周 和一个用二进制搜索或除法 1209 00:52:21,470 --> 00:52:22,180 和征服。 1210 00:52:22,180 --> 00:52:26,240 这是回来了,更好的是, 圣杯这个星期三 1211 00:52:26,240 --> 00:52:29,510 将要拿出 运行真正的数据结构 1212 00:52:29,510 --> 00:52:32,070 或者理论上 恒定时间,由此 1213 00:52:32,070 --> 00:52:34,760 不要紧多少 千万甚至上亿的东西 1214 00:52:34,760 --> 00:52:38,470 我们已经在该数据结构中,它会 需要我们持续的时间,也许一步 1215 00:52:38,470 --> 00:52:41,387 两个步骤或10个步骤, 但步骤常数 1216 00:52:41,387 --> 00:52:42,970 通过该数据结构进行搜索。 1217 00:52:42,970 --> 00:52:46,300 这的确将是制胜法宝 但更多的是在周三。 1218 00:52:46,300 --> 00:52:49,045 见雅则。 1219 00:52:49,045 --> 00:52:53,704 >> [音乐播放] 1220 00:52:53,704 --> 00:56:08,448