[音乐播放] 戴维·J·马兰:好吧。 这是CS50,这 是第四周的结束。 今天的话题之一 是数字取证的, 艺术恢复信息。 事实上,即使 你在中间 现在和平就在三 和突围,下周, 重点将放在 正是这个领域。 因此,最酷的工作之一,我曾经 不得不回来读研究生, 当我工作的地方 米德尔塞克斯县地区检察官 办公,做取证工作。 所以基本上,马萨诸塞州 国家警察,有时, 在案件工作时,会 带来的东西像硬盘驱动器 和软盘和 存储卡等。 他们会交给他们 我和我的导师, 我们的目标是要找到证据, 如果有可能对这些媒体。 现在,你可能已经看到一瞥 这个世界取证的 在媒体,电视和电影。 但这份工作,我曾和 敢说这世界上, 是不是很喜欢,你会看到它。 让我们来看看有哪些 你可能已经看到了。 [视频回放] - 确定。 现在,让我们好好看看你。 [音乐播放] -hold它。 跑了回来。 - 等待一分钟。 向右走。 -There。 冻结。 - 全屏幕。 - 确定。 冻结。 向上拧得过紧上,你愿意吗? -Vector在上 小伙的后轮。 -zoom在这里在这一点上。 - 带有合适的设备中, 图像可以放大和激化。 - 什么是什么? - 它是一个提升计划。 - 你能清楚了没有? - 我不知道。 让我们增强了。 - 增强部分A6。 í增强的细节,还有 - - 我认为有足够的提升。 它释放到我的屏幕。 - 我增强了她的眼睛反射。 - 让我们通过运行这个 视频增强。 -Edgar,可以加强这方面的? -hang上。 -I've一直在研究这种反映。 -There的人的反思。 - 反射。 -There是男人的脸的反映。 -The反思! -There的一个反映。 -zoom在上镜。 你可以看到一个反映。 - 你能在这里提升形象? - 你能提高吗? - 你能提高吗? - 可我们加强这方面的? - 你能提高吗? -hold在第二。 我会加强。 -zoom在门上。 -Times 10。 -zoom。 -Move英寸 - 更多。 -wait,停止。 -stop。 -pause它。 -rotate我们75度 绕垂直,请。 -stop。 回去的一部分 关于门了。 -Got图像增强器,可以位图? - 也许我们可以使用普拉迪普·辛格 方法看进窗户。 -The软件是最先进的。 -The特征值是关闭的。 - 随着权 algorithms--组合 - 他的拍摄照明 算法,以一个新的水平, 我可以用它们来 加强这方面的照片。 -lock上并放大的z轴。 - 增强。 增强。 - 增强。 -freeze和提高。 [完视频回放] 戴维·J·马兰:所以这些都是 所有的话,但他们并不 句子中的正确使用。 而事实上,在未来,任何时候 拜托,你听到有人说一句话, “提升,”轻笑只是一点点。 因为当你试图提升, 举例来说,这是发生了什么。 因此,这里是一个美丽的照片。 这是CS50自己Daven。 并假设我们想 聚焦于眨了一下眼睛, 或的反射 坏家伙,显然是 由安全摄像机拍摄的。 这是发生了什么时 你放大图像上 只有数量有限 与它相关联的位。 这是你会得到什么。 事实上,在Daven的眼睛 不过是4,也许6个像素 这构成什么 在若隐若现的存在。 所以,习题集四将最终有 你探索这个世界上,特别是 由一些性质 我们所说的文件I / O,其中 I / O是只是一种奇特的方式 说的输入和输出。 所以到目前为止,所有的相互作用 我们已经与一台电脑 已在很大程度上与 键盘和屏幕 但没有这么多的硬盘, 或保存文件的超越了那些你 自己写的。 你的计划迄今有 未建立和保存, 并更新自己的文件。 那么,什么是文件? 嗯,有点像JPEG格式。 这是一个形象,你可能 有或上传至Facebook, 或者看到在网络上的任何地方。 事实上,那张照片我们只是 Daven的看到的是JPEG格式。 而有趣 关于类似的JPEG文件 是,它们可以被识别, 典型地,通过比特某些型态。 换句话说,它是什么, 区分JPEG格式从一个GIF 从一个Word一个PING 从Excel文件中的文件? 好吧,这只是不同 比特模式。 而这些不同的图案 通常,在这些文件的开始处。 所以,当您的计算机打开一个Word DOC,或当计算机打开一个JPEG, 它的外观通常是在 第一数位的文件中。 如果它识别出模式, 它说,哦,这是一个形象。 让我展示给 用户为图形。 或者说,哦,这看起来像一个Word文档。 让我展示给用户的一篇文章。 因此,例如,JPEG文件, 事实证明,有 相当复杂 引擎盖下方。 但在大多数每前三字节 JPEG开始与这三个数字。 这样字节零个,一个,另外两个是,在 最每JPEG,255,则该数 216,然后是电话号码255。 ,你就可以什么 开始做下周 其实底下戳 文件的引擎盖像JPEG图片 而像位图文件,并查看 什么是一直存在的,只要 当你使用计算机已经。 但是,什么是不存在一般 写的十进制数是这样的。 计算机科学家不 往往在小数点说话。 他们没有真正的二进制说话。 通常,当我们想 来表达数字, 我们实际使用十六进制, 您可能还记得 ,比如说,从习题集 一,它挑战 你想想不同的系统。 当然,我们都是熟悉的 与小数,0至9。 我们谈到了二进制。 我们真的没有 用这么多在这里 对了,因为电脑会使用它。 但是,程序员会很 常常,但不总是, 用十六进制,这只是意味着 你有你的字母表16个字母, 相对于两个或两个10。 那么,你如何指望更高 比十六进制9? 你去0,1,2,3,4,5,6,7,8,9, A,B,C,D,E,F,只是约定。 但是,什么是关键的是,每个 这是一个象征。 有没有10。 有没有11本身,因为每 你的数字,就像在小数 而就像在二进制,应该只是 是单个字符,按照约定。 所以这则是我们的字母表 我们所掌握的十六进制数。 那么什么是JPEG格式的样子,如果你 要写出那些前三 不是字节为十进制但是, 例如,为十六进制? 而为什么是十六进制,甚至所有有用吗? 好了,快看一个例子。 所以,如果我写出来的比特 代表这些小数numbers-- 这可能是一个有点生疏 现在从几个星期前, 但左1和 合适的人是很容易。 255是最大的数字,我们 可以代表与八位。 这是所有的人。 因此,只有一个是轻度 有趣的是中间的一个。 善良的,如果你做出来的 数学,你会推断出,事实上, 一个是模式, 零代表216。 所以我们只订定 现在,这些都是正确的。 但为什么这很有趣? 好了,一个字节,当然,为8位。 而事实证明,如果你认为 一个字节的四位两个大块, 像这样。 让我补充一些空间。 所以在后。 我只是添加了一些空白 可视化的缘故这里。 我们怎么可能现在代表, 比方说,十六进制位各四, 每个四位组? 因此,例如,在左侧 现在,我们有1111的二进制文件。 什么是十进制的数字, 如果你做出来的数学? 你有那些地方,三三两两的地方, 四肢着地的地方,和八分的地方。 听众:15。 戴维·J·马兰:这是15。 因此,如果我们做的八加4 加二加一,得到15。 所以,我可以写下15以下 1111,但这里的整点 是十六进制,十进制没有。 所以不是写下15,1-5, 我要编写十六进制, 而如果你想回来,如果你有 零到f,什么15将是? 听众:F。 戴维·J·马兰:那么原来它的F。 而且你可以工作了这一点说, 还有,如果是10,然后单击OK,f为15。 所以事实上,我们可以重写 同一组数字为F F的。 然后,如果我们做数学的一点, 我们推断,该公司的D。 八是很容易的,因为我们 有一个在八分地方。 然后,我们有一对夫妇更多的F F的。 那么,人类倾向于做了约定 当他们用十六进制是他们只是 更简洁地写这一点, 摆脱大部分的空白。 和刚需超清晰 读者,这是十六进制, 中简单的约定 人类是你写零 x,它是没有意义的其他 比的视觉识别, 又来了一个十六进制数。 然后,你把两个数字,F f单位这种情况下,则d a,则F F。 所以长话短说, 十六进制刚刚趋于 是有用的,因为它的每一个 数字,零到F,完美线条 了四个比特的图案。 所以,如果你有两个十六进制数字, 零到F,一遍又一遍, ,让你完美 8位或1字节。 所以这就是为什么它往往 通常是有用的。 有没有智慧 内容真的除此之外, 比其实际效用等。 现在JPEG文件不是唯一 文件格式的图形。 您可能还记得,有 像这样的文件在世界上, 至少从几年前。 因此,这实际上是 安装在Windows XP中 对数以百万计的世界各地的个人电脑。 这是一个位图文件,BMP。 和位图文件,你会看到下一个 本周,只是意味着圆点的图案, 因为他们是所谓的像素, 一张地图上的位,真的。 那么,什么是有趣的,但是, 这个文件格式,BMP,是 该发动机罩的下面,它 已经不仅仅是三个字节 ,组成它的头,所以 可以说,最初的几个叮咬。 实际上,它看起来有点 乍看复杂。 你会看到这个在P组。 和得到的东西 特别是出了现在这个 不那么重要,因为只是事实 即在每一个位图的开始 文件以图形格式, 还有一大堆数字。 现在,微软, 这种格式的作家, 往往那些打电话 事情不是整数和字符 和花车,但文字和D 单词和长和字节。 所以,他们只是不同的数据类型。 他们是不同的名字 同样的事情。 但你会看到,在P设定四。 但是这仅仅是说,如果一个人的 双击某些文件.BMP他 或她的硬盘驱动器,并打开一个窗口 一个显示他或她的形象, 发生因为操作 系统想必注意到,不仅 .BMP文件扩展名 在文件名中, 而且事实上,有一些 公约比特模式 在开始的时候 位图文件。 但是,让我们现在专注于 这样一个复杂的文件, 而是对这样的事情。 这里假设gedit中,我 只是开端 的程序,非常简单。 我有一些包括向上顶。 现在我已经得到了#包括“structs.h”,但 我会回来的,在一个时刻。 但是,该方法适用于现在。 因此,这是一个程序 那将实施 如处长的数据库。 因此,学生的数据库, 和每一个学生在世界 有一个名字和一个房子,可能是一些 其他的东西,但我们会保持它的简单。 每一个学生都有一个名字和一个房子。 所以,如果我想写一个 计划,其目的在生活中 刚刚从循环 零上最多三个, 如果有三名学生 在哈佛大学。 我只是想,用GetString的, 每个学生的名字和房子, 然后只是打印出来的那些。 这有点像周 其中,第二周的东西,现在, 在这里我只想对 环或类似的东西。 我想打电话给GetString的几 次,然后打印为f的几十倍。 所以,我怎么可以这样做,但是, 当这两个名字和房子 所涉及的每一个学生? 所以,我的第一反应可能 可以做这样的事情。 我会先说,好了,给我, 说,叫名字的字符串数组。 我不想硬编码3在这里。 我想要什么就放那里? 所以学生们,因为这只是 在顶部声明一个常数, 就这样我就不必硬编码 3在多个地方。 这样一来,我可以改变它一个地方, 它影响的变化随处可见。 然后,我可能会做 串安置学生。 而现在,我可能会做这样的事情 为(int i = 0;我<学生,我有用。 所以,我打字快​​,但这是 可能熟悉的语法了。 而现在,这是更近一些。 如果我想要把在第i个 学生的名字,我想我做到这一点。 然后,没有名字 但房子级别I。 我这样做,GetString的,并让 我回去和修复这条线。 同意吗? 不同意? 这不是很人性化。 我还没有告诉用户该怎么做。 但现在,如果我还 希望以后,我们 比如,打印这些东西 out--所以TODO后。 我会做更多的 this--这无疑就是 正确实施 越来越名字和房子,三 它们的总的每一个,从用户。 但是,这不是很好的设计,对不对? 如果学生已经不仅仅是一个名字 和一所房子,但也是一个ID号, 和一个电话号码, 和一个电子邮件地址, 也许一个主页,并 也许是Twitter的手柄, 和任意数量的其他细节 一个学生或一个人有关, 更普遍。 我们该如​​何开始添加 功能,这个程序? 嗯,我觉得最简单的方法可能 可以做这样的事情,比方说, 诠释IDS学生。 这样我就可以把所有的标识在了那里。 然后,对于一些 如电话号码, 我不知道如何 代表了,只是还没有。 因此,让我们继续前进,只需要调用 这个Twitter的学生,其中 是有点怪,但 - 和一帮更多的领域。 我已经开始有效 复制并粘贴在这里。 这是要相当长 笨拙的很快,对不对? 那岂不是很好,如果有 在世界的数据结构称为 而不是整数或字符串,但一些 较高的水平,一个抽象,所以 可以说,被称为是学生吗? Ç没有配备内置 对学生的功能, 但如果我想给它这样的? 嗯,事实证明,我要去 打开一个名为structs.h这里的文件, 你可以准确的做。 我们打​​算从现在开始这样做。 和P组三个的引擎盖下面, 你已经这样做了。 有没有这样的事,作为一个克矩形或 在编程语言C的克椭圆形 人们在斯坦福实现这些 由此处使用这种方法的数据类型, 宣布自己的新数据 使用new关键字类型 所谓的结构,另一个 一个叫的typedef。 而事实上,即使语法 看上去从东西有点不同 我们已经看到过,在 原则上,这是超级简单。 这只是意味着“定义一个类型。” 这将是一个 结构和结构 就像是一个容器 多重的东西。 而这个结构是怎么回事 有一个名为name的字符串, 和一个字符串名为房子。 而且,我们打电话,只是为了方便, 这整个数据结构的学生。 所以,此刻你到 分号,你现在有 创建您自己的数据 类型称为学生 现在站在旁边诠释, 和float和char和字符串, 和g矩形,和g椭圆形,以及任何数目的 其他的事情人发明的。 那么什么是这个有用 现在,如果我回去 为结构0,完成本 实施,这是我写的 提前在这里,请注意,所有的 不可避免的杂乱的 即将开始发生,因为我加入 电话号码和鸟鸣和所有 这些其他的事情 学生的定义, 现在它简洁地包裹起来 因为只有一个阵列的学生。 而每个学生的现在 拥有它里面多的东西。 因此,仅仅留下一个问题。 你怎么看名字搞定, 和房子,和ID, 和任何其他的 里面的学生? 超级简单的,也是如此。 新的语法,但一个简单的想法。 您只需索引数组, 正如我们上周和这一样。 什么是明确的 新片语法? 只是,,意为“进去了 结构,并得到现场叫 名,拿到所谓的房子现场, 让学生称为该领域。“ 因此,在P设定三,如果你 还在努力的, 和大多数人仍 是,要认识到你 开始使用类似的东西 克rects和g椭圆形 和其他的东西似乎没有了 来自周零个,一个或两个, 意识到这是因为斯坦福大学 宣布了一些新的数据类型。 事实上,这也正是我们将 什么时候,以及在P设定四, 我们先来处理事情 像的图像,位图,等等。 所以,这只是一个玩笑话和 心智模式是什么来。 现在,我一拖再拖 有些今天上午。 我是那种好奇,想看看是什么 其实微软壁纸 貌似今天。 而事实证明,一个人在2006年 居然跑到几乎一样, 在同一地点,以在现实中拍摄 什么样子的,这些天。 本场现在是有点杂草丛生。 因此,图像的现在来讲, 让我们带回Daven这里 屏幕和Nicholas上, 而只是提醒你 如果你想和我们一起吃午饭 本周五,头我们平常网址 这里。 那么,我们曾在周一离开了吗? 我们推出了这个问题,对不对? 这看似是一个正确的 实现交换的, 因此你要带两个整数, 一个叫A,一个叫B, 交换它们,就像劳拉在这里做 在与牛奶和水的阶段, 通过使用临时 变量或空杯, 这样我们就可以把B,在和中 b移动,而不做乱七八糟的东西。 我们用一个变量。 这就是所谓的温度。 但是,什么是根本 问题在周一这个代码? 是什么问题就在这里? 是啊。 听众:它占用更多的空间。 戴维·J·马兰:占用更多 空间,因为我使用的是可变的, 那没关系。 这是事实,但我 会说没关系。 这只是32大位 物联网方案,所以没什么大不了的。 其他的想法? 听众:这只是交换 这些变量在本地。 戴维·J·马兰:没错。 它只能在本地交换的变量。 因为任何时候你调用一个函数 - 当我从安嫩伯格托盘 最后一次,你主要在底部。 只要您拨打一个叫做函数 掉期,掉期没有得到x和y, 原来的值。 什么交换的GET,我们什么要求? 听众:复制。 戴维·J·马兰:所以他们的副本。 所以它得到一个和两个,如果 记得上次的例子, 但是一个和两个副本 被成功交换。 但不幸的是,最终, 这些值仍然是相同的。 因此,我们可以看到这与我们的 新朋友,希望广发行, 您或转录因子和Ca的有 在指导你走向如下。 因此,没有掉召回看起来like--我们 开拓this--看起来像这样。 我们初始化X要1,Y两。 有一堆打印F公司。 但随后,该按键通话 这里是交换,这 正是我们的代码 就是刚才看到的。 这是正确的,在第一 一目了然,但在功能上, 这个方案行不通,因为 它不会永久交换x和y。 因此,让我们看到这个,咋暖 在这里用GDB中,./noswap。 一堆铺天盖地的信息 我会摆脱与控制L现在。 而现在,我要 继续并运行它。 不幸的是,这 是没有多大用处的。 它运行的程序这里面 程序调用GDB,调试器, 但它并没有让我闲逛。 所以,我怎么能真正暂停 执行这个程序里面? 因此打破。 我可以打破任何 行数,1,10,15。 但我也可以打破象征 说休息为主。 这就是要设置一个断点 点,显然在主线16。 而其中的16行? 让我们去到的代码 并上升到noswap。 事实上,第16行是 第一个在程序中。 所以,现在,如果我继续和类型 运行这个时候,回车,就暂停。 因此,让我们闲逛。 打印x--为什么是X为零? 而忽略了美元符号。 这还只是票友 使用的程序的。 为什么为x为零的时刻? 是啊。 听众:它暂停前的权利 线16,而不是实际的线16。 戴维·J·马兰:没错。 广发行,在默认情况下,已暂停 只是线16日前执行。 因此它没有执行,其中 意味着x是一些不知名的价值。 我们很幸运,它的 干净的东西像为零。 所以,如果我输入下一个,现在, 现在执行16。 它等待我去执行17。 让我继续前进,打印的X. 这是之一。 让我继续前进,印刷年。 我现在应该看到了什么? 听众:[听不清] 戴维·J·马兰:大声一点。 听众:[听不清] 戴维·J·马兰:不太一致。 所以,是的,我们看到一些垃圾值。 现在,y是134514064那里。 好吧,这只是一些垃圾值。 我的程序使用内存 为不同的目的。 还有其他功能。 别人写我的电脑里面。 所以这些位已经被用于 其他的价值观,我所看到的 是一些残余 在先使用该内存。 所以,没什么大不了的,因为一旦 我键入下一个,然后打印Y, 它的初始化 我想要的价值。 所以,现在,让我们继续快一点。 n转到下一个。 让我们再做一次。 让我们再做一次。 但我不想打 在这里,因为如果我 想看看里面有什么事情 掉,有什么命令? 听众:步骤。 戴维·J·马兰:步骤。 所以这个步骤我变成了 功能,而不是通过它。 而现在,这是一个有点神秘 说实话,但是这仅仅是 告诉我,我在第33行了。 让我们再次做到这一点。 打印温度。 垃圾值,负此时, 但是这仍然只是一个垃圾值。 因此,让我们做下一个,打印温度。 它初始化为1,这 是x的值,也叫做。 现在,这里是我们的a和从X来了吗? 好吧,注意主,我们 所谓的这些值x和y。 然后,我们通过他们交换如下。 点¯x排在第一位,逗号年。 然后,交换可以称他们为x和y。 但为清楚起见,这是 称他们为A和B。 但a和b是现在将要 x和y分别的拷贝。 所以,如果我回去GDB,温度 现在是一年,现在1。 但是,如果我做一个和现在做的打印 A,A已经搬了过来。 牛奶已经倒入前 橙汁的玻璃,或者反之亦然。 如果我下一次再这样做了,现在 如果我打印出来作为一个全面的检查, 一是仍然是两个,但是B现在之一。 坦率地说,它仍然存在。 我不在乎什么温度的。 但只要我现在打字,让我们说, 继续回去,现在我在最后 该程序。 不幸的是,x是 还是1和y仍然是2。 那么,什么是有GDB的效用? 它没有帮我解决 该问题本身, 但它希望能帮助我 理解它通过实现 ,是的,我的逻辑是对的,但 我的代码是不是最终有 产生长远的影响。 所以这是一个问题,我们 要解决现在今天。 但是,让我们以这种方式到达那里。 String是一个谎言。 它也没有一种数据类型 存在于C.它是 是一个代名词一些 时间的东西, 我们可以揭示如下。 让我去进取,不断开拓 一个名为比0。 而非键入此一出来, 我们将开始遍历代码 我已经写了,但 这是只有几行。 所以这是比较-0。 的第一件事情我做 越来越一行文本。 但是要注意什么,我 做第一次。 什么是明确约21行有什么不同? 其实,等一下。 这是一份2。 这甚至不是正确的程序。 好吧,扰流器警报。 好了,所以从不介意。 这就是答案,未来的问题。 这里是比较-0,和我 要得到一个文本行。 程序要简单得多。 因此,这很简单。 这就好比第一周,第二周的东西 眼下。字符串s = GetString的。 现在,我再说一遍下来这里。 串T = GetString的。 然后,在该过去的事 程序,正如它的名字所暗示的, 是我要尝试对它们进行比较。 因此,如果S,第一个字符串, 等于= T,那么我 要说你输入同样的事情。 否则,我会说 你输入不同的事情。 因此,让我们编译并运行这个程序。 所以要比较为零。 看起来不错。 没有编译错误。 现在让我继续前进 并键入./compare-0。 让我继续前进,说些什么 :Daven和东西:罗伯。 与I型不同的东西。 到目前为止,一切都很好。 程序似乎是正确的。 但是,让我们再次运行它。 说些什么:加布。 说些什么:加布。 好吧。 也许我打空格键 什么时髦。 让我们再做一次。 所以Zamyla。 Zamyla。 不同的东西。 那么到底是怎么回事? 因此,我们有以下两行 代码的GetString被调用两次。 然后,我只是 试图比较s和t。 但真正那么是怎么回事? 嗯,我的手写的要 屠夫这个例子有点。 而且,我们居然丢 这件事在这里,也是如此。 因此,我们必须像一条线 字符串s = GetString的。 所以,这只是第一 有趣的线从该计划中。 但是,这段时间一直 正在进行的引擎盖底下? 以及,在左手侧是字符串, 这是某种类型的变量, 而且它称为S。 所以,我知道,这是使用的内存, 或RAM,在我的电脑不知何故。 所以,我要抽象 绘制一个正方形。 32位的,它的出现,但 更多的是在未来。 然后,这是怎么回事了吗? 那么,很明显的GetString 从用户获取的字符串。 和GetString了 Zamyla或加布或Daven。 因此,让我们选择第一 那些的,这是Daven。 所以,有效,什么的GetString了 我在第一种情况是D-A-V-E-N。 然后,还有什么做 它给我的秘密? 听众:[听不清] 戴维·J·马兰:是啊, 在/ 0或空字符。 因此,有效地给了我一个字符串。 但是,我们已经知道,从以前的 看着一个字符串只是一个数组 字符,它的终止 这个特殊的标记字符,/ 0。 但是,如果这是真 这是一个正方形, 这显然​​是一个更大的矩形。 事实上,这是, 我要求中,只有32位。 而这显然超过32 位,因为这很可能是 八加八加8 加八加八, 只是因为在ASCII码的字节。 到底如何我们要适应 Daven到这里这个小盒子? 那么,什么是GetString的真正在做什么? 好了,该网格在这里代表 我的电脑的内存或RAM。 因此,让我们武断地说,如果 每一个都代表一个字节, 那么,我们能想到的每一个 字节为具有一个地址, 像33牛津街,或34 牛津街,或35牛津街。 所以就像家庭有地址 和建筑物有地址, 这样做的单个字节 记忆有地址或号码 唯一地识别它们。 现在,这是任意的。 但要保持简单,我要 用十六进制只是按照惯例, 但0X意味着什么等 比“,这是十六进制。” 而我要去声称, “D”结束于字节的一个存储器中。 我没有什么其他的事情 内存,所以Daven拿到了第一个景点 在字节之一。 那么,这将是0X2。 这会为0x3。 这将是为0x4。 这是要为0x5。 这将是为0x6。 但是,一旦你开始思考 什么电脑做的 引擎盖下方, 你就可以开始来推断 怎么啦,几年前,会 有C本身实现的。 什么是可能的GetString returning--因为它 感觉这不是 返回Daven,本身 因为他肯定不会 适合在这个小box-- 那么,什么是可能的GetString返回? 听众:[听不清] 戴维·J·马兰:Daven的位置。 而且它已经这样做 自从第一周。 什么GetString的是真的 返回不是字符串,本身。 那是善意的谎言之一。 它返回的地址 串在存储器中,唯一的地址。 Daven住在33牛津街。 但更简洁,加文·生活 在为0x1,地址一号。 那么,被放在这个 小盒子那么,要清楚, 是字符串的仅仅是地址。 所以这一切的时候,这 已经持续。 但是,这暗示 现在,如果所有S有 是一个数字,它里面,谁的 阻止你,程序员, 从把任何数目的 任何变量,只是跳 到的内存块? 事实上,我们可以看到 这是一个威胁下一次。 但现在,这种感觉不足。 如果我说,让我 字符串,你给我Daven。 但是,你真的不给我Daven。 所有你给我的是Daven的地址。 我怎么那么肯定知道 其中Daven开始和ends-- 故事的越来越weird-- 其中Daven的开始和结束, 然后,下一个 字符串在内存中开始? 好吧,如果你递过 我Daven的开始, 基本上,我怎么知道 在那里他的名字到底是? 特别空字符,这 是更重要的,现在 如果下面的字符串 引擎盖只是确定 通过唯一地在存储器中的位置。 所以这一切的时候,那是 什么是怎么回事。 所以,当我们现在看 这里的代码,解释 如果你会在第26行的错误。 为什么Zamyla和Zamyla有什么不同? 为什么加布和加布有什么不同? 是的,在后面。 听众:他们有不同的地址。 戴维·J·马兰:很简单,因为 他们有不同的地址。 当你调用GetString的,因为 再次,我会尽快在这里, 如果这是第二行,串 T,因为我在该程序中一样, 等于另一个电话给GetString。 下一次我打电话 GetString的,我要去 以得到不同的块的内存。 GetString的允许 问工作 系统越来越多的内存。 它不会重复使用相同的 六个字节每一次。 这将得到一个新的 块的存储器,其中 装置吨是会得到 其他一些价值在这里。 所以,当我做s等于= T,你不比较 ð对这个和A对 这和V反对这一点。 你这个比较 针对这一点,这 坦率地说是相当useful-- useless-- 没什么用,因为谁真正 关心那里的字符串在内存中? 事实上,我们还没有。 我们不是要 启动特别关怀。 只是在某种程度上,错误可能出现 与安全的威胁可能会出现意志 我们真正开始关心这个。 因此,让我们解决这个问题。 事实证明,你解决它超级简单。 而且,我们其实之前,我 再次表明,会是什么 怎么做,如果在CS50类, 你不得不实施 对两个字符串进行比较。 你显然不能仅仅用s等于= T。 但是,仅仅从逻辑上讲,如何 你比较这串 不要使用C代码这个字符串? 是啊。 听众:刚才做的 for循环[听不清] 戴维·J·马兰:完美。 听众:[听不清] 戴维·J·马兰:是的。 只需使用一个for循环或 while循环或什么的。 但就应用的基本想法,如果 这是内存或阵列的块 这就是,遍历 二者在同一时间。 而只比较字母。 而且你必须是一个 小心一点,因为你 不想一个手指 晃过对方 因为一个字符串 比其他的长。 所以你会想检查 在年底这个特殊的值,则返回null。 但它确实是,在 最后,就这么简单。 坦率地说,我们不需要 重新发明了车轮。 下面是两个版本。 什么我要在这里说的是, 而不是比较s等于= T, 我反而要说,如果字符串 第逗号吨相比等于= 0。 现在,什么是字符串比较? 事实证明,这是一个函数, 带有C,其目的在生活中 要比较两个字符串。 搅拌相比,如果我们读了 手册页或文档或CS50 参考,它会 简单的告诉你,搅 比较收益或者负 数或正数或零, 其中零表示他们是平等的。 所以只是猜测。 可能是什么意思,如果 搅拌收益比较 负值或正值? 听众:大于或小于。 戴维·J·马兰:是啊, 大于或小于。 所以,如果你想整个排序 在dictionary--一串字符串 因为我们最终会下来road-- 完善的功能,潜在的使用, 因为它要做到这一点 比较字符串给你,并告诉 你做了来自前B,或不 b来之前,按字母顺序排列。 我们正是这样做。 而且请注意,我没有一个其他 在本实施例中的事情。 什么改变了更高的 在这个主要的功能? char *的。 而这是其他善意的谎言。 这一切的时候,当你 在写字符串, 我们一直在偷偷改写 字符串为char *,这样实际上铿锵 理解你。 换句话说,在CS50.h 当我们最终会看到, 我们做了一个代名词叫做字符串 这是同样的事情为char *。 而现在,只有在知道 *,在这种情况下,至少 装置的地址。 什么样的报告? 嗯,事实上,我说的 char *的,而不是int *或浮动* 也就是说char *的是 一个字符的地址。 所以这里这个小盒子,又名 字符串,是真的char *类型, 这是说只是一个奇特的方式, 在此框中会去的地址。 并且这是什么地址是指? 显然,一个char。 但是,我们绝对可以 必须是int *和其他的东西。 但现在,char *的是最真的 直接的和感兴趣的。 所以这个问题是要 上升,不过,一次。 假设我打开了这个节目。 让我们来看看现在我们可以预测 有什么不对的代码。 所以这个方案,复制0,我 要继续前进,并再次呼吁 GetString的并存储在s的值。 然后,我为什么这样做, 只是从过去几周的提醒? 我们确实说的GetString 有时,则返回null。 是什么意思,如果 的形式返回空值? 出事了。 这可能意味着该字符串是太 大,计算机的内存不足。 它发生超,超,超 很少,但它可能发生。 我们要检查它, 这就是我们所做的。 因为我们现在看到的,如果你不这样做 开始检查习惯性的东西 像空,你可能 真正开始去 到存储器中的地址是无效的。 而你要开始诱导 越来越多的细分故障。 或者在Mac还是PC,只要 使计算机挂起 或程序冻结,有可能。 所以,现在,我要求在复制0.c,我 现在要通过的方式来复制这些字符串 线28。 然后,我会 如权利要求在底部 在这里,我要 改变其中之一。 所以注意到这一点。 我打电话是我们的老朋友strlen的。 而在英语只是解释 这行34是干什么的? 什么吨支架0 表示在左边。 是啊。 听众:T的第一个字符? 戴维·J·马兰:T的第一个字符。 就是这样。 吨的第一个字母,我想 指定的大写版本 在吨的第一个字符。 因此,这是资本 第一个字母。 然后,在最后一件事,我做的 在这个计划是我要求这里的 原来,S,和这里的副本,T。 但根据故事我们只是 说什么串真的是, 什么是28行真的 做的,什么是 所产生的错误会 要在屏幕上? 因此,首先,第一个问题,28。 什么是串T = S真的在做什么? 如果我们有在左手 这里边串T = S; 这给了我一个盒子 在这里,一个盒子在这里。 并假设该地址是0X, 比方说,50这时候,随意。 什么串T = S 做引擎盖底下? 听众:[听不清] 戴维·J·马兰:它存储在内存中 有地址,所以为0x50去那里。 所以,如果现在我去的第一个 字符T和大写的, 我是什么切实做送? 我真的做同样的事情,对不对? 因为如果地址0x50--,只是,我 没有太多空间在黑板上这里, 但假设这是0X50到这里, 某处在我的电脑的内存中。 而我,比如,加布 在这里小写,这样。 我已经说过吨支架 0被资本化。 嗯,T支架0 T中的第一个字母。 所以,小克将要 成为大湾但是问题 是,是什么而是也指向? 听众:相同。 戴维·J·马兰:同样的事情。 因此,一个简单的解释或许是, 即使语法是有点怪异。 因此,让我们做到这一点。 使复制的0,然后./copy-0。 说些什么:加布。 不幸的是,这两个 他们现在已经被资本化, 但对于基本 原因是我们根本 现在要处理的地址。 那么,我们如何开始 address--没有双关语intended-- 我们该如​​何着手解决 这方面的问题? 那么,在copy1.c,事情进展 变得有点复杂。 但我会要求 概念上很简单的解决方案。 所以很难得到乍一看。 不是一件容易的事为先 一次打出来,也许, 但是,如果该问题是 简单地做T =的只有我 复制地址什么的, 再次,如果我可以选择你, 将是解决方案 在实际拷贝的字符串? 听众:我们可能会 再次使用一个循环。 戴维·J·马兰:是的。 所以,我们要再次需要一个循环。 而且,因为如果我们想复制 一个字符串s转换另一个字符串, 我们可能想这样做 逐字符。 但问题是,如果 这本来是S, 现在我们需要明确启动 在t分配内存。 换句话说,让我们 重绘这是最后一次。 如果是字符串s = GetString的。 让我们把这个在这里,也是如此。 这是GetString的。 然后,画面的东西 像将是象以前那样 G-A-B-E-/ 0。 这看起来有点像这样。 和S因此,我们称这种为0x50, 那将是51,52。 因此,这是为0x50。 然后,我做的串T。 在内存方面,这只是将 给我这样一个小广场。 那么什么是关键的一步呢? 如果我想复制s转换T,什么 空白,我们需要在这里填写? 或者是什么,我们需要 做在一个较高的水平? 是吗? 有人在吗? 是啊。 听众:我们需要[听不清]。 戴维·J·马兰:是的,我们 需要填写这个空白。 我不能复制,然后 利用Gabe的名字 直到我问操作系统 对于内存另一块 这至少一样大的原稿。 所以这给我们留下了一个问题。 我如何向操作系统不 只是一个简单的小pointer-- 因为这是所谓的,一个 地址,pointer--不 一个简单的小盒子 像这样所谓的一个字符串? 我怎么问工作 系统内存一大块? 到目前为止,我只得到了回 间接调用GetString的。 因此,如何的GetString 即使得到它的内存? 嗯,事实证明,有 这个其他的功能在这里 那我们现在就开始使用。 现在,这种方式看起来更神秘than-- 我是谁可以看到它 - 唯一一个 这条线看上去方式更隐蔽 那么就应该第一眼。 但是,让我们逗它拆开。 在左边,我的char *吨。 因此,在英语,让我们开始制定 正确的句子中的技术术语。 因此,这是分配 char类型的变量*称为T。 现在,这究竟意味着什么? 那么,这意味着,我该怎么 把这个变量称为T? 一个字符的地址。 所以,这仅仅是简单的, 更合理的方式 的说明的左手侧。 因此,创建这个盒子在这里只。 这样的右手侧, 据推测,是怎么回事 分配的大 内存块是如何? 因此,让我们取笑这个分开。 它压倒性的第一眼, 但是这是怎么回事里面吗? 首先,有malloc的,这 显然是我们的新朋友, “内存分配”。 因此,这是传递的参数 进去,所以这是一个相当大的争论。 因此,让我们取笑这个分开。 当然,第strlen的,代表the-- 听众:字符数。 戴维·J·马兰:就在 s中的字符数。 所以s的长度,原来的字符串。 因此,G-A-B-E。 因此,它可能是在这里为四个。 之后我为什么要做1 调用第strlen的? 听众:[听不清] 戴维·J·马兰:对于 特殊的空字符。 如果你问我什么是长度 Gabe的名字,我会说,四名。 在系统底层,不过,我需要 在第五个字节的空字符。 所以这就是为什么我做了1。 现在,以防万一你运行这个 程序的计算机比其他的,说, 在CS50家电, 其中一个字符的大小 可能是不同 从我自己的computer-- 事实证明,我可以把这个 运营商的sizeof,只是问了电脑, 什么是a的大小 char的这台电脑上? 并通过在此乘以5 例如,通过一个字符的大小,这 在大多数计算机上会 仅仅是一个,malloc的 是要分配给我这个大 内存块在这里就对了。 而这将return-- 它是一个函数 - 所以它的 要回到我身边吗? 听众:地址? 戴维·J·马兰:什么样的报告? 听众:内存是分配呢? 戴维·J·马兰:的 它的内存分配。 所以,我不知道,坦白地说, 这是怎么回事结束了。 我要建议 这将结束在均为0x88。 完全是任意的,但 什么地方比其他的0x50, 因为操作系统,什么 Windows和Mac OS为我做的,是 请确保它给 我的内存不同的块。 因此,这是价值所在今 内存块可能最终。 原来这就是在这里,均为0x88结束。 所以,现在清楚了,我能理解 这是不一样的,因为这, 因为他们指着 不同组块的存储器。 所以,如果我现在真的想复制此 在,让我们做你的建议的解决方案。 让我们只是去创建一个for循环, 和做T支架í得到Š支架岛 因为现在我可以使用 这阵般的符号, 因为即使非常的malloc 一般我分配内存, 内存只是连续的字节。 字节,字节,字节,回背靠背。 我可以肯定,作为一个程序员 把它当作一个数组,其中 意味着我可以用这个终于熟悉 符号只是一些方括号。 因此,让我停在那里,因为 这是很多一次性全部,甚至 虽然基本思路重温 是字符串,这一切的时候, 是不是一个新的数据类型本身。 这只是一个所谓的指针, 一个字符的地址, 这只是意味着它是一个数字 由人约定 我们倾向于写为0X的东西。 但是,这只是一个数字, 像33牛津街, 这恰好是 政务司司长建筑物的地址。 对这些细节有问题吗? 是吗? 听众:我们为什么检查 在t等于null? 戴维·J·马兰:为什么我们 检查吨等于null? 如果我们读了documentation-- 对malloc的伟大question--, 它会在印刷精美的说, 有时候可能的malloc返回null, 就像GetString的。 事实上,形式返回空值 如果反过来,malloc的返回null, 因为GetString的使用的malloc。 和可能,如果操作系统发生, 的Mac OS,Windows中,无论是简单的 出内存给你。 所以,这就是发生在那里。 并且让我发现一件事 这可能只是打击你的心 或者完全是太远了就行了。 不过,让我拉起来 同样的for循环复制, 其中,刚才被召回 这个。吨级​​别I得到Š支架岛 尼斯和用户友好。 再次感觉就像第二周。 但这个版本其实是可以 写成这样,看起来神秘。 这是一个技术,称为指针 算术,地址运算。 但是为什么这工作? 现在烦人的 的C笔者决定使用 *符号为不同的目的。 我们已经看到了使用一次已, char *的,意思是“给我一个变量 那将包含 一个字符的地址。“ 在这方面如此的char * 意思是“给我一个变数。” 不幸的是,如果您使用不带* 在它前面的单词,如焦炭, 它现在被称为 引用操作。 我们会看到更多这样用不了多久。 但它只是意味着“去那里。” 这就像说,如果有人递给我 在一张纸“33牛津街” 如果我做“* 33牛津街,”这意味着 “走在路上到CS的建设。” 因此,*的意思只是去那里,如果 还有就是在它前面没有字。 那么,什么是T,要清楚? t是该块的地址 这是还给我的记忆。 s是什么,要明确的地址, 在这个例子中,我们一直在讨论, 小写加布? s是地址of-- 听众:字符串。 作者加布的原名:戴维·马兰。 所以它的地址 这个块的存储器。 所以,如果我说T +我 - 我的通知, 只是我们的老朋友了。 这只是一个索引变量 这是从零上了迭代 到的字符串s的长度。 因此,这将是零,再一个, 然后二,然后三天,4。 因此,让我们组装这些新 从无到有,就像拼图游戏一样,如果你愿意, 即使再次,语法 远比划痕更晦涩难懂。 因此,t是一个地址+ i的要给我 数,因为这些都是 我们已经制订为十六进制数。 但他们只是数字。 因此,如果T的地址,我们说 为均为0x88,什么均为0x88加零。 即使你不舒服 用十六进制然而,以此来猜测。 听众:原来。 戴维·J·马兰:仍然均为0x88。 那么,是什么*均为0x88是什么意思? 这意味着,“去那里”,这意味着 有效,“把你的手指在这里。” 和现在的右手侧 该表达式中,*,然后在括号, S + i表示s,这是 这里的小克解决了。 S + 0,当然,S,不管s是。 所以,现在,它的* s,这就像* 33 牛津街是指去的地址 第 因此,这里的这个手指,右手。 那我要复制到什么? 在右侧的事情,这是 加布,在这里,小克,到这里。 那等的影响 在循环的第一次迭代中, 如你提出,尽管它看起来 疯狂的比什么都更复杂 我们已经看到过,只是说 到这里,并在这里复制该字符。 它给你一张地图两个位置。 我们将看到更为了这一点。 但现在,希望仅仅是 介绍其中的一些基本思路。 事实上,让我们来看看 最后一个节目在这里, 然后承诺的粘土动画, 这将使得一切都还好吗。 好吧。 因此,让我开up--我们走吧。 因此,让我 - 我们会回来的 到不久这张图片。 让我开了这个最后的例子在这里。 因此,这里是一个超级,超级 程序完成 没有在生活中,做了以下几点。 它首先声明两个变量,X 和y即不是数字此时, 本身。 他们不是整数,本身。 他们显然是int *。 所以只要任何人,这是什么意思 如果你的数据类型,你的变量, 是的类型是int *星? 这是一个int的地址。 所以,我不知道它在哪儿呢。 它只是意味着“最终, 这里的int的地址。“ 为0x50,均为0x88,无论它是在 存储器中,地址是要在那里。 而这正是y是 将要,以及。 如果我现在说,X =的malloc(sizeof运算(INT)), 这是说,一个奇特的方式, 哎操作系统通过malloc, 给我足够的内存的大小 一个int,这可能是 将是32位或4个字节。 那么,是什么的malloc返回? malloc的返回地址。 那么,什么会得到存放在X? 的组块的地址 存储器,四个字节,该malloc的 刚发现我问 操作系统。 现在同时在线 4在此,* X = 42。 只是要清楚, 这是怎么回事那里? 在左手侧,* X。 这就像* 33牛津街。 因此,* X意味着什么? 听众:去。 戴维·J·马兰:进入该地址。 无论那一块 记忆,去它。 放什么在那里,很明显? 听众:42。 戴维·J·马兰:42。 好吧,* Y,同样的想法。 转到Y中的地址。 把13号在那里, 但为y的时刻? 听众:有没有记忆的年。 戴维·J·马兰:有 对Y没有记忆。 那么什么是ÿ可能 包含,因为我们一直在说什么? 听众:垃圾。 戴维·J·马兰:一些垃圾值。 现在,垃圾的价值仍然是一个数字。 它仍然可以被误认为是一个地址。 就好像一个人 潦草的东西了, 我误解了它的意思 一些建筑在街上。 如果你只是试图进入 一些建筑物不属于您, 或一些内存块,你有没有 已经给出不好的事情可能会发生。 计算机可能会崩溃,或者一些其他的 未确定的行为可能会发生。 所以,前奏的话,要宾基是这样的。 我还记得,20 一些多年后, 我在那里的时候,我终于 理解指针。 这就是说,如果 离开这里在三分钟 而以为我不 理解指针,实现 我记得20 年,一些疯狂的原因 何时以及为什么它最后沉没 中,坐在我的教学 老乡,尼沙特梅塔在 艾略特食堂回来。 现在,我想起了 这是因为,这是 的主题时,我在一个 特别是,挣扎。 然后,它最后点击, 像我敢说很多话题 最终会的。 而现在,以使该感到所有的 更快乐,更让人信服, 让我们在最后我们看一下 最后三分钟,在这里宾基, 从我们的朋友,尼克 Parlante来自​​斯坦福大学。 [视频回放] 嘿,宾基。 醒来! 现在是时候为指针乐趣。 - 什么是什么? 了解指针? 噢,好极了! - 嗯,上手的,我想我们 将需要几个三分球。 - 确定。 此代码分配两个三分球, 它可以指向整数。 - 确定。 嗯,我看到两个三分球,但他们 似乎并没有被指向任何东西。 - 这就是正确的。 最初,指针 不指向任何东西。 他们指出,被称为东西 指针对象,并设置他们的 一个单独的步骤。 哦,对,对。 我知道这一点。 该指针对象是分开的。 呃,那么你如何分配指针对象? - 确定。 那么,这个代码分配 一个新的整数指针对象, 而这部分设置x指向它。 嘿,这看起来更好。 因此,利用它做些什么。 - 确定。 我将间接引用指针x可 数字42存入及其指针。 对于这一招,我需要我的 提领的魔术棒。 解引用的 - 你的魔术棒? That--这是伟大的。 - 这是什么样的代码如下所示。 我会刚刚成立的号码,[流行] 嘿,快看。 就这样吧。 -so做一个提领在X如下 箭头访问及其指针。 在这种情况下,存储器42在那里。 嘿尝试使用它来存储数 13穿过另一个指针,Y。 - 确定。 我就投奔这里Y, 并获得了13号成立。 然后,采取的魔杖 非关联化和公正[叮咚] - 哦! 哦,嘿嘿! 没有工作。 说,宾基,我不认为提领 y是一个好主意,因为你知道, 建立指针对象 是一个独立的步骤。 而且我不认为我们曾经做到了。 - 良好的点。 是啊。 我们分配的指针,Y,但我们 从来没有把它设置为指向一个指针对象。 - 非常细心。 嘿,你看起来好有,宾基。 你可以解决它,从而y点 到相同的指针对象为x? -sure。 我会用我的魔杖 的指针赋值。 -is那将是 像以前一样的问题吗? - 没有。 这不碰指针对象。 它只是改变了自己的指针 指向同样的事情又。 哦,我明白了。 现在Ÿ指向同一个地方为x。 所以等待。 现在,Y是固定的。 它有一个指针对象。 所以,你可以尝试的魔杖 提领一次送13以上。 -Uh,确定。 在这里不言而喻。 [流行] 嘿,看看这个。 现在提领Y上的作品。 而由于指针分享 一个指针对象,他们都看到了13。 是啊。 共享,等等。 那么,我们现在要切换的地方? 哦,你看。 我们没时间了。 -But-- - 只是记住三个指针的规则。 第一,基本结构 是你有一个指针, 它指出了一个指针对象。 但指针和 指针对象是分开的, 和常见的错误 是要建立一个指针, 但忘了给它一个指针对象。 第二,指针废弃 开始于指针 并沿用其在箭头 访问及其指针。 大家都知道,这 只有当有 指针对象,哪一种 变回规则一。 第三,指针 任务需要一个指针 并将其更改为指向 同样的指针对象作为另一个指针。 因此,在转让之后, 这两个指针 将指向同一个指针对象。 有时候,这就是所谓的共享。 而这一切就是这么简单,真的。 再见了。 [完视频回放] 戴维·J·马兰:这就是它的CS50。 我们会看到你下周。