>> [音乐播放]
戴维·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。
我们会看到你下周。