DAVID J.马兰:好的。 所以欢迎大家来首次 CS50死后来做个测试​​。 我们认为我们会开幕 这一传统在今年。 这将是一个机会 漫步 解决方案的测试。 我们会加快或基于放缓 对那些在这里的利益。 所以你可能在这里,因为你 感兴趣的是如何你可以有或 应该回答一些 的这些问题。 那么我们为什么不来看看 在本节第一? 因此让字符串。 这给了你三个不同的版本 一个程序,是的,最终, 为了从用户获得一个字符串。 不论它这样做是 留给你来决定。 我们问的问题0, 假设第1版 编译和执行。 为什么会程序出现段错误? 乍一看,有什么建​​议 至于为什么? 是啊。 观众:所以我记得在看到这个 看着在前面的例子 的char * s和看到S的扫描和 看到因为它是一个指针,如何 没有它会影响您的扫描? 它是S或s的地址? DAVID J.马兰:确定。 好。 所以,最后,任何问题的来源 大概是要减少 该变量s。 而且这的确是一个变量。 该变量的数据类型是 的char *,这意味着它要 包含一个字符的地址。 而这其中就有敏锐的洞察力。 它要包含的地址 一个字符,或者更一般地,本 在第一个字符的地址 字符的整个块。 但美中不足的是,扫描秒,目的在 生活中,被赋予一个地址和给定的 格式的代码,如%s,读取 字符串转换成的块 存储在该地址。 但因为没有等号前 在第一次的分号 一行代码,因为我们实际上并不 分配任何内存 malloc的,其实是因为它没有 分配一些大小的数组,所有 你正在做的是读取用户 键盘输入到一些完整的 垃圾值, 是s中默认情况​​下。 所以赔率是你要出现段错误,如果 该地址并不仅仅如此发生 是一个值就可以了, 其实,写。 如此糟糕不分配 你的内存有。 因此,在问题1中,我们问, 假设2版 编译和执行。 为什么会这个程序出现段错误? 所以这一块是bug更少。 而且也真的只有一个 显而易见的方法,你可以 这里触发段错误。 这是主题。 任何我们用c + +在内存中的时间,有什么 你能做些什么来诱发段错误 与第2版? 观众:如果您使用的输入 一个字符串,它比49再 字符。 DAVID J.马兰:没错。 你看到的东西固定长度的任何时间 当它涉及到一个数组,你 雷达会熄灭,这可能是 有问题的,如果你不检查 阵列的界限。 这就是这里的问题。 我们仍然使用scanf函数。 我们还在用%s,这意味着尝试 从用户读取的字符串。 这就是它会被读成s,, 在这一点上,是有效的 内存块的地址 或同类产品。 这是一个数组的名字 的内存字符。 但恰恰是,如果你读一个字符串 这是超过49个字符,49长 因为你需要的空间反斜线 0,你要溢出 该缓冲区。 你可能会得到幸运,能够 写一个字第51,第52,第53。 但在某些时候,操作系统 会说,没有。 这绝对不是内存 你不准碰。 并且程序将会出现段错误。 因此,启发式应该有任何 你已经有了固定长度的时间,你有 确保你检查的长度 不管它是什么你想要 读了进去。 观众:所以要解决这个问题,你可以 有一个说法实际上检查 为长度大于 大于或小于? DAVID J.马兰:当然可以。 你只需要一个条件 那说,如果 - 或者说你不一定知道 提前多少个字符 用户将要输入时,因为 你有鸡和蛋。 直到你跟scanf函数读取它 你可以计算出它有多长。 但在这一点上,为时已晚, 因为你已经将它读入 一些内存块。 所以,作为一个在旁边,CS50库避免了 这个问题完全,召回 用龟etc。 它读取一个字符时, 针尖沿着八字,知道你 不能溢出一个字符,如果 你读一次。 美中不足的是GetString的召回 我们必须不断地调整大小 那大块的内存,这 仅仅是一个痛苦。 这是一个很大的行 代码来做到这一点。 因此,另一种方法是将 实际使用的表弟,所以 说话scanf函数的。 有很多这样的变种 功能,实际上检查 的长度多少个字符 你可能会最大限度地阅读。 并且您可以指定,不读 超过50个字符。 所以这将是另一种方法,但 更大的投入较少宽松。 所以,问题2问,假设版本 3编译和执行。 为什么会是程序出现段错误? 所以这一块实际上是相同的 回答,即使它 看起来有点票友。 我们正在使用的malloc,这感觉就像 我们正在给自己更多的选择。 然后我们释放了 存储在末尾。 它仍然只有50个字节的内存。 因此,我们可能仍然尝试读取 在51,52,1000字节。 它会出现段错误的 正是由于同样的原因。 但还有另外一个原因了。 还有什么能malloc返回除了 内存块的地址? 它可能返回null。 而且因为我们不检查 这一点,我们可能会做一些 愚蠢的另一个原因,那就是 我们可能会告诉scanf函数,读取 用户从键盘输入 到0的位置,又名空。 而这,也一定会 触发段错误。 所以对于测验的目的,我们将 已接受或者那些作为的 正当理由。 一个是相同的。 一个是多了几分微妙。 最后,相对于该节目的 使用的内存,怎么办第2版和 第3版有什么区别? 因此,对于它的价值,我们看到了一个 可能看似源源不绝 回答这个。 而人与人之间的答案,我们都 希望,但我们接受的其他 的东西,是一些提到的 事实上版本2使用 所谓堆栈。 版本3正在使用的堆。 而在功能上,这并没有真正 让所有的多大的差别。 在一天结束的时候,我们仍然 刚开50字节的内存。 但是,这是可能的答案之一 我们在看。 但你会看到,当你得到你的测验 从转录因子回首,那我们做 接受其他讨论他们的 内存完全不同的用途。 但堆栈和堆本来 一个简单的答案去用。 有问题吗? 我给你抢。 ROB BOWDEN:所以问题4。 这是一个在那里你必须填写 在字节数出所有的 这些不同类型的使用。 我们看到那么第一件事情。 假设一个32-bit架构, 这样CS50设备。 所以对基本的事情之一 32位体系结构,它告诉我们 到底有多大的指针是怎么回事 是在体系结构。 于是马上,我们知道,任何指针 类型是32位或4个字节。 所以看这个表, 节点*为指针类型。 这将是4个字节。 结构节点*,这是字面上 相同的节点明星。 所以那将是4个字节。 字符串,所以它看起来并不像一个 指针还,但自定义类型,一 字符串只是一个char *,这 为指针类型。 所以这将是4个字节。 所以,这三个都是4个字节。 现在,节点和学生都 更复杂一点。 所以看着节点和学生,我们看到 节点为一个整数和一个指针。 和学生是两个指针 里面的它。 所以至少在我们的情况下在这里,该方法 我们最终计算的大小 这个结构是只加了一切 这就是结构体里面。 因此,对于节点,我们有一个整数, 这是4个字节。 我们有一个指针,它是4个字节。 所以一个节点是怎么回事 占用8个字节。 同样的学生,我们有 指针,该指针是4字节而另一个 指针就是4个字节。 所以这将结束 最高为8个字节。 因此,节点和学生都是8个字节。 而这三项都是4个字节。 该问题? 是。 观众:是它是一个64位 建筑,那会 加倍所有的人? ROB BOWDEN:不会 加倍所有的人。 因此,64位架构,它再次, 的变化,根本的东西,一个 指针现在是64位。 是啊。 这样一个指针是8个字节。 因此,这些是分别为4个字节 都将是8个字节。 一个学生,这是两个指针, 好了,现在它要 是8个字节,8字节。 这将会使16个字节。 但一个节点仍然是4个字节。 所以这个指针是怎么回事 为8字节。 这是4个字节。 所以一个节点只打算 为12个字节。 在那一个别的问题吗? 所以,下一个,这些都是 HTTP状态码。 而你必须描述的情况 根据这些威力 退还给您。 我听到有些同学一个问题 有是,他们试图使 错误是在客户端的结束。 所以,当我们试图提出要求 到服务器上,出了 错在我们这边。 但一般来说,这些代码是 服务器正在返回。 因此,我们要弄清楚这是怎么回事 错误或正确的服务器上 导致返回这些东西。 那么,为什么一个服务器返回 状态代码200? 有什么想法? 是啊。 因此,一些关于成功 请求经历。 而且他们能够返回 不管你提出的要求。 所以,一切都很好。 怎么样302发现了什么? 是啊。 观众:服务器一直在寻找 为你所要求的。 但无法找到它。 所以这是一个错误。 ROB BOWDEN:那么服务器是 找你想要的东西。 所以只是看这里,302发现, 它能够找到它。 观众:我很抱歉。 发现意味着,他们没有找到它。 抱歉。 ROB BOWDEN:那么302个记录。 该服务器能够找到 你想要的东西。 观众:但它不显示呢? ROB BOWDEN:之间的区别 这个302和200的是,它 知道你想要什么。 但它是不完全的地方 你要问。 所以302是一个典型的重定向。 所以,你所请求的页面。 它知道,哦,我想 给你退货。 但是,这是在一个不同的URL。 所以,嘿,你真正想要的。 DAVID J.马兰:这是一块提到 我们给你们一个重定向 函数所使用的头功能 这,反过来,打印出来的位置, 冒号,然后到的URL 你要拒绝的用户。 即使你没看见302 明确存在,这就是PHP的 会奇迹般地插入的标头 说正是罗布说有 - 发现。 但到这里吧。 ROB BOWDEN:确定。 那么,关于403被禁止? 观众:我认为这是服务器 基本上说,在客户端 无法访问主页。 ROB BOWDEN:所以,是的。 嗯,典型的答案我们 期待是一样的东西,这些文件 没有适当chmodded。 这可能是在什么情况下 你看见了他们。 但还有一个原因,客户端 可能是错在这里。 实际上,有另外一个状态代码 - 401。 因此,这些都是非常相似的。 401是未经授权的。 而403是被禁止的。 所以你们擅自专 如果你没有登录。得到 但登录可能意味着 你被授权。 但如果你已经登录,并且您 仍然没有权限,然后 你也可以禁止。 所以,如果你登录并且没有 许可,严禁也是 有些东西你可以得到的。 DAVID J.马兰:而到了机制 这些问题通常是 解决了在服务器上是 通过什么命令? 文件模式,如果是,的确,一个权限 发出的文件或目录。 ROB BOWDEN:那404未找​​到。 是啊。 所以不像302的地方是不完全 在那里你问,但它知道什么 你想,这一点,它只是 不知道你想要什么。 而你没有请求 一些有效的。 418我是一个茶壶,然后 500内部服务器。 那么,为什么你明白了吗? 所以出现段错误 - 我居然不知道该分级 标准这一点。 但是,如果你的PHP代码有一些东西 错了,从理论上讲,它可以 实际上段错误,在这种情况下,这 500内部服务器错误,东西 是错误的与您的服务器的 配置。 或者有语法错误 在你的PHP代码。 或坏事是怎么回事。 DAVID J.马兰:我们确实看到段错误 其中几个人的答案。 而在技术上,它可能发生。 但是这将是一个PHP的程序 其他人写的,实际上 segfaulted,只如果那些人 搞砸了,并在写bug的代码 他们的解释器 PHP本身出现段错误。 因此,即使500就像是一个段错误 在精神上,它几乎总是 配置文件问题的结果 与您的Web服务器,或如罗布说, 一个语法错误,像你 没有关闭的报价。 或者你在某处失去了一个分号。 观众:所以对于班车PSET,我 认为当我做到了,一旦我点击 浏览器,但没有上来, 他们所谓的白页。 但它是因为代码。 我认为这是JavaScript的,对不对? ROB BOWDEN:是啊。 观众:请问这个错误 还是来了? ROB BOWDEN:所以你就不会得到 这个错误,因为一切 从Web服务器的角度来看 是完全没问题。 但你要求的index.html。 你要求shuttle.js 和service.js。 它能够成功返回 给你所有这些事情 - 200。 确定。 只有当您的浏览器尝试 解释JavaScript代码 这就像,等待,这是不 有效的JavaScript错误。 还有没有其他问题? 好的。 DAVID J.马兰:那么下一个 时间为11号。 和11是最可怕的 对于很多人。 所以最重要的事情需要注意 是,这是,事实上,大约 一个双向链表。 但是,这并不等同于去年的 双向链表的问题, 它没有给你有条件的,就是 这个名单可以,其实是未排序。 这样一个事实,即列表是排序的 而事实上,这个词是 有下划线是为了传达 这实际上是一种简化 什么否则会一直 更具挑战性的问题 和一个较长的一个。 所以这里一个常见的​​错误是已经把 您的最后一个年度的解决方案 寻呼机,然后就盲目地复制 跌的答案,这是正确的 回答不同的问题 类似的精神。 但这里的微妙之处 分别如下。 因此,一个,我们有一个节点,并宣布 在这里以通常的方式来定义。 然后,我们定义列表是一个全球性的 指针初始化为null。 那么显然,有两个功能 我们有原型在这里,插入 并删除。 然后,我们这里有一些示例代码 的做了一堆插入的。 然后,我们要求你完成 下面的实施刀片以这样 一种方式,它插入n转换成列表 在固定的时间,还强调, 即使已经存在。 因此能够插入美女 在常数时间是,它意味着 你必须插入 新的节点在哪里? 到前面。 所以它消除了,幸运的是,至少 的过去需要一个案件 甚至更多的代码行,像它那样 去年,甚至在上课的时候​​我们 通过这种事情谈 与人类和一些 语言伪代码。 所以在这里的解决方案,让我们跳过 到只是为了有一个视觉上的 在屏幕上。 请注意,我们正在做以下。 同时也注意到另一种简化 是,即使是 已经存在的,所以这意味着即使 数已经是存在的,你可以 只是一味地插入另一 它的副本。 而这,太,本来是一个 简化,这样你可以 集中精力,说真的,一些比较 智力有趣的部分和 不只是一些额外的错误检查 在有限的时间。 所以在这个示例解决方案,我们分配 在左侧的指针 这里边一个节点。 现在,认识到指针,如 罗布说,只有32位。 而实际上它并不包含 一个地址,直到你 分配给它的地址。 我们这样做的右手 通过malloc的一面。 像一个好公民,我们检查 malloc的是不是,事实上,空,从而使 我们不小心创建 这里一个段错误。 任何时候你在生活中使用malloc,你 应检查null,以免 你有一个微妙的错误。 然后我们初始化由空 分配n和上一页和下一页。 而在这里这种情况下,我初始化 以前为null,因为这个新的 节点将是新的 开始我的名单。 所以有将是 什么才。 我想基本上追加 现有列表,由新的节点 接下来设置等于列表本身。 但我没有这样做,只是还没有。 所以,如果列表本身已经存在, 并且有至少有一个节点 已经到位,如果是这样的列表 在这里,我插入一个新的节点在这里,我 需要确保我的前任节点 向后指向我的新节点, 因为这是再一次 一个双向链表。 所以我们做完整性检查。 如果列表不为空,如果有已经 一个或多个节点存在,则 添加反向引用可以这么说。 然后,我们需要的最后一件事 这样做实际上是更新全局 变量列表本身为指向 到该新节点。 是啊。 观众:在指针箭头 [听不清]等于null,即不 处理列表中,因为 该列表为空? DAVID J.马兰:不。 这简直是​​我正在积极 小心,因为如果这是我的 原来列表也许更多一些节点 在这里,我插入我的 在这里新的节点,还有的将 是什么在这里。 我希望捕获的想法 通过设置前,以 在新节点上无效。 想必,如果我的代码是正确的 并有插入没有其他办法 节点比这个功能以外, 据推测,即使列表已经有 在它的一个或多个节点,想必 列表中,在第一个节点,将具有 空本身先前的指针。 观众:而就在跟进。 你把指针下一个等号的原因 列表是你正在做的指针 列表中,它的指向前 下一个,我猜 - 我鸵鸟政策 - 只是列出? DAVID J.马兰:没错。 所以,让我们真正考虑两种情况 这里真的,即使 订单,我们会考虑他们是不是 不太一样的代码。 但在一个高的水平,如果该指 列表,这是一个32位的 指针,最简单的情况是 这是默认为空。 并假设我想插入 数字50是一个数字。 所以我要继续前进并分配 一个节点,它也会包含 三个领域 - N,上一页和下一页。 我打算把50号 在这里,因为这会为n。 这将是下一个。 而这将是以前的。 所以我该怎么在这种情况下呢? 好吧,我刚刚做1号线在这里。 指针n得到Ñ。 我接着说,以前的 应该得到空。 因此,这将是空。 然后我会说下 是会得到列表。 而这只是工作搞好。 这是空。 所以我说,新节点的下一个 字段应该得到什么,这是。 让把另一个空在那里。 再过去的事情 我要做的就是在这里检查。 如果list不等于空,但它 等于空,所以我们跳过 干脆。 等等一切我下一步要做的就是获取列表 指针,它形象地导致 类似的图片。 所以这是一个情景。 和一个你问的是有关 具体是这样的情况, 我们已经有一个单节点列表。 如果我回去了原 问题陈述,接下来我们将 插入说的是34,只为 就事论事。 所以我打算只方便 绘制在这里。 我刚刚malloced。 假设我检查null。 现在,我要初始化 电量为34。 这将为n。 这将是下一个。 而这将是以前的。 让我们确保我没有 得到这个倒退。 上一页至上 在该定义中。 让我来解决这个问题。 这是以前的。 这是下一个。 尽管这些是相同的, 让我们保持一致。 上一页。 这是下一个。 所以,我刚刚malloced我的注意,检查 为null,则分配34到节点。 上一页变空。 所以,让我说。 下一步得到列表。 所以列表是这样的。 所以这个现在是一样的绘画本 箭头,使它们指向一个 中是相同的。 然后我检查,如果列表 不等于空。 它不是这个时候。 那么我该怎么办名单 先前得到的指针。 所以列表上得到的PTR。 所以这把的效果 这里的图形箭头。 这就是开始有点 波浪状的线条。 然后,我最后更新 列出指向指针。 所以,现在这个指向这个家伙。 现在,让我们做一个快速 完整性检查。 这里的名单,这是 全局变量。 第一个节点是,事实上,34,因为 我下面的箭头。 这就是正确的,因为我想 插入在列表的开头 所有新的节点。 他的下一场让我这个家伙。 如果我坚持下去,我打接下来为空。 所以没有更多的列表。 如果我打以前,我得到 回到了我的期望。 所以还是有几个指针, 显然,操纵。 但事实上,你被告知这样做 这在常数时间内只意味着你 有一个事物的有限数目 你可以这样做。 那是什么号码? 它可能是一个步骤。 这可能有两个。 这可能是1000步。 但它是有限的,这意味着你不能 有什么样的循环的事 在这里,没有递归,没有循环。 这只是必须是硬编码线 的代码,因为我们有这样的样本。 所以接下来的问题12问我们 完成删除的实现 下面以这样一种方式,它消除 N从该列表中的线性时间。 所以,你必须多一点 现在回旋的余地。 你可以假设N,如果存在 在列表中,将存在 不超过一次。 而这也意味着是一个测验为基础的 简化的假设,因此 如果你发现数字50的地方 在列表中,你不还 担心继续 遍历,寻找一切可能的 50个拷贝,这将只是下放 为在有限的时间一些细节。 因此,与删除,这其中肯定 更具挑战性和更 代码编写。 但乍一看,坦率地说,它可能 看起来喧宾夺主,喜欢的东西 有没有办法,你可以有 拿出了一个小测验。 但是,如果我们专注于各个步骤, 希望,它会突然 打击你,每个个体的 步骤做明显的感觉 回想起来。 因此,让我们一起来看看。 因此,首先,我们初始化指针 是列表本身。 因为我想线性时间,那手段 我要去有一些循环。 和常见的方式来遍历 在列表结构或任何种类的节点 结构的迭代是采取 一个指针的数据的前 结构,然后就开始更新 它和走你的路 通过该数据结构中。 所以我打算这样做。 虽然指针,我的临时变量, 不等于空,让我们 继续和检查。 难道我很幸运? 是我目前的节点n场 看着等于 数我在找? 如果是这样,让我们​​做一些事情。 现在,请注意这一点,如果条件 围绕整个 代码如下行。 这是我所关心的唯一的事情 - 发现了一些问题。 所以没有其他人,从而简化 概念上的东西一点点。 但现在,我才明白,你可能有 只有思前想后意识到了这一点 它通过了一下,有 实际上2箱子这里。 一种是其中的节点是在 开头的列表,这是一个的 有点讨厌,因为这是一个 特殊情况,因为你必须处理 有了这个东西,这 是唯一的异常。 放眼天下,列表, 这是同样的事情。 有一个以前的节点和下一 节点,前一个节点,下一个节点。 不过这家伙有点特殊 如果他是在开始。 因此,如果该指针等于列表 本身,因此,如果我在初 列表中,我发现N,我需要 做了几件事情。 一,我需要改变列表 指向下一个领域,50。 因此,假设我想 删除34。 原来这家伙的得走了 走一会儿就好了。 所以我要说,列表 获取指针下一个。 那么,这是指针。 接着指向了这里。 所以,这种情况正在改变这个箭头向右 现在指向这个家伙在这里。 现在,请记住,我们有 一个临时变量。 所以我们并没有孤立的任何节点, 因为我也有这个家伙在我 执行删除的。 所以,现在,如果列表本身不为空, 我需要修复的一点心意。 我现在需要确保这个箭头, 这是先前指向 从50到34,这得走了, 因为如果我试图摆脱 34,50,最好不要保留任何 一种反向引用它作为 箭头提示。 所以,我只是做了这一行。 所以后来我做。 这种情况下,实际上是非常容易的。 斩去列表的头部 相对来说比较简单。 遗憾的是,这 恼人的else块。 所以,现在,我要考虑的情况下 那里有什么东西在中间。 但它不是太可怕了,除了 像这样的语法。 所以,如果我不在的开始 名单,我在中间某个地方。 而这条线在这里是说,开始 在任何节点你在。 前往上一个节点的下一个字段 并指出,在指针。 让我们做这样形象地。 这是越来越复杂。 所以,如果我有一个以前的领域在这里 - 让我们做到这一点 - 下一个栏位在这里。 我要简化我的指针,而 比画出一大堆 东西来回往返奔波 对方。 现在,让我们只说这是1,2, 3为便于讨论,甚至 虽然不与排队 所讨论的问题。 因此,这里是我的链接列表。 我想在此删除两个 特别版本的故事。 所以,我已经更新指针 是指向这个家伙。 因此,这是PTR。 他指指点点。 这是列表,其中存在 作为全球前。 而且他指指点点不管。 而现在,我试图删除两个。 所以,如果指针指向这里,我 要遵循,显然,该 以前的指针,这使我在1。 我接着要说的话,下一个 场,这使我到这 框这里,将要 平等的指针下一个。 因此,如果这个指针,这是下一个。 这意味着,该箭头的需求 指向这个家伙。 那么,这行代码刚 所做的就是这一点。 而现在,这看起来像一个 步在正确的方向。 我们基本上要剪断2出 的1和3的中间。 因此,它是有道理的,我们要 路线this指针周围。 因此,这下一行检查,如果指针 接下来是不是null,则 确实有人为2的右边, 这意味着我们还必须做 这里一点剪断。 所以,我现在需要遵循这个指针 和更新先前的指针 这家伙做的一点点 解决办法在这里这里的重点。 而现在,在视觉上,这是很好的。 这是一个有点凌乱在有 没有人在2指点了。 2是指向左边。 和图2是指向右侧。 但他可以做任何他想做的,因为 他即将得到释放。 它什么都无所谓 这些值了。 最重要的是,剩余的 家伙上面的路由 现在他之下。 事实上,这正是我们下一步的行动。 我们免费的指针,这意味着我们告诉 操作系统,欢迎你 回收这一点。 然后最后,我们返回。 否则含蓄,如果我们 还没有还回来, 我们必须继续寻找。 所以指针等于next指针刚 这里指移动这个家伙。 搬到这里这个家伙。 这里提出这个家伙的话,其实, 我们没有发现的数 我们正在寻找的呢。 所以坦率地说,它看起来完全 铺天盖地,我认为,首先 一目了然,特别是如果你挣扎 与此测验中则见 这样的事情。 和你拍拍自己的背。 那么,有没有办法,我能有 想出,关于测验。 但我认为,你可以,如果你打破 它分解成这些个人 例,只是通过它走 小心,虽然,不可否认,在 压力的情况下。 值得庆幸的是,画面制作 一切快乐。 你可以在此画 任何数量的方式。 你不必做交叉的 这里的事情。 你可以用直线做 线路是这样的。 但这个问题的要点,在 一般情况下,是要认识到,在 图片到底应该看起来有点 这样的事情,因为 固定的时间暗示你保持 干扰与抗干扰和干扰的 在开始新的节点 的列表。 有问题吗? 可能是最具挑战性的 肯定是编码的问题。 观众:那么类似于清单 在头前面的例子。 DAVID J. MALAN:没错,没错。 只是不同的名称 一个全局变量。 世界各地的什么? ROB BOWDEN:确定。 因此,这是一个在那里你 不得不写一段。 有些人撰写的论文 对于这个问题。 但是,你只需要使用这六个条款 描述发生的事情时, 你尝试联系facebook.com。 所以我就谈谈整个过程 使用所有这些条款。 所以在我们的浏览器,我们输入facebook.com 然后按Enter键。 因此,我们的浏览器将构建一个 HTTP请求,它将会发送 通过一些过程的Facebook Facebook来与回应我们 它的HTML页面。 那么,什么是过程 该HTTP请求 实得到Facebook? 因此,首先我们需要翻译 Facebook.com。 因此,只要给定的名称Facebook.com, 其中实际执行HTTP请求 需要去? 因此,我们需要翻译Facebook.com 到一个IP地址,它唯一 标识实际上是什么,我们的机器 要将此请求发送到。 你的笔记本电脑都有一个IP地址。 任何连接到互联网 有一个IP地址。 所以DNS,域名系统,也就是 这是怎么回事处理翻译 从facebook.com到一个IP地址, 你其实是要联系。 所以我们联系了DNS服务器和 比如说,什么是facebook.com? 它说,哦,它的IP地址190.212 什么,什么,什么的。 好的。 现在,我知道什么机器 我想联系。 这样的话你把你的HTTP请求 在该机器。 那么它是怎样得到那台机器? 好了,该请求会从 路由器到路由器的反弹。 请记住这个例子在课堂上,在那里 我们居然看到了路由的 包了,当我们试图 进行通信。 我们看到它跳过去的大西洋 海洋在一个点或什么的。 所以最后期限端口。 所以这是现在你的电脑上。 你可以有多个当前的事情 与互联网通信。 这样我就可以运行,例如,Skype公司。 我可能有一个Web浏览器中打开。 我可能有一些 torrenting文件。 因此,所有这些事情都 与通信 互联网以某种方式。 所以,当您的计算机接收的一些数据 从互联网上,是怎么做的 知道什么是真正的应用 想要的数据? 它如何知道是否这个特殊的 数据,是为 torrenting应用程序,而不是 到web浏览器? 因此,这是在该端口的目的 所有这些应用都 要求您的计算机上的端口。 所以,你的网页浏览器说,哎, 我正在侦听端口1000。 和你的torrenting程序是在说, 我正在侦听端口3000。 和Skype说,我使用的是端口4000。 所以,当你得到一些数据属于 一个这些应用程序,数据 标有哪个端口它实际上 沿途应该被发送。 所以这个说,哦,我是属于 到端口1000。 我知道,那么我就需要这个转发 跟着我的网页浏览器。 因此,它之所以与此有关 是Web服务器往往 侦听端口80。 所以,当我联系Facebook.com,我 配有人机通信。 但我需要说的是哪个端口 机器我要与之通信。 和Web服务器往往是 侦听端口80。 如果他们想要的,他们可以将其设置 高达所以它会列出为端口7000。 然后在Web浏览器,我可以 手动输入Facebook.com:7000 将请求发送到端口7000 Facebook的Web服务器。 DAVID J. MALAN:而且在这种情况下,即使 虽然我们没有要求的人 提到这一点,在这种情况下,什么端口 会的要求,其实去? 请再试一次。 没错。 不找了,但一个微妙 那有没有最后一次。 ROB BOWDEN:所以HTTPS的,因为它是 听专门为 加密的,它在端口4430。 观众:和电子邮件是25吧? DAVID J.马兰:出站 电子邮件,25,是的。 ROB BOWDEN:我什至不知道大多数的 的 - 所有的较低的往往是 对于保留的东西。 我觉得一切都在 1024被保留。 观众:你为什么说 3是打错电话了? ROB BOWDEN:因为在一个IP地址, 有四组数字。 并且他们是从0到255。 所以192.168.2.1是一种常见的 本地网络的IP地址。 请注意,所有这些都小于255。 所以,当我开始用300,这 不可能有 一直是数字之一。 DAVID J.马兰:但是,这傻夹 从 - 这是CSI,在那里他们有一个 数字太大 为IP地址。 ROB BOWDEN:本有问题吗? 下一个,在如此彻底的改变 的话题,但是我们有这个PHP数组的 房子在四。 我们有一个无序列表。 我们想打印出每个列表项 只是含有的房子名字。 所以我们有一个foreach循环。 所以请记住,语法的foreach 数组作为项目的数组中。 因此,通过循环的每次迭代, 房子是要采取的一个 该数组内的值。 在第一次迭代中,房子 将卡博特众议院。 在第二次迭代,房子会 是快递楼等。 因此,对于每一个为四家,我们是 只是要打印 - 你也可以呼应 - 列表项,然后房子的名字 然后关闭列表项。 花括号是可选的在这里。 然后我们又在这个问题说 本身,记得关闭 无序列表标记。 因此,我们需要退出PHP模式 为了做到这一点。 或者,我们也可以呼应 关闭无序列表标记。 DAVID J.马兰:精也将在这里 一直使用旧的学校 循环使用$ I = 0,并使用计数 计算出射线的长度。 完全没问题,只要 有点wordier。 观众:所以,如果你要 [听不清],你会怎么做 - 我忘记了环[听不清]是什么。 你会$四架我? DAVID J.马兰:没错。 是的,没错。 ROB BOWDEN:还有别的吗? DAVID J.马兰:好的。 权衡。 因此,有答案的串 可以为每个这些。 我们真的只是寻找 对于一个颠倒和令人信服的东西 不利的一面。 和16号要求,验证用户的 输入客户端,使用JavaScript, 而不是服务器端,如使用PHP。 那么什么是一个颠倒 做客户端? 好了,我们提出的事情之一是 你减少等待时间,因为你 不必费心接触 服务器,这可能需要几分钟 毫秒甚至几秒钟 通过避免和公正 验证用户的输入客户端通过 触发的提交和处理程序 只是检查,没有他们的类型 在对名称的东西? 难道他们输入一些内容 在电子邮件地址? 难道他们从中选择一个宿舍 下拉菜单? 你可以给他们即时的反馈 使用千兆赫兹的电脑 或不管他们有那 其实自己的办公桌上。 所以它只是一个更好的用户 通常会遇到。 但在做客户端的缺点 验证,如果你这样做也没有 做服务器端验证是 大多数人现身CS50都知道 你可以直接发送你想要的任何数据 到服务器任何数目的方式。 坦率地说,在几乎所有的浏览器,你可以 单击各地在设置和公正 关闭JavaScript,这会, 因此,禁止任何形式的 验证。 但您可能还记得,即使我 没有使用类的一些神秘的东西 telnet和实际假装 是一个浏览器通过发送GET 请求到服务器。 而这当然不是 使用任何JavaScript。 这只是我输入命令 在一个键盘。 所以真的,足够在任何程序员 舒适与Web和HTTP 可以发送任何数据,他或她想要的 到未经验证的服务器。 如果你的服务器是不是也检查, 没有他们给我一个名字,是 这实际上是一个有效的电子邮件地址,做 他们选择一个宿舍,你可能最终 向上插入伪造的或只是空白数据 进入你的数据库,这可能 不会是一件好事,如果 你假设它在那里。 所以这是一个恼人的现实。 但在一般情况下,客户端 验证是很大的。 但它意味着两倍的工​​作。 虽然确实存在各 库的JavaScript库 例如,使这么多, 更不用说头痛。 并且可以重复使用一些代码 服务器端,客户端。 但一定要明白,这是典型的 额外的工作。 是啊。 观众:所以,如果我们只是 说不太安全 - DAVID J.马兰:[笑] 唉。 那些总是更难 那些作出裁决。 ROB BOWDEN:那倒 已被接受。 DAVID J.马兰:什么? ROB BOWDEN:我创造了这个问题。 这将被接受。 DAVID J.马兰:是啊。 观众:酷。 ROB BOWDEN:但我们不接受 第1 - 好了,我们要找的是 像你不必 与服务器通信。 我们不接受只是速度更快。 观众:怎么样 不重新加载页面? ROB BOWDEN:是的。 这是一个公认的答案。 DAVID J.马兰:凡是我们认为 它比不太可能更容易 你知道你是什么 说,这是一个艰难的 有时行画。 使用链接列表,而不是 阵列保持的 排序的整数列表。 所以,一个颠倒,我们经常引用与链接 这促使他们的整个列表 引入是你的活力。 他们可以成长。 他们可以收缩。 所以,你不必赴汤蹈火 实际创建更多的内存 与阵列。 或者你也不必只 说,对不起,用户。 阵列被充满。 列表中的那么强劲增长。 虽然链表的缺点? 观众:它是线性的。 搜索关于链表是线性的 而不是你登录。 DAVID J.马兰:没错。 上搜索一个链表是线性的, 即使它的排序,因为你可以 只有遵循这些面包屑,这些 指针,从列表的开始 到结束。 你不能利用随机访问和, 因而,二进制搜索,即使它是 排序,您可以 做的一个数组。 还有还有另一个代价。 是啊。 观众:内存效率低下? DAVID J.马兰:是啊。 好吧,我不一定会 说效率低下。 但它确实花费你更多的内存, 因为你需要32位,每 节点为额外的指针,在 至少一个单向链表。 现在,如果你只是存储整数, 您要添加的指针,这是 种不平凡的实际。 这是加倍的内存量。 但在现实中,如果你存储一个 可能有结构的链表 8字节,16字节,甚至更 重要的是,也许是少 的边际成本。 但它的成本仍然。 因此,无论是那些已经会 被罚款的缺点。 18。 使用PHP,而非C + +写 一个命令行程序。 所以在这里,它往往更快的使用 如PHP或Ruby或Python语言。 你只是迅速打开 一个文本编辑器。 你有更多的功能 提供给您。 PHP有功能的厨房水槽, 而在C中,你 有非常,非常小。 事实上,家伙知道硬盘的方式 那你没有哈希表。 你不用链表。 如果你想这些,你必须 实现它们自己。 PHP的这么一颠倒或任何真正 解释型语言是快速性 使用它可以编写代码。 但不利的一面,我们看到这个的时候我 迅速刮起了miss​​peller 使用PHP在讲座的实施,是 在使用一种解释语言 通常比较慢。 而且我们看到,明确与 0.3秒的时间增加至3 秒,因为该解释, 实际发生的情况。 另一个上攻是你 不必编译。 因此,它也加快了发展 顺便说一句,因为你没有 两个步骤来运行的程序。 你只有一个。 所以这是相当 引人注目的为好。 使用SQL数据库,而不是 CSV文件来存储数据。 因此SQL数据库用于pset7。 CSV文件你没有使用太多。 但是你用它间接pset7为 以及通过交谈雅虎财经。 但CSV就像一个Excel文件,但 超级简单,这里的列 只是划出由内而外逗号 否则一个文本文件中。 并使用SQL数据库 多了几分吸引力。 这是一个颠倒的,因为你得到的东西 像选择并插入和删除。 你会得到,据推测,该索引 MySQL和其他数据库一样, 甲骨文在内存中建立你的,这 意味着你的选择可能是不 将是线性从上到下。 它实际上将是什么 像二进制搜索什么 类似的精神。 所以他们普遍较快。 但缺点是, 它只是更多的工作。 这是更多的努力。 你必须了解数据库。 你必须设置它。 你需要一个服务器来运行 该数据库。 你需要了解 如何配置它。 所以这些都只是这些 各种权衡。 而一个CSV文件,你可以 用gedit创建它。 和你去好。 有没有超出复杂性。 用trie树代替了哈希表 有独立的链接来存储 话让人想起字典 的pset5。 所以试图上攻,在理论上 至少,是什么呢? 固定的时间,至少如果你是 散列上每个单独的 字母词,像你 可能对pset5。 这可能是五哈希,六 哈希值,如果有五六个 字母的单词。 并就不错了。 如果有一个上限如何 长你的话可能是,这是 的确渐近常数时间。 而具有独立的哈希表 链,问题出在那里与 样的数据结构是 你的算法的性能通常 取决于事物的数量 已经在该数据结构中。 而这肯定与案件 链,从而使更多的东西你把 到哈希表中,这些长 链去,这意味着在最坏 情况下,你可能会寻找的东西 是所有的方式在一个的端 那些枷锁,有效的 转予弄成线性的。 现在,在实践中,它可能完全 这样的话,与一个哈希表 链是比相应的快 特里实施。 但是,这是由于各种原因,其中 这是尝试使用了一大堆 内存可以,其实,慢的东西 下来,因为你没有得到很好的 一种叫做缓存的好处, 那里的东西都是靠在一起 在存储器中可被访问。 往往更快。 有时你能想出 一个真正好的哈希函数。 即使你有浪费一点 内存,则可能确实,能够 找东西快速而且效果不 那样糟糕线性。 因此,在短,存在不一定是 与上述任何一种或两种的 我们正在寻找具体的事情。 真的什么说服力 作为上行和下行 一般吸引了我们的眼球。 ROB BOWDEN:所以对于上升空间,我们做 不接受它自己的“更快”。您 不得不说一些事情。 即使你更快地从理论上说, 我们知道那种你明白 它的0 1。 及哈希表,从理论上讲, 不为0的1。 提及在运行什么 一般把你的分。 但“快”,大部分的解决方案上 大板,分别是尝试 客观上比慢的解决方案 这是哈希表。 所以更快本身并 是不是真的。 DAVID J.马兰:DOM德DOM DOM。 我可能是唯一一个实现 这是怎么说的应该 发音,对不对? ROB BOWDEN:我居然不知道。 DAVID J.马兰:这让 感觉在我的头上。 ROB BOWDEN:我做这一个。 确定。 因此,这是一个在那里你不得不动用 类似于你的图可能 看到过去的考试。 所以,就让我们看看这个。 所以从HTML节点,我们有两个 儿童的头部和主体。 因此,我们分支 - 头部和身体。 头部有一个标题标签。 因此,我们有一个标题。 现在,有一件事很多人 忘了的是,这些文本节点 此树中的元素。 所以在这里我们碰巧吸引他们为椭圆形 从这些区分它们 类型的节点。 但公告同时在这里我们有顶, 中部和底部最终会被 文本节点。 所以,忘记那些有点 一个常见的​​错误。 人体有三个孩子 - 这三个div的。 所以格,格,格,然后在文本 这些div的子节点。 这几乎是它 该问题。 DAVID J.马兰:而且这是值得注意的, 尽管我们不会对这些纠缠 在我们花费的时间细节 JavaScript中,该命令呢, 事实上,无论在技术上。 所以,如果头自带的身体之前,在 HTML,那么它应该出现在 在实际的DOM离开身体。 他是,在一般情况下,刚刚仅供参考, 一些所谓的文档顺序,其中 这非常重要。 如果你正在实施一个解析器, 一个程序,在建筑读取HTML 在内存中的树,说实话, 这就是直觉可能是你 无论如何做 - 从上到下, 左到右。 ROB BOWDEN:该问题? 我应该做的下一个? DAVID J.马兰:当然可以。 ROB BOWDEN:确定。 因此,这是缓冲区溢出 攻击的问题。 最主要的是要在这里认识的是, 好了,怎么可能一个对手绝招 这个程序到执行 任意代码? 所以argv1,第一个命令行 参数传递给这个程序,那可以是 任意长。 但在这里,我们用memcpy复制 argv1,在这里是酒吧。 我们把它当作参数。 所以它采取的名字吧。 因此,我们memcpying吧 这个缓冲液C。 我们有多少字节复制? 然而,良好的字节酒吧恰好 可以使用,这样的说法的长度。 但c是只有12个字节宽。 因此,如果我们输入命令行参数 这比12个字节长,我们 将这个溢出 特定的缓冲区。 现在,怎么可能对手的绝招 程序执行任意代码? 所以请记住,在这里 主要是调用foo。 所以当时主要调用foo。 让我们得出这样的。 因此,我们有我们的堆栈。 与主有一个堆栈帧 在底部。 在某些时候,主要调用foo。 好了,马上,主要调用foo。 所以富都有自己的堆栈帧。 现在,在某些时候,富 将要返回。 又走了foo返回了,我们需要知道在 哪些代码主要我们的内线 是为了知道在哪里 我们应该恢复在主。 我们可以从整个调用foo 一堆不同的地方。 我们怎么知道从哪里回来? 好了,我们需要存储在某个地方。 所以,正确的地方在这里,我们存储 在这里我们还是要回到曾经 富回报。 这是返回地址。 因此,如何对手可能利用 的是这样的事实,即 这个缓冲区C存放,让我们 说,就在这里为c。 因此,我们已经有了12个字节对​​于C。 这是C。 这是Foo的堆栈环。 因此,如果恶意用户输入更多 超过12字节或者输入命令 行参数,这比12再 字符,那么我们要 溢出这个缓冲区。 我们可以继续下去。 在某些时候,我们走多远 够了,我们开始 这个覆盖返回地址。 所以一旦我们覆盖返回地址, 这意味着,当富 返回时,我们返回的地方 恶意用户告诉它 任何值它进入,以任何 字符的用户输入。 所以,如果恶意用户正在 特别聪明,他能有这样的 返回到某处printDef 功能或某处的malloc 功能,只要在任何地方随心所欲。 但更巧的是什么,如果他有 用户返回到这里。 然后你开始执行 由于这些代码行。 所以在这一点上,用户可以输入 任何他想要进入这一地区。 他有完全的控制 在你的计划。 该问题? 因此,接下来的问题是完全的 富的以这样的方式重新实现 它不再是脆弱的。 因此,有几种方法 你可以这样做。 我们还有C只 是长度为12。 你可以改变这 作为解决方案的一部分。 我们还增加了一个检查,以 确保酒吧是不是null。 虽然你并不需要 对于全额贷款。 因此,我们先检查 酒吧的字符串的长度。 如果是大于12,则 实际上不做副本。 所以这就是修复它的方法之一。 固定它的另一种方式是代替 有C只是长度为12,拥有它 是长度函数strlen(巴)。 固定它的另一种方式是 实际上只是返回。 所以,如果你刚刚摆脱了所有的 这一点,如果你刚刚删除了所有 行代码,你会得到 全额贷款,因为该功能 实际上并没有完成任何事情。 它的复制命令行 参数为一些阵列 它的栈帧。 然后事情就是返回。 此外,无论它成功的走了。 所以回报也足够 获得全部学分的方式。 DAVID J.马兰:不太精神 这个问题,但每可接受 规格书号仍然。 ROB BOWDEN:在任何的问题? 有一件事,你至少 需要已编译代码。 因此,即使在技术上你是不是 脆弱的,如果您的代码不 编译,我们不接受。 没有问题? 确定。 DAVID J.马兰:你想 说这个称号? ROB BOWDEN:号 DAVID J.马兰:所以在这一块,这 无论是好消息还是坏消息。 这是字面上相同的问题 作为第一次测验。 而且它几乎是相同的 问题是PSET1。 但它被刻意简化为 一个更简单的金字塔,一个可 解决了用微 简单的迭代。 真的,我们都拿到在 这里是没有那么多的逻辑, 大概是因为,通过这一点,你 比你更舒适 在一个用for循环或循环为什么一周, 但真正捉弄除了那 你有点舒服的 概念,PHP是不只是什么 编程。 它实际上可以被用来作为一种语言 写命令行程序。 事实上,这正是我们试图 提请你注意。 这是一个PHP命令行程序。 因此,这里的C代码,而正确的 在C中,不正确的PHP。 但是代码确实是相同的。 如果你比较对测验的解决方案 0反对测验1,你会发现, 它几乎是相同的,除了 一些美元符号和对 缺少数据类型。 特别是,如果我们看看这里, 你会看到,我们遍历,在这 情况下,从1到7。 我们可以做它0指数。 但有时候,我认为这只是 精神上更容易思考的东西 从1到7。 如果你想有一个街区,然后两个 块,然后三,然后 点,点,点7。 我们已经j为初始化为1 然后指望达我。 而这里的一切 否则相同。 但值得注意的是 一对夫妇的事情。 我们给你这两条线,这首 1,goofily命名为家当 对于尖锐的爆炸。 而这只是指定的路径中, 文件夹,在其中一个程序可以 发现要使用 解释这个文件。 和随后的线路之后, 当然,是指进入PHP模式。 和线在最底层 表示退出PHP模式。 而这个工程,在一般情况下,与 解释型语言。 这有点恼人,如果你写了一个 计划在一个名为foo.php文件。 然后你的用户要的只是 记住,好了,运行这个程序,我 必须输入“php空间foo.php。”样 恼人的,如果没有别的。 同时也表明你的程序 是用PHP编写的,这是不是所有的 该照射的用户。 这样你就可以完全消除。PHP 从讲座召回。 而你实际上可以做。/ foo的,如果 你通过使已经chmodded它 可执行文件。 因此存取权限chmod a + X富会做的。 如果你也在这里添加家当。 不过说真的,这个问题是越来越在 打印出这样的事情。 没有HTML,没有C代码肯定, 只是一些PHP。 所以米洛然后在问题25返回。 而在25日,你被赋予以下 框架代码,这是一个 很简单的网页。 而多汁部分的HTML明智下跌 这里,我们有身体的内部 具有输入唯一ID的形式 其内部是两个输入,一个 同的名称,1的想法 与按钮的想法。 第一个是文本类型的 类型的第二提交。 因此,我们给了你,其实,更 比你需要的,只是这样的成分 你们有选择与 来解决这个问题。 你并不需要严格 所有这些ID的。 但它可以让你解决 它以不同的方式。 并在顶部,注意 的目的是为了触发 像这样的窗口 - 您好,米洛! - 使用弹出的浏览器 超级简单,如果 不丑,报警功能。 所以,最终,这归结 概念以某种方式监听 表单的客户端提交的材料 ,而不是服务器端的,不知何故 要答复意见书 抓住用户键入的值 在Name字段,然后 在警告的正文中显示它。 所以,你可以做到这一点的方法之一是用 jQuery的,看起来有点 语法傻了眼在第一。 为此,您可以用纯DOM代码 - 通过ID document.getelement。 但是,让我们来看看这个版本。 我有几个重要的 行第一。 这么一句,我们这行,这是 相同的你可能已经看到 在,我相信,form2.html 从类中第9周。 这只是说,执行 下面的代码时, 该文件已准备就绪。 这是重要的,因为只有 HTML页面顶部读 底,左到右。 因此,如果你尝试做 东西在这儿代码在一定的DOM 元素,一些HTML标签,这就是下降 在这里,你这样做为时过早, 因为这并没有什 被读入内存。 所以说这样的document.ready 行,我们在说, 这里的一些代码,浏览器。 但不执行此操作,直到整个 文档准备好,即在DOM 树存在于内存中。 这一个是多一点 直截了当,如果一个语法 有点不同,这里我说的,抢 在HTML元素,其独特的 标识符输入。 这就是散列标签 表示,唯一ID。 然后我打电话。提交。 因此,这里提出的是一个函数,否则 已知作为一种方法,这就是 在左侧的对象的内 一边有,我没有强调。 所以,如果你想输入作为一个对象 在内存中 - 实际上它是。 这是在一个树中的节点 - 。提交的手段时,这种形式与 这个ID被提交后,执行 下面的代码。 我不在乎什么的名字 功能是我执行。 所以在这里我使用的,和以前一样,有什么 被称为lambda函数或 匿名函数。 它不是在所有智力 有趣以外它没有名字, 这是好的,如果你只 永远要调用它一次。 里边有我真正处理 提交表单。 我首先声明一个变量 所谓的价值。 然后这个是什么效果 这里突出部分吗? 这是什么做的一 高层给我吗? 观众:它得到的值的 用户在下面的HTML没有。 它得到的ID,然后 发现它的价值。 DAVID J.马兰:没错。 它抓住节点,其独特的 标识符名称。 它得到了其中的价值,这 是,据推测,什么样的用户 键入他或她自己。 然后将其存储在该 变量称为价值。 顺便说一句,你可以有也 这样做有点不同。 通过做一些完全可以接受 谎言的VaR值,得到 的document.getElementById。 这就是为什么它是一个小 乏味,不使用jQuery的。 “名”。值。 所以完全可以接受的。 不同的方法来做到这一点。 jQuery的刚 往往是多了几分简洁和 肯定更受欢迎 间的程序员。 现在,我正在做一个有点理智的 检查一下,因为在这个问题 声明中我们明确地说,如果 用户尚未键入他或她的 名,不显示一个警报。 但你可以检查,通过刚 检查一个空字符串 报价引文结束,如果有 什么居然还有。 但如果它不等于报价引文结束, 我想打电话报警。 这里最有趣的部分是, 我们使用加运算符, 在JavaScript中做什么? 串连。 所以它就像PHPS点运算符。 同样的想法,稍有不同的语法。 而我只是在创建字符串 你看到了屏幕截图 - 您好,某某。 然后最后的细节是这样的。 为什么我返回false内 这个匿名函数? 观众:有没有价值。 你把它的形式。 它只是说,如果值不 等于空白,然后再去做。 有在提交的一项空白。 DAVID J.马兰:确定。 小心,虽然。 有没有一个人在这里。 并且返回false是外 的if条件。 因此,这突出显示的行,返回false, 执行不管是什么时候 表单被提交。 什么是回国这里面的假 事件处理程序,因为它叫, 在有关活动 被提交? 观众:因为它 只发生一次。 DAVID J.马兰:只发生一次。 不完全是。 是吗? 观众:它防止表单 提交到默认的行为, 这样就会使页面重载。 DAVID J.马兰:没错。 所以我对超载提交一词在这里, 因为我说的,形式是 提交。 但如你所说,它实际上不是 在提交的真实的HTTP方法被。 当您点击提交,因为,我们的 onsubmit处理,我们正在拦截 该表单提交可以这么说。 我们然后做我们的事 与JavaScript代码。 但我故意返回false, 因为我不希望发生的一 一瞬间之后,是为整个表格 本身提交到网上 服务器与键值对通过改变 是类似的URL Q =猫,或任何我们所做的, 例如,在课堂上。 我不希望这样的事情发生,因为 有没有这个问题的服务器监听 表单提交。 这是纯粹的JavaScript代码完成。 这就是为什么我什至没有一个 action属性的窗体上,因为我 没有为这个打算 曾经去到服务器。 因此,它被提交。 但是我们截取该表单 提交并防止默认 的行为,这是实际 走一路到服务器。 观众:所以保持它的客户端。 DAVID J.马兰:保持 它的客户端。 完全正确。 接下来是我的哦MySQL的。 ROB BOWDEN:确定。 所以这第一个问题通常是 粗糙的人。 虽然后来者去更好。 所以,你必须选择正确的数据 类型这两个列。 和这两个有一定 关于他们的事情, 做出选择很难。 所以整数是不是一个有效的 键入数字。 究其原因是一个12位帐号 数,一个int是不是足够大的 存储总位数。 因此,一个有效的选择将是一个很大的 如果你碰巧知道INT。 另一种选择可能是 长度12的字符字段。 因此,无论是那些会工作。 诠释不会。 现在,平衡,回想着pset7。 所以我们专门用于十进制 储存的股份或价值 - DAVID J.马兰:现金。 ROB BOWDEN:现金。 我们使用十进位存储量 现金用户目前拥有。 所以我们这样做的原因是 因为,记住,浮在水上。 有没有在精度浮点。 它不能精确地存储的现金 像我们想要的值在这里。 所以,十进制是能够精确地存储 东西,说,小数点后两位。 这就是为什么平衡,我们希望它 为十进制数,而不是浮动。 DAVID J.马兰:此外,他也一样,虽然 它可能在其他被聪明 上下文去思考,也许这 是一个int的机会。 我就继续跟踪 事情便士。 因为我们明确地显示了默认 的是100.00,值 意味着它可能仅仅是一个int。 而另一个微妙过与数 是,这并不意味着 是一个棘手的问题。 但记得,在MySQL的一个int, 像在C中,至少在 家电,是32位的。 而且即使我们不指望你来 确切地知道有多少位数的 手段,千万记得最多 你可以代表可能 一个32位数字大致是怎样的? 什么号码我们老是说什么? 2至32,这是大约? 你不必知道准确。 但大致是在生活中有所帮助。 这是约4十亿。 因此,我们说了几次。 我知道我已经说过,几十倍。 它是约4十亿。 这就是一个很好的规则 拇指就知道了。 如果你有8位,256 是一个神奇的数字。 如果你有32位,4 十亿给予或采取。 所以,如果你只写下跌4十亿, 你会看到它的位数少于 12,表示这显然不 够表现来捕获 12位帐号。 ROB BOWDEN:确定。 所以其他的人去比较好。 因此,假设银行 规定了每月20元 维修收费标准上的所有帐户。 用什么SQL查询可以在银行 从每一个计数中扣除20元,就算 它会导致一些负面的余额? 因此,基本上,有四个 查询的主要类型 - 插入,选择,更新和删除。 那么,我们认为我们 要在这里使用? 更新。 因此,让我们一起来看看。 所以在这里,我们要更新。 我们要更新什么表帐户? 所以更新账户。 然后语法说什么 帐户被我们更新? 好了,我们设置的平衡等于 余额减去20的电流值。 因此,这将更新所有行 帐户,减去 20美元的余额。 DAVID J.马兰:这里一个常见的​​错误, 即使我们有时会原谅它, 是实际上这里有PHP代码 调用查询功能,或将 周围的一切引号的 并不需要在那里。 ROB BOWDEN:请记住,MySQL是 从PHP一个独立的语言。 我们碰巧在PHP中要编写的MySQL。 和PHP,然后送它 在MySQL服务器。 但你不为了需要使用PHP 与MySQL服务器进行通信。 DAVID J.马兰:没错。 所以没有带美元符号变量 应于该上下文。 它可以做所有的数学 在数据库本身。 ROB BOWDEN:确定。 所以,下一个。 这是下一个? 是啊。 所以用什么SQL查询可以在银行 其检索的帐号 最丰富的客户,那些与 余额大于1,000? 所以这四个主要类型 我们要在这里想要什么? 选择。 所以,我们要选择。 我们究竟要选择? 我们想要怎样栏选择? 我们会特别希望 选择号码。 但是,如果你说的明星,我们 也接受这一点。 那么从​​什么表中选择号码? 帐户。 然后条件,我们想要的吗? 凡结余超过1000人。 我们也接受更大 小于或等于。 最后一个。 用什么SQL查询可以在银行 接近,即删除每一个帐户 有$ 0的平衡? 因此,这四个是我们 会想使用? 删除。 所以,语法是什么? 从什么表中删除? 帐户。 然后在其上的条件 我们想删除 - 其中平衡等于零。 因此,从账户中删除所有行 当余额为零。 对上述任何一个问题? 要排队? DAVID J.马兰:队列指南。 所以在这一块,我们给你一个有点 熟悉的结构,我们探索出了 在课堂位旁边的结构, 这是一个数据 结构中的精神有关。 虽然与队列的区别是 我们必须以某种方式记得是谁 是在队列的前面,在大 一部分这样我们就可以赚更多 有效地使用存储器,至少 如果我们用一个数组。 因为召回,如果我们有一个数组,如果, 举例来说,这是前部 队列中,如果我进入队列这里, 然后有人得到一致 我,在我身后,在我身后,后面 一个人走出行,你 可以,因为我们看到了一些我们人类的 在课堂的志愿者,让每个人都 转向这种方式。 但在一般情况下,大家有做 自己是不是时间的最佳利用 在程序中,因为这意味着你的 算法在运行什么 渐近运行时间? 它是线性的。 我觉得这是种愚蠢的。 如果下一人行是下一个 人谁的应该进入 商店,他们不都 一起移动。 只是让那人被人拔光了 在时机成熟时,例如。 这样既可以节省一点时间在那里。 所以要做到这一点,那就是说 该队列的头部或 该队列的前面是要 逐步移动越陷越深 到阵列中,并最终可能 实际上环绕,如果我们使用的是 数组来存储人 在此队列中。 所以你几乎可以想到的 数组作为循环数据 结构在这个意义上。 所以,你无论如何都必须跟踪的 它的大小或它的真正结束 然后在那里它的开始是。 因此,我们建议您声明 一个这样的队列,呼叫 它Q,只是一个字母。 然后,我们建议把前面是 初始化为零,并且大小 初始化为零。 所以现在,没有什么 里面的那个队列。 我们要求你完成 在下面执行的入队 这样一种方式,该函数将n到 q的末尾,然后返回true。 但是,如果q是满的或负的,本 函数应该改为返回false。 我们给你一对夫妇 假设。 但他们并不是真正的功能 相关的,刚才那布尔存在, 因为,从技术上讲,布尔不 存在于C,除非你有一个 某些头文件。 所以这只是确保有 没有了这是一招 问题之类的话。 所以排队,我们的样本中提出的 解决方案来实现,如下所示。 一,我们首先检查方便, 低悬的果实。 如果队列已满或数 你试图插入小于 大于零,这是我们在所述 规范的问题应 不会被允许的,因为我们只想要 非负值,那么你应该 只是立即返回false。 因此,一些相对容易 错误检查。 如果你虽然想补充的是,实际 号,你不得不做一点 想在这里。 而这正是它是一个有点讨厌 弱智,因为你必须 弄清楚如何处理环绕。 但这个想法的萌芽在这里,是的 我们感兴趣的是,环绕 往往意味着模运算和 mod运算符,百分比方面, 在那里你可以从一个较大的值 回零,然后一个及两个 3,然后绕回至零, 1和2和3等 一遍又一遍。 因此,我们建议这样做的方法是 那不是我们不想索引到 阵列被叫号码所在 我们的整数说谎。 但到那里,我们首先想要做的 无论队列的大小是但 然后添加到无论 在列表的前面是。 和其效果是把我们 在队列中合适的位置和 不要以为在线路的第一人 是在开始时,他或 她绝对可以,如果我们 也被转移大家。 但我们只是创建工作 为了我们自己,如果我们把 该特定路径。 所以我们可以保持它相对简单。 我们必须记住,我们只是 添加一个int到队列中。 然后我们就返回true。 同时,在出队,我们问 你要做到以下几点。 实现它以这样一种方式,它 出队,那就是移除并返回, 整型在队列的前面。 要取出整数,它满足 忘记它。 你并不需要覆盖其位。 因此,它实际上仍然存在。 就像一个硬盘上的数据, 我们只是忽略了一个事实 它现在在那里。 而如果q是空的,我们应该 而不是返回负1。 所以这种感觉随心所欲。 为什么返回负1 而不是假的? 是啊。 观众:Q被存储 正值。 既然你只存储正值 在第q,负是一个错误。 DAVID J. MALAN:好,真的。 所以,因为我们只存储正 值或者为零,那么它的罚款 返回一个负的值作为定点 值,特殊符号。 但你重写历史上, 因为我们是唯一的原因 返回非负值 是因为我们要 有一个标记值。 所以,更确切地说,为什么不干脆 在错误的情况下返回假的? 是啊。 观众:你已经失败 返回一个整数。 DAVID J.马兰:没错。 这就是其中C得到 漂亮的制约。 如果你说你要去 返回一个int,你有 返回一个int。 你不能花哨,并开始返回 一个bool或浮或 字符串或类似的东西。 现在,与此同时,JavaScript和PHP和 其他一些语言可以,其实, 你有不同的返回 类型的值。 而这实际上是有用的,其中 你可以返回正整数,零, 负整数,或虚假或无效 甚至表示错误。 但是,我们没有这方面的 多功能性C. 因此,与出队,我们什么 建议做的是 - ROB BOWDEN:你可以返回false。 这只是虚假的散列 定义虚假为零。 所以,如果你返回false, 你返回零。 零是一个有效的事情在我们的队列中, 而负1是不是如果 假正好是负1。 但你应该甚至不 需要知道。 DAVID J.马兰:这是 为什么我没有说出来。 ROB BOWDEN:但它是不是真的 你不能返回false。 DAVID J.马兰:当然可以。 所以出队,发现我们接受 丧失作为它的参数。 那是因为我们不是 递东西英寸 我们只是要移除的元素 在队列的前面。 那么我们如何能够去这样做? 嗯,首先,让我们这样做 快速完整性检查。 如果队列大小为0,有 没有工作要做。 返回负1。 Done(完成)。 所以这是我的程序几行。 因此,只有四行依然存在。 所以在这里我决定递减 的大小。 并有效地递减的大小 也就是说,我忘了 东西就在那里。 但我也有更新的地方 数字的前面是。 因此,要做到这一点,我需要 做两件事情。 我首先需要记住的数量 是在该队列的前面, 因为我需要返回那个东西。 所以我不想忘记意外 关于它,然后覆盖它。 我只是要记得在一个int。 而现在,我要更新 q.front被q.front +1。 因此,如果这是在第一人称 行,现在,我想要做加1 指向下一个人行。 但是,我必须处理回绕。 如果能力是一个全局常量, 那将让我确定 当我点到最后的人 线,该模运算将带来 我回零的 前面的队列。 而且这里处理环绕。 然后我继续返回否。 现在,严格地说,我没有 必须声明ñ。 我没有抓住它并将其存储 是暂时的,因为该值是 仍然存在。 所以我只能做正确的算术 返回前负责人 队列。 但我只是觉得这是更清晰 实际上抢整数,把它 以n,然后返回 为清晰起见,但 不是严格必要的。 嘘。 他们都是发音的在我的脑海。 ROB BOWDEN:所以第一个问题 是二叉树的问题。 所以,第一个问题是,我们是 考虑到这些数字。 我们希望以某种方式将它们插入到 这些节点,例如,它是一个 有效的二叉搜索树。 所以,有一点要记住的 二叉搜索树是它的不 刚才说的事情向左移 少与事 右边是更大的。 它需要整个树 左边是更小,并且在整个树 向右更大。 所以,如果我把34在此间举行的顶部,然后 我把20在这里,所以这是有效的, 到目前为止,因为34在这里。 20是要在左边。 所以这是少。 但我不能再放入59在这里,因为 尽管图59是对20的右侧, 它仍然在34的左边。 因此,在这该约束时, 大概解决这个最简单的方法 问题是,只是排序 这些数字 - 所以20,34,36,52,59,106。 然后将这些 从左至右。 所以20放在这里。 34放在这里。 36放在这里。 52,59,106。 你也可以想通了与 有些堵塞和实现, 哦,等一下,我没有足够的数字 填补这个在在这里。 所以我需要reshift我什么 路线音符将是。 但是请注意,在最后三,如果 你读从左至右,它是在 递增的顺序。 所以,现在,我们想声明的是什么 结构将是为 在这棵树的节点。 所以,我们需要在一个二叉树是什么? 因此,我们有类型的值 整型,所以一些int值。 我不知道我们所谓的 它在溶液中 - INT N。 我们需要一个指向左边的孩子 和一个指向右边的孩子。 所以它会看起来像这样。 它会实际上看前 什么时候的双向链接 列表的东西,所以通知 - 我将不得不滚动所有 方法回落到问题11。 所以发现它看起来相同这一点, 除了我们只是碰巧调用这些 不同的名称。 我们还有一个整数 值和两个指针。 它是这样的态度对待这一点的 作为指针指向的下一件事 和以前的事情,我们正在处理 该指针指向一个左子 和右孩子。 确定。 所以这是我们的结构节点。 而现在,唯一的功能,我们需要 实施这是遍历,这 我们要越过树,印刷 从树上,以便这些值。 所以在这里看,我们要打印 出20,34,36,52,59,和106。 我们如何实现这一目标? 所以这是非常相似的。 如果你在过去的考试,看到了问题 你想打印出 整个树用逗号之间 一切,它实际上是连 比这更容易。 因此,这里的解决方案。 这是显著更容易 如果你递归地做到了。 我不知道是否有人试图 要反复做。 但首先,我们有我们的基本情况。 如果哪根是空? 然后,我们只是要回。 我们不希望打印出任何东西。 否则我们将遍历 递归下降。 打印整个左子树。 所以打印较少的一切 比我的当前值。 然后我要打印我自己。 然后,我要向下递归我 整个右子树,所以一切 比我的价值更大。 这是要打印 出一切为了。 这个实际上是怎样的问题 完成了吗? 观众:我有一个问题 在[听不清]。 ROB BOWDEN:逼近所以单程 任何递归的问题是只是觉得 它喜欢你不得不思考 所有的角落案件。 因此认为,我们要 打印此整个树。 所以我们要专注于 就是这个特殊的节点 - 36。 递归调用,我们假装 那些只是工作。 所以在这里,这个递归调用 遍历,我们甚至没有想到 关于它,只是遍历左 3,假设已经打印20 34我们。 然后当我们最终递归 遍历调用的 右,这将正确打印 52,59,106我们。 所以考虑到这可以打印20,34,和 另可打印52,59,108, 所有我们需要能够做的就是打印 我们自己在那中间。 因此,摆在我们面前打印出来的一切。 打印我们自己,所以当前节点的打印 36,定期的printf,然后 之后,我们打印了一切。 DAVID J.马兰:这是递归 变得非常漂亮。 这是信仰的这个惊人的飞跃,其中 你做的工作哪怕一丁点。 然后你让别人 别人做休息。 和别人 是,讽刺的是,你。 因此,对于严重的印象分,如果 你向上滚动的问题 - ROB BOWDEN:在的问题呢? DAVID J.马兰:上下了多大 这些数字,有没有人知道在哪里 这些数字从何而来? ROB BOWDEN:我简直不知道。 DAVID J.马兰:他们似乎 整个测验。 观众:他们是相同的号码? DAVID J.马兰:这些数字。 有点复活节彩蛋。 因此,对于那些你在网上看 回家,如果你可以通过电子邮件告诉我们 heads@CS50.net什么意义 这些反复出现的六个号码是 整个测验1,我们将沐浴你 以惊人的注意力在最后 演讲和一个压力球。 美观大方,含蓄。 ROB BOWDEN:最后还有什么问题 关于测验什么?