Tip:
Highlight text to annotate it
X
>> DAVID马兰:好的,欢迎回来。
这是CS50。
这是七周的开始。
因此,它已经有一段时间,所以我想我们最好 在哪里,我们需要旋风之旅
离开的,我们现在要。
>> 所以这个东西在这里可能有 造成了一定的焦虑在第一。
但我希望,你开始 适应新环境,这表示在这里 -
星级代表一个指针,它是 究竟是什么,更通俗地说?
因此,它是一个地址。
>> 因此,它的地址是 在内存中的东西。
我们开始剥开层层 几个星期前,事情喜欢
GetString的和其他类似的功能 这一切的时候已经返回
地址在内存中的东西,像 地址中的第一个字符
一些序列。
>> 因此,我们也介绍了valgrind的, 你会开始使用这个问题
设置,尤其是为下一个 问题设置。
valgrind的为我们做什么?
检查内存泄漏, 检查滥用记忆。
>> 以一定的概率,它可以检测,如果 你的代码将触摸内存
那根本不应该。
所以不一定泄漏,但如果你 一些超越的界限
数组,并在实际运行Valgrind的 并诱发这种行为,而
Valgrind是运行在你的程序是 它内部的运行,你会得到
这样的消息 - “无效写 尺寸4,“记得一对夫妇
两周前意味着我不得不意外 喜欢上一个int太远
边界之外的一个数组。
等大小4表示这里的大小 该特定的诠释。
>> 因此,需要安慰的事实, Valgrind的输出,它的格式,
仅仅是残暴的。
这真的很难识破的一塌糊涂 有趣的信息。
所以我们在这里所做的只是摘录 一些对情侣更
有趣的线。
但要意识到80%的valgrind 输出将是一个有点
分心。
>> 只要看看这些模式,如 - 无效的,正确的,无效的阅读,40个字节
和一些的块数是绝对 丢失,这样的关键字。
什么,你会希望看到的是一些 那种一丝什么功能
错误是实际上英寸的
在这种情况下,在这里,在哪一行 我的代码,显然是错误的吗?
>> 在一个名为memory.c,这是26 例如,我们都在玩
的时间。
所以它可能不是malloc的。
这可能是在我的代码代替。
因此,我们将再次看到这 前再次长。
>> 因此,scanf函数,这是在一个 夫妇迄今形式。
我们看到sscanf的简要介绍。
而东西 你在你跳入
准备测验。
和scanf实际上是什么CS50 图书馆一直使用下面的
相当长的一段时间,以便罩 得到来自用户的输入。
>> 举例来说,如果我移动到CS50 家电在这里,让我开了
比如今天这就是所谓的scanf函数0.C 它的超简单。
这只是一个几行代码。
但它真的演示如何调用getInt 已经工作的这段时间。
>> 在这个程序中在这里,在第16行 请注意我声明一个int。
因此,没有指针,没有什么神奇 在那里,只是一个int。
然后在第17行,我提示 用户输入一个数字,请。
然后在18年底,我这里使用的scanf。
我和规定,一种如printf, 我期待报价
引文结束%。
>> 所以我%,当然, 表示一个int。
但是要注意什么第二 是scanf函数参数。
你会如何形容第二 逗号后的参数?
那是什么?
>> 这是x的地址。
因此,这是非常有用的,因为通过提供 scanf函数x的地址,什么
授权功能怎么办?
不只是去那里,而且还做什么呢?
>> 它的变化。
因为你可以去那里,它的排序 就像一张地图在内存中的位置。
所以只要你提供scanf函数,或 任何这样的地图,即功能
功能可以去那里,不仅 看一看的价值,但它也可以
更改该值,这是有用的,如果 scanf函数在生活中是
扫描来自用户的输入,具体 从键盘输入。
和F表示格式化,就像 printf的一个格式化的,f表示
要打印的串。
>> 因此,在短期,简单地说,此行18, 从用户的尝试读取一个int
键盘和它里面存储的x, 无论地址x恰巧住在。
然后最后,19号线刚说, 感谢为int的,在这种情况下。
>> 所以,让我继续前进,使这个。
所以使:scanf的0。
让我继续放大。
我会去,并运行此 点斜线:scanf的0。
号码好吗?
50。
感谢为50。
因此,它是相当简单的。
>> 现在是什么是不是在做什么?
这不是做了一大堆 错误检查。
举例来说,如果我不配合, 我不键入一个数字,但
而不是我写的东西,如“你好”, 这只是一种奇怪的。
因此CS50的事情之一 库已经为我们做了一些
时间是再次提示 并再次提示。
>> 重试短语召回在cs50.c, 的原因,调用getInt
CS50库实际上是一个整体 一堆线长,因为我们
检查这样的愚蠢的东西。
用户不要给 我们,其实,一个int?
他或她给我们的东西 像一个字母?
如果是这样,我们要检测 ,并大声喝斥。
>> 但是,事情变得更加有趣 在下一个例子。
如果我去scanf函数1.C,什么是一个 事情是从根本上改变
在下一个例子吗?
我使用char *,当然, 而不是int。
>> 因此,这是有趣的,因为char *, 回想一下,其实只是
同样的事情串。
所以感觉一样,也许这是一个超级 GetString的简单实现。
但我已经去皮层 CS50库,所以我
现在调用这个char *的。
让我们看看,如果在任何地方, 我们去错了。
>> 第17行 -
我再次说,请你给我的东西, 在这种情况下,一个字符串。
然后在下一行,我调用scanf函数, 再次,给它一个格式码,
但这次%秒。
那么这个时候,我 给它的缓冲区。
>> 现在请注意,我没有使用 符号。
但是,这是为什么这里大概OK?
原因是什么缓冲了吗?
这已经是一个指针。
它已经一个地址。
>> ,让我们这个“混淆视听”,让我 只是把它,例如,
简约。
不过,我已经把它称为缓冲,因为在 一般情况下,在编程中,如果你有一个
大块的内存,这一个字符串真的 只是,你可以称之为一个缓冲区。
这是一个地方来存储信息。
>> 类似的事情,如YouTube,当 他们正在缓冲,可以这么说,
只是意味着它的下载位 将它们保存在互联网和
本地阵列,一个地方的内存块,所以 ,你可以看它,以后不
跳跃或挂在 你一边玩。
>> 所以这是一个问题,但在这里, 因为我告诉scanf函数,期望
来自用户的字符串。
这里的地址是 一块内存。
把该字符串。
这是为什么绑定给 给我们带来麻烦,但?
>> 那是什么?
我允许访问 内存的那部分?
你知道,我不知道。
由于缓冲区被初始化 什么吗?
真的没有。
因此,这是我们一直呼吁 垃圾值,这
是不是一个正式的词。
它只是意味着,我们不知道什么位 内的四个字节,
我已经分配缓冲区。
>> 我还没有叫的malloc。
我肯定不叫GetString的。
那么,谁知道什么是真正的 缓冲液内?
还告诉scanf的盲目,去那里 并把任何用户输入。
>> 那么,什么是可能造成 在我们的代码中,如果我们运行呢?
大概一个segfault。
也许不是,但可能是一个段错误。
和我说,也许不是因为有时 你这样做,有时
你没有得到一个段错误。
有时候你就是幸运的,但 但是这将是
在我们的程序中的一个bug。
>> 所以,让我继续前进,编译这个。
我要做到这一点老派的方式。
所以铛破折号scanf函数-1,0, scanf函数1.C,回车。
哎呀,太旧的学校。
让我们来看看。
我应该在哪里?
哦,字符*缓冲区。
哦,谢谢你 -
保存,OK -
很老的学校。
好吧,它已经有一段时间。
>> 所以,我刚刚保存后的文件 使该临时
前改变了一会儿。
现在我已经编译 手动锵。
现在我要继续前进 并运行scanf函数-1,回车。
字符串。
我会键入“你好。”
>> 而现在,这里的地方,坦率地说,PRINTF 可以是有点恼人。
它实际上并不是要 在这种情况下,段错误。
printf是有点特殊的,因为 它是如此的超级常用
基本上printf是做 我们赞成和实现,
这不是一个有效的指针。
让我把它后,我自己只是打印 在括号空,甚至
虽然它不一定是 我们自己的预期。
>> 因此,我们不能真的很容易诱发 段错误这一点,但显然这
是不是我想要的行为。
那么,有什么简单的解决方案?
那么,在scanf-2,让我提出, 而不是实际只是分配
的char *,让我有点小聪明有关 这一点,让我分配缓冲区
为16个字符的序列。
>> 所以,我可以做到这一点的方式在一对夫妇。
我完全可以使用malloc。
但我可以回去两个星期时 我只是需要一大堆
字符。
这只是一个数组。
因此,让我,而不是重新定义缓冲区 是一个数组为16个字符。
>> 而现在,当我通过缓冲区 -
这是我们没有的东西 谈谈在本周二 -
但你可以把一个数组作为 虽然它是一个地址。
技术上,正如我们已经看到的那样,他们是 有一点点不同。
但scanf函数不会介意,如果你传递给它 数组名,原因是什么
铛会为我们做本质上是 作为治疗该数组的名称
16个字节的数据块的地址。
>> 因此,这是更好的。
这意味着,现在我希望能 做到以下几点。
让我缩小了一会儿, 做scanf的-2,编译OK。
现在让我做了斜线scanf函数2。
字符串。 “你好。”并且它 似乎工作时间。
>> 但有人提出了一个方案 它仍然可能不工作?
是吗?
东西超过16个字符。
而实际上,我们可以 更确切的一点。
东西不再那么15个字符, 因为我们真的需要牢记
我们需要反斜杠零 上面的字符串末尾的隐式
这是一个抛开scanf函数通常会 照顾我们。
>> 因此,让我做这样的事情 -
有时我们就可以 离开它这样。
好了,我们现在已经引起 我们的分割故障。
为什么呢?
因为我打字不超过15个 字符,所以我们实际上已经
其实我感动内存 不应该有。
>> 那么,什么是真正的解决方案在这里?
那么,如果我们需要一个更长的字符串?
好吧,我们也许做32个字节。
那么,如果不够长吗?
大约64个字节?
如果不够长?
约128或200字节?
什么是真正的解决方案,在这里 一般情况下,如果我们不知道在
推进用户要输入什么?
>> 这是一个很大的痛苦的屁股只是一种, 说实话,这是为什么
CS50库有几十行 共同实施的代码
字符串的方式,我们不这样做,则由GetString引发 提前知道什么
用户将要输入。
特别是,如果你回头看看 cs50.c从两个星期前,你会看到
确实,GetString的 以这种方式不使用的scanf。
相反,它读取一个字符 的时间。
>> 因为一个美好的事情 我们可以读取一个字符
保证自己总是 至少有一个字符。
我可以声明一个char,然后采取 只是这些真正的婴儿的步骤
在读取一个字符 从键盘输入的时间。
然后,你会看到的GetString 确实是每次用完,
说,16字节的内存,它使用 malloc的,或一个表弟物,
分配更多的内存,复制旧 内存成新的,然后爬
一直以来,得到一个字符的时间, 当它用完
的内存块,它扔了出去,待价而沽 更大的内存块复制旧
进入新的和重复。
,它是一个真正的痛苦其实 实现的东西一样简单
得到来自用户的输入。
>> 所以,你可以使用scanf函数。
您可以使用其他类似功能。
而很多课本和在线 例子,但他们都
脆弱到这样的问题。
最终,得到一个segfault 是有点恼人。
这不是为用户好。
>> 但是,在最坏情况下,这是什么 它从根本上把你的
代码的风险吗?
某种攻击,有可能。
我们谈到了一个这样的攻击 - 堆栈溢出。
但在一般情况下,如果你允许 缓冲区溢出,像我们做了一个
几个星期前,只是写 以上的“你好”,你在堆栈上
的确可以考虑,潜在的, 计算机上,或者至少在数据
不属于你。
>> 因此,在短期,这就是为什么我们有 这些培训轮子。
但是现在,我们开始把他们赶走, 因为我们的课程不再需要,
必须的,来自用户的输入。
但在问题的情况下,设置6个, 您的输入将来自一个巨大的
一些字典文件150 奇千言万语。
>> 所以,你将不必担心 用户任意输入。
我们会给你一些假设 关于该文件。
指针上有任何疑问或scanf 或用户输入一般?
>> 所有的权利,所以在一个快速浏览一下,然后 尾随从两个星期前的话题。
这是一个struct这个概念。
不 - 这个概念, 结构,这是什么?
什么结构为我们做什么?
>> 定义 -
对不起?
定义一个变量的类型。
因此,排序。
其实我们两个主题结合。
因此,用typedef,回想一下,我们可以 声明一个类型,像我们自己的
的代名词,就像字符串的char *。
但是,我们可以使用typedef和结构 真正创造我们自己的数据结构。
>> 举例来说,如果我回去到gedit中 这里只是一个瞬间,我先走
做这样的事情,让我节省 本作,让我们说,structs.c
暂时我只是 继续前进,包括
standardio.h,INT主要无效。
然后在这里,假设,我想 写一个程序,存储
多个学生从多个 房屋,例如。
因此,它是像一个registrarial的 某种数据库。
>> 所以,如果我需要一个学生的名字,我 可能会做一些像char *的名称,
我会做这样的事情 -
其实,让我们使用CS50库 只是一瞬间,使这个
简单一点的,所以我们可以借用 那些几十行代码。
只是,让我们保持它的简单。
我们会保持它的字符串, 现在则由GetString引发。
>> 因此,我要求现在,我已经存储的名称 一些学生,房子
一些学生,只需使用变量 像我们一样,在第一个星期。
但是,假设我现在要支持 多个学生。
好吧,让我的直觉是做 字符串名称2,得到的GetString,串
house2得到的GetString。
然后我们的第三个学生, 让我们做NAME3 GetString的。
>> 所有的权利,所以这是希望引人注目 作为一种愚蠢的,
因为这个过程是真的从来没有 将要结束,它只是要
使我的代码看起来更糟糕 和每况愈下。
但我们解决了这个在本周二也。
我们比较干净的解决方案是什么 当我们有多个变量,
相同的数据类型都有关,但 我们不希望这种残暴的混乱
同样命名的变量?
我们做了什么呢?
>> 所以我想我听到了几个地方。
我们有一个数组。
如果你想的多个实例 的东西,为什么不要我们清理这一切
,只是说,给我 数组的名字呢?
>> 现在,让我们的硬编码3。
然后给我另一个数组 称为房子,让我
现在硬编码3。
而且我已经大规模清理 乱,我只是创建。
现在,我还是硬编码3,但即使 3可以动态来自
用户,或者argv的或类似。
所以这已经是清洁。
>> 但恼人的是, 现在,即使名字是某种
根本联系 学生的家 -
这是一个学生,我真的 要代表 -
我现在有两个平行的阵列 在这个意义上,他们是
相同的大小,名称托架0 想必映射到房子支架0,
和名称支架1地图 房屋支架1。
换句话说,该学生生活在 那房子,房子和其他学生
生活在其他的房子。
但可以肯定,这可能是 做得更干净。
>> 好吧,它可以,其实。
并让我继续前进,打开 了structs.h,你会
在这里看到这个想法。
请注意,我用的typedef,因为你 刚才提到申报我们
自己的数据类型。
但是,我也使用此关键字 称为struct这给了我一个新的
的数据结构。
>> 而这一数据结构,我要求是怎么回事 有两件事情里面
- 一个字符串名为name, 一个字符串,称为房子。
和名字我要去给 将这样的数据结构
被称为学生。
我可以打电话给我想要的任何东西, 但这种语义
我感觉到,在我的脑海里。
>> 所以,现在,如果我打开了一个更好的版本 的节目,我开始写
那里,让我滚动到顶部。
还有一些更多的代码行 在这里,但让我专注
一个时刻。
我宣布一个恒定的所谓学生 硬编码的现在。
但现在,注意到何洁 我的代码开始就搞定了。
>> 在22行,我宣布 阵列的学生。
并注意学生显然是 现在的数据类型。
因为在顶部的文件,通知 我已经包含了该头文件
我拉起刚才。
该头文件很简单 这个定义一个学生。
>> 所以,现在,我创建了自己的自定义数据 类型,作者的C年
前事先没有想到的。
但没有问题。
我可以做自己。
所以这是一个阵列称为学生, 其每名成员
是学生结构。
我想三个 在数组中。
>> 而现在,没有休息 这个程序怎么办?
我需要的东西有点武断。
因此,从24日起在网上, 我遍历从0到3。
然后我再问用户 学生的名字。
然后我用则由GetString引发如前。
然后,我问学生的房子, 我用则由GetString引发像以前那样。
>> 但通知 - 稍微新 一块语法 -
我仍然可以索引到的第i个学生, 但我怎么得到的具体数据
领域里面的结构吗?
那么,什么是显然 新语法?
这仅仅是点操作符。
>> 这之前,我们还没有真正见过。
你已经看到了它的pset五,如果你 已经跌位图文件。
但点只是意味着在这里面, 结构或多个领域,给点
名称,或者给我点的房子。
这意味着内部结构 得到这些特定的领域。
>> 这个程序的其余部分做什么?
这还不是全部,性感。
请注意,我再次循环从0到3, 我只是创造英语
短语,比如某某等 这样的房子,通过在点名称
的第i个学生和他们的 房子,以及。
>> 最后,现在我们将开始得到 肛门,现在我们
熟悉什么malloc和 其他功能已经
做这一切的时候。
为什么我一定要释放这两个名字 和房子,即使我
没有调用malloc?
>> GetString的了。
那是肮脏的小秘密 几个星期,但GetString的
遍布泄漏内存 把所有学期迄今为止。
valgrand终于将 揭示给我们。
>> 但是,它不是一个大不了的,因为我知道, 我可以简单地释放名称
和房子,虽然在技术上, 超强,安全,应该是我
做一些错误检查。
什么是你的直觉告诉你吗?
我应该怎么检查 之前,我释放什么是
字符串,又名一个char *?
>> 我真的应该进行检查,如果学生 支架I点名称不
等于空。
然后,它会确定先走,并免费 该指针,相同或其他
别人。
如果学生支架I点的房子是不是 等于为null,这将保护
对角落的情况 的形式返回类似空。
而且我们刚才也看到了,printf的 保护我们在这里只是说
null,这是怎么回事,看起来很怪异。
但至少它不会出现段错误, 正如我们所看到。
>> 好吧,让我在这里做另一件事。 结构-0是一个愚蠢的计划
因为我输入所有数据,然后 它失去了,一旦程序结束。
但是,让我继续前进,做到这一点。
让我做终端 窗口有点大了。
让我结构-1, 这是一个新版本。
>> 我会在一点点放大。
现在让我跑点 削减结构1。
学生的名字 -
大卫·马瑟,让我们做罗布·柯克兰, 让劳伦利维瑞特。
现在是什么有趣的通知 -
我只知道这是因为 我写的程序 -
现在我目前有一个文件 目录students.csv。
你们当中有些人可能已经看到 这些在现实世界中。
>> 什么是CSV文件?
逗号分隔值。
它有点像一个穷人的 版本的Excel文件。
这是一个表的行和列, 你可以打开一个程序如Excel,
或在Mac上的数字。
>> 如果我在这里打开此文件gedit中, 通知 - 数字是不存在的。
这只是gedit的告诉 我行号。
的第一行通知 文件是大卫和马瑟。
下一行是罗布逗号柯克兰。
第三行是劳伦 逗号利维瑞特。
>> 所以我创建了什么?
我现在写的C程序 可以有效地生成电子表格
可以打开在 如Excel程序。
并非所有引人注目的一个数据集,但 如果你有更大的大块
数据,你其实是要 操纵,使图表和
喜欢,这也许是一个 的方式来创建数据。
此外,特装车点实际上超共同 只是简单的数据存储 -
雅虎财经,举例来说,如果你得到 通过他们所谓的股票行情
API的免费服务,让您 获取当前到最新的库存
公司的报价,他们 在给数据
超简单的CSV格式。
>> 所以,我们是怎么做到的呢?
注意到,这一计划的最 几乎是相同的。
但是请注意,在这里,而不是打印 学生,上线35
开始,我要求我保存 学生到磁盘,保存文件。
>> 因此,注意到我声明一个FILE * -
现在,这是一种异常C. 无论出于何种原因,文件是全部大写,
这是不是像大多数其他数据类型 但是这是一个内置的
数据类型,文件*。
我声明一个指针到一个文件, 你怎么能想到的。
>> FOPEN意味着打开的文件。
你想打开什么文件?
我想打开一个文件,我将 任意调用students.csv。
我可以打电话,我想要的任何东西。
>> 再取一个猜测。
第二个参数做什么 FOPEN大概是这个意思吗?
右,w代表写, 是读r为。
还有一个附加的,如果你 要添加行,而不是
覆盖整个事情。
>> 但我只是想创建这个文件 一次,所以我会使用报价引文结束瓦特。
而且我知道,只有在读取 文档或手册页。
如果文件不为空 - 换句话说, 如果没事就去那里错了 -
让我遍历 从0到3的学生。
>> 现在注意到有什么东西 曾经如此略有不同
行约41。
这不是printf的。
fprintf printf的文件。
因此,它会写入文件。
哪个文件?
您指定的指针 作为第一个参数。
>> 然后,我们指定格式字符串。
然后,我们指定我们想要什么字符串 插头的第一%S和
然后另一个变量或 第二个%秒。
然后关闭文件FCLOSE。
比我释放内存之前,虽然 我应该回去,并添加
一些检查为空。
>> 就是这样。
FOPEN,fprintf等FCLOSE给我 创建文本文件的能力。
现在,你会看到问题集五, 涉及图像,您将使用
二进制文件来代替。
但是从根本上说,这个想法是一样的, 即使功能,你会
看到的是有一点点不同。
>> 所以旋风之旅,但你会得到 太熟悉文件I/O--
输入和输出 - pset中五。
而任何疑问 初始的基础在这里?
是吗?
>> 如果你试图释放一个空值?
我相信,除非已经得到了自由 对用户来说更加友好,你可以
潜在的段错误。
它传递空是不好的,因为我不 相信自由困扰为你检查,
因为它可能会是浪费 为它做自己的时间
在世界上的每个人。
好问题,虽然。
>> 好,那么这种得到 我们一个有趣的话题。
习题集的主题 五是取证。
至少这是一个部分 问题集。
取证一般是指在 恢复的信息,可能或
可能没有被删除 故意的。
所以我想,我想给你一个快速 什么味道真的
下面这段时间 引擎盖您的计算机。
>> 举例来说,如果你里面有你 笔记本电脑或桌面电脑一
硬盘驱动器,它可以通过机械 设备实际旋转 -
有圆形的东西称为盘片 看起来很喜欢我
刚刚在这里,虽然在屏幕上 这是越来越多的老同学。
这是三个和一个半英寸 硬盘驱动器。
三个半英寸指 的东西,当你安装它
在一台计算机。
>> 你们中许多人的家伙现在在您的笔记本电脑 有固态硬盘或SSD,
没有移动部件。
他们更像RAM不像 这些机械设备。
但这些想法仍然是相同的, 当然,因为它们涉及
问题五。
>> 如果你想想现在的硬盘驱动器 代表了一圈,这
在这里,我会得出这样的。
当您在您的计算机上创建一个文件, 无论它是一个SSD,或在
这种情况下,硬盘驱动器是较旧的学校, 该文件包括多个位。
比方说,它的0和1, 一大堆的0和1。
所以这是我的整个硬盘驱动器。
这显然是一个相当大的文件。
并且被使用在该0s和1s 部分的物理盘片。
>> 那么,什么是物理部分?
嗯,事实证明,在硬盘上, 至少在此类型中,有
这些微小的磁性粒子。
他们基本上有北部和 南极,因此,如果您
打开其中一个,这些磁性颗粒 通过这种方式,你可能会说,这是
较1。
如果它是倒挂南下 北,你可能会说,这是
代表一个0。
>> 因此,在真实的物理世界,这是 你如何能代表的东西
二进位的0状态和1。
所以这是一个文件。
有一大堆磁 是他们这样或颗粒
通过这种方式,创建模式 0和1。
>> 但事实证明,当你保存文件, 一些信息分开保存。
所以这是一个小桌子, 一个目录,可以这么说。
我会打电话给这列名, 我会打电话给这个列位置。
>> 我要去说,假设 这是我的简历。
我的resume.doc被存储在 位置,比方说123。
我总是去该号码。
但我只想说,就像 在RAM中,你可以把一个硬盘驱动器
这是一个千兆字节或200千兆字节 TB级,你可以
所有的字节数。
你可以列出所有的8位块。
>> 因此,我们会说,这 是123的位置。
因此,这个目录里面,我的作业 系统会记住我
简历是在位置123。
但它变得有趣,当 你删除一个文件。
>> 因此,例如 -
令人欣慰的是,世界上大多数国家都有 捕捉到这 - 时会发生什么
拖动文件到您的Mac OS垃圾桶 或Windows回收站?
这样做的目的是什么?
这显然是要摆脱的文件, 但到底是什么行为拖动
下降到废纸篓或 回收站在电脑上做的吗?
>> 绝对没有,真的。
这就像一个文件夹。
这是一个特殊的文件夹,可以肯定的。
但它实际上删除的文件?
>> 哦,不,因为一些你可能 一直喜欢,哦,该死的,你没有
意味着这样做。
所以,你双击 垃圾桶或回收站。
你周围戳,你已经恢复 只需拖动文件
离开那里。
所以很明显,它不一定 删除。
>> OK,你聪明得多。
你知道,只是拖动它到 垃圾桶或回收站并不意味着
你清空垃圾桶。
所以,你上去的菜单,和你说 清空废纸篓或清空回收站。
然后会发生什么?
>> 是啊,所以它被删除,更是这样。
但所发生的一切是这样的。
电脑忘记 是resume.doc。
>> 但什么也没有明显变化 在画面?
位,0和1,我要求的是 在现场的一些物理方面的
硬件。
他们还在那里。
这只是电脑有 遗忘它们是什么。
>> 因此,它本质上释放文件的 位的,所以它们可以被重复使用。
但直到你创建更多的文件, 多个文件,多个文件
概率,这些0和1, 这些磁性粒子,得到重用,
上攻或右侧, 其他文件,0和1。
>> 所以,你有这样的时间窗口。
它不是可预测 长度,真的。
这取决于你的硬盘的大小 驱动器和你有多少个文件
你如何迅速做出新的。
但是这期间的时间窗口 该文件仍然是完美的
收回。
>> 所以,如果你使用的程序如McAfee 或Norton尝试恢复
数据,他们正在做的是试图 恢复这个所谓的目录
弄清楚你的文件在哪里。
有时诺顿和会说, 文件是可收回93%。
那么,是什么意思呢?
这只是意味着,其他一些文件 巧合的结束使用,也就是说,
那些位出你的原始文件。
>> 那么,什么是真正参与 在恢复数据?
好吧,如果你不会有这样的事情 诺顿预先安装在电脑上,
有时你可以做的是最好的看 在整个硬盘寻找
的位模式。
和问题集的主题之一 五是,你会搜索
相当于一个硬盘驱动器,一个法医 形象从一个紧凑的闪存卡
数码相机,搜索为0 和1,通常,具有较高的
概率,代表 开始的JPEG图像。
>> 你们可以收回这些图像 假设,如果我看到这个图案
位法医形象, 的概率很高,这标志着
开始的JPEG。
如果我再次看到同样的模式, 可能标志着开始
另一个JPEG格式,和其他 JPEG格式,和其他的JPEG。
这通常是如何 数据恢复工作。
关于JPEG文件有什么高兴的是,即使 的文件格式本身是有点
复杂,每一个这样的开头 文件其实是相当可识别
和简单,因为你会看到, 如果你还没有准备好。
>> 因此,让我们来仔细看看下面 正是一直罩
回事,这些0和1 ,给你多一点的
上下文这个特殊的挑战。
>> [视频回放]
>> ,如果您的电脑存储最 其永久性的数据。
要做到这一点,数据从RAM 随着软件信号,告诉
硬盘驱动器如何将这些数据存储。
硬盘驱动器电路翻译 这些信号转换成电压
波动的影响。
这些,反过来,控制硬盘驱动器的 移动部件,一些数
留在移动部件 现代计算机。
>> 部分的信号控制电机 其中旋转金属涂层盘片。
您的数据实际上是存储 这些盘片上。
其他信号将读/写 头读取或
写在盘片上的数据。
这个机器,一个人如此精确 头发甚至不能之间传递
磁头和旋转盘片。
然而,这一切都以惊人的速度。
>> [END视频播放]
>> 国宝马兰:在一个小放大 更深现在什么
实际上这些盘片上。
>> [视频回放]
>> - 让我们来看看,在我们刚才 看到慢动作。
当一个简短的电脉冲 发送到读/写头,如果翻转
一个微小的电磁 的一小部分的第二个。
磁铁创建一个字段,该字段 一个微小的,微小的改变极性
部的金属颗粒 大衣每个盘片表面。
>> 这些微小的一个模式系列, 充电区,在磁盘上的
表示的一个位 二进制数中的数据
由电脑系统使用。
现在,如果当前发送的一种方法 通过读/写头,该地区
是在一个方向上极化。
如果当前的发送,在 相反方向上,
极化反转。
>> 您是怎样从硬盘的数据?
只要相反的过程。
因此,它是在磁盘上的颗粒 获取中的电流
读/写头移动。
这些放在一起百万 磁化段,
你已经得到了一个文件。
>> 现在,一个单一的文件件 遍布驱动器的
盘片的一塌糊涂,有点像 你的办公桌上的文件。
因此,一个特殊的额外的文件跟踪 这里的一切是。
难道你不希望你有 类似的东西?
>> [END视频播放]
>> 国宝MALAN:OK,大概不会。
所以,你们的许多球员 从小一起长大的这些吗?
OK,所以越来越少 表决时,每一年。
不过,我很高兴你至少熟悉 与他们,因为这和我们自己的
可悲的是,书的演示,死一个非常 熟悉拖死。
>> 但是,这是我,至少,早在 高中,用于备份。
它是令人惊异的,因为你 可以存储140兆字节
这个特定的磁盘。
这是高密度版本, 所指示的HD,其中有
这意味着之前今天的高清视频。
>> 标准密度为800千字节。
而在这之前,有 400千字节的磁盘。
而在这之前,共有5和1/4 英寸磁盘,这是真正的软盘,
和一点点更宽,更高 比这里这些事。
但实际上你可以看到所谓的 这些磁盘的软盘方面。
>> 和功能,它们实际上是 非常相似,在硬盘驱动器
至少这种类型。
同样,固态硬盘在新电脑 工作方式略有不同。
但是,如果你移动,小金属卡, 实际上,你可以看到一个小的cookie,
或拼盘。
>> 它不是像这样的金属。
其实这其中的一些便宜 塑料材料制成。
你可以摆动它的那种。
你trully只是抹去一些 位或磁性颗粒的数量
从该磁盘。
>> 令人欣慰的是,它没有什么。
如果这件事情的方式 - 并覆盖 你的眼睛和你的邻居 -
你可以只是一种拉 整个鞘关闭这样的。
但是,有一个小弹簧,所以 知道你的眼睛。
所以,现在你有一个真正的软盘。
>> 什么显着 在尽可能多的是,因为这是一个
一个更大的小规模的代表性 硬盘驱动器,这些东西都是超,
超级简单的。
如果你捏它的底部,现在 该金属的东西,和剥离
他们打开,有两件 感到,并且所谓的软盘
一块金属在里面。
>> 并有去一半 我的磁盘的内容。
去他们的另一半。
但是这一切,里面纺纱 您的计算机在昔日。
>> 再次,把这种成角度, 有多大你的大部分
硬盘驱动器,这些天?
500千兆字节,TB级,也许在 一台台式电脑,3,2 TB的
TB级,4 TB的,对不对?
这是一个兆字节,或采取 甚至不能符合一个典型的MP3
这些天了,还是有些 类似的音乐文件。
>> 有那么一点点的纪念品今天为你, 也能帮助处境是什么
我们将采取理所当然的 现在的问题设置5个。
所以,那些是你的保持。
因此,让我这里将成为过渡 花下的pset。
所以我们现在已经设置这个页面 - 哦, 一对夫妇很快公布。
>> 本星期五,如果您想加入CS50 吃午饭,去平常的地方,
cs50.net/rsvp。
最终项目 -
所以每教学大纲,我们已经发布了 项目最终规范已经。
要认识到,这并不意味着 这是由于特别快。
它的贴吧,真的,只是为了得到 你们想着它。
果然,有一个超级显著 将解决你的百分比
最终项目的材料,我们 甚至还没有得到在课堂上,
但下周初。
>> 但请注意,该规范要求 几个不同的组件的
最终的项目。
第一,在几个星期内,是一种 建议前期,很随意的电子邮件
你的TF告诉他,或者你在做什么 想为您的项目,
没有承诺。
建议将您的特定 的承诺,他说,在这里,这是什么
我想为我的项目做。
你觉得呢?
太大?
太小?
是管理?
你可以看到更多的细节。规范
>> 几个星期后,状态 报告,这是一个类似的
休闲电子邮件到TF说多么 不甘落后,你在你的最终
项目的实施,其次是 CS50 Hackathon大家
被邀请,这将是一个事件 下午8:00至7:00一个晚上
AM第二天早晨。
比萨,因为我可能会提到周 为零,将担任下午9:00,
中国食品在凌晨1:00。
而如果你还醒着上午5:00, 我们带你去IHOP早餐。
>> 因此,黑客马拉松是其中一个比较 类中的难忘的经历。
然后执行由于 然后高潮CS50展。
在所有这些的更多细节 在今后几个星期。
>> 但是,让我们回去的东西 旧学校 -
再次,一个数组。
所以数组是不错的,因为它解决 的问题,像我们看到的只是一个
刚才学生结构 开始有点失控,如果我们
希望有学生,学生, 学生点点点三,学生,
一些任意数量的学生。
>> 所以阵列,几个星期前,猛扑 并解决我们的问题不
事先知道有多少东西 某种类型的,我们想要的。
我们已经看到,结构可以帮助我们 进一步组织我们的代码,并保持
概念类似的变量,就像一个 名称和房子一起,使我们
可以把它们当作一个实体,里面 其中有小块。
>> 但是,阵列具有一些缺点。
的一些缺点是什么 我们遇到
阵列,从而有多远?
那是什么?
固定大小 - 所以即使你可能 能够分配内存的
阵列,一旦你知道有多少学生 你有,你有多少个字符
从用户,一旦你分配 数组,你样的画
自己陷入了困境。
>> 因为你不能插入新元素 到一个数组中。
您不能插入更多的元素 在结束一个数组。
真的,你不得不求助于创造一个 全新的数组,如我们已经讨论了,
复制旧到新。
再次,这是头痛 则由GetString引发为您处理。
>> 不过,你不能甚至插入 成的中间的数组的东西
如果利率没有被完全填充。
例如,如果该数组的大小 六只有五件事情,
好了,你可能只是粘 到年底的东西。
但是,如果你要插入的东西 到中间的
阵列,即使它可能有 五六个的东西在里面?
>> 哦,那我们做的时候,我们都 我们人类志愿者在舞台上
周过去?
如果我们希望把这里有人,无论是 这些人该如何移动
的方式,还是这些人该如何移动 方式,并且变得昂贵了。
里面的人转移 阵列加起来和成本
我们的时间,因此我们很多ñ平方 运行时间,如插入排序,
例如,在最坏的情况下。
所以数组是伟大的,但你必须 提前知道你希望他们有多大。
>> 这样就OK了,这里是一个解决方案。
如果我事先不知道多少 我可能有学生,而且我知道,一旦
不过,我决定,我坚持与 许多学生,为什么不我只是一直
分配两倍的空间 因为我可能认为我需要什么?
那是不是一个合理的解决方案吗?
>> 实际上,我不认为我们 将需要超过50个插槽
阵列中的一个中等大小的类, 因此让刚刚围捕。
我会让我的数组,只需100插槽 这样我们就可以肯定得到
我期望的学生数 在一些中等大小的类。
那么为什么不围捕和分配 更多的记忆体,典型地,一个数组
比你想象的,你甚至可能需要?
这是什么简单的推托 这个想法?
>> 你只是浪费内存。
从字面上看你写的每一个程序,然后 也许使用两倍的内存
你的实际需要。
而这只是不觉得自己像一个 特别是优雅的解决方案。
此外,它只是降低了 出问题的概率。
如果你碰巧有一个流行的课程 一个学期,你有101
学生,你的程序仍然是 从根本上面临着同样的问题。
>> 令人欣慰的是,有一个解决方案, 这个广告的形式我们所有的问题
的数据结构的 之外的更复杂的
到目前为止,我们已经看到了。
,我要求,这是一个链表。
这是一个数字列表 -
9,17,22,26,34 -
已连在一起的方式 什么,我画箭头。
>> 换句话说,如果我想代表 我可以做一个数组,
这样的事情。
我就把这个开销 在短短的时刻。
我可以做的 -
你好,所有的权利。
待机。
在这里,新的计算机明确 -
所有权利。
>> 所以,如果我有这些数字阵列 -
9,17,22,26,24 -
未必按比例绘制。
所有的权利,所以这里是我的数组 -
噢,我的上帝。
所有的权利,所以这里是我的数组。
哦,我的上帝。
>> [笑]
>> 国宝马兰:假装。
这是太多精力回去 解决这个问题,所以有 -
26。
因此,我们有这阵 9,17,22,26,和34。
对于那些你可以看到 令人尴尬的错误,我只是做了
它是。
>> 因此,我要求这是一个 非常有效的解决方案。
我分配尽可能多的int类型, 我需要 - 一,二,三,
四,五,六 -
然后我存储的数字 这个数组里面。
但是,假设,然后,我要插入 8号这样的值?
那么,它在哪里去了?
假设我想插入 20这样的数字。
那么,它在哪里去了?
某处有在中间, 或数字35去
某处在年底。
但我所有的空间。
>> 所以这是一个根本性的挑战 的阵列,它的解决方案。
刚才我声称是,GetString 解决了这个问题。
如果你想插入第六号 进入此阵列,什么是至少一种
解决方案,您可以依傍的肯定, 就像我们做的GetString?
那是什么?
>> 嗯,使其更大 说起来容易做起来难。
我们不一定可以使数组 大,但我们能做些什么呢?
创建一个新的更大的数组,大小 6,或者大小为10,如果我们想要
出人头地的东西,然后复制 旧到新的数组,然后
释放旧的阵列。
>> 但是,什么是运行时间 现在这一进程?
大O n的,因为复制 要花费你一些单位
时间,所以不是那么理想,如果我们有 分配一个新的数组,这是怎么回事
消耗的两倍多 暂时记忆。
复制旧到新的 -
我的意思是,它只是头痛, 再次,我们为什么写
则由GetString引发你。
>> 所以我们可能会做什么呢?
那么,如果我们的数据结构 实际上有差距?
假设我的目标是让我放松 连续的内存块,其中9
至17日,这是旁边 旁边22,依此类推。
>> 假设9可以在这里 RAM,17能在RAM中,在这里
22可以在这里,在RAM中。
换句话说,我并不需要他们 甚至背靠背了。
我只是必须以某种方式穿针 通过每个这些数字,或每个
这些节点,我们称之为 我画的矩形,
记得怎么到最后 从第一个这样的节点。
>> 那么,什么是编程构造 我们最近见过不少与我
可以实现,线程,或者 吸引到这里,我可以
实现这些箭头?
所以指针,对不对?
如果我不只是一个分配 int,但是一个节点 - 和
节点,我的意思只是容器。
和视觉,我的意思是一个矩形。
所以一个节点显然需要 包含两个值 -
的int本身,然后,如所暗示的 矩形的下半部分,
类型为int的足够的空间。
>> 所以只是想提前在这里, 有多大,这是节点,这
容器中的问题?
多少字节的整数?
大概4,如果是 一样平常。
那么有多少字节 指针?
4。
所以这个容器中,或此节点 将是一个8字节的结构。
哦,这是一个令人高兴的巧合, 我们刚刚推出这个概念
一个结构或C结构。
>> 所以我要求,我要采取的一个步骤 朝着这个更复杂
实施数字的列表, 链表的数字,我需要做一个
多思考一点前面 声明不只是一个int,但结构
我会打电话的,传统 在这里,节点。
我们可以把它称为我们想要的东西,但 节点将是在一个特定的主题
的事情,我们现在开始寻找。
>> 该节点的内部是一个INT N。
那么这个语法,一点点 怪异的第一眼 -
结构节点*。
形象好了,那是什么?
这是下半部分的 我们看到的矩形
刚才。
>> 但是为什么我说结构节点* 而不是只是节点*?
因为如果指针指向 在另一个节点时,它只是
一个节点的地址。
这是符合我们什么 关于指针讨论迄今。
但是,为什么,如果我要求这个结构 称为节点,我不得不说结构
内部节点这里?
>> 没错。
这是一个愚蠢的现实C. typedef的,可以这么说,有没有
尚未发生。
C的超级字面。
它读取你的代码顶级 底部,从左到右。
直到它击中,分号 底线,你猜怎么着不
作为数据类型存在?
节点,报价引文结束节点的。
>> 但由于更详细 声明,我做的第一行 -
的typedef struct节点的 -
因为来之前,首先 大括号,有点像
前教育锵,你 知道吗,给我一个struct
所谓结构节点。
坦率地说,我不喜欢调用的东西 结构节点,结构节点
在我的代码。
但我会只使用一次,只是里面, 让我能有效地
创建一个循环引用,而不是 一个指针,指向自己本身,而是一种
另一个指针 属于同一类型。
>> 所以,事实证明,一个数据结构 这样,有几
操作,可能会对 我们感兴趣的。
我们可能要插入 进入这样的名单。
我们可能想要删除 从这样的名单。
我们可能要搜索一个列表 值,或者更普遍的是,遍历。
和横向只是一个奇特的方式 说你应该开始在左侧和移动全部
的方式的权利。
>> 通知,即使有这样的稍多 复杂的数据结构,让
我建议,我们可以借用一些 在过去两个星期的思想和
执行一个函数调用 搜索这个样子。
这将返回true或 false,表示yes或
不中,n为在列表中。
它的第二个参数是一个指针 列表本身,所以
到一个节点的指针。
>> 我要那么做是申报 一个临时变量。
我们叫它PTR按照惯例, 指针。
我给它等于 开始的名单。
>> 现在注意到while循环。
只要指针不等于 空,我要来检查。
指针箭头n等于 中传递的n?
并等待一分钟 - 新 一块语法。
什么是箭头一下子?
是吗?
>> 没错。
因此,而在几分钟前,我们使用 点符号访问一些东西
内部的一个结构中,如果变量 你是不是该结构
本身,而是指向结构的指针, 令人欣慰的是,一块语法
终于使得直观的感觉。
箭头指按照指针, 像我们的箭通常意味着
形象,并去 数据字段内。
所以箭头是点,但同样的事情 你使用它的时候,你有一个指针。
>> 因此,只要回顾一下,然后,如果n场 里面的结构称为指针
等于等于N,则返回true。
否则,这条线的位置 - 指针 等于指针。
所以,这是什么做的,通知,如果我 我目前指向的结构
含有9,和9的不数 我要找的 - 假设我要找
n等于50 -
我要更新我的临时指针 在这个节点不指向
了,但指针旁边的箭头, 正打算把我在这里。
>> 现在,我意识到是旋风 的介绍。
上周三,我们将真正做到这一点 用一些人类和一些较
代码以较慢的速度。
但要意识到,我们现在正在做我们的数据 更复杂的结构,使我们的
算法可以得到更高效, 将是必要条件
pset中六,当我们加载,再次,那些 15万字,但需要这样做
高效,理想的情况下,创建一个 我们的用户不是在运行的程序
线性的,而不是在n的平方,但在 恒定的时间,在理想。
>> 上周三,我们会看到你。
>> 演讲嘉宾:在未来CS50大卫 忘记了他的基本情况。
>> 国宝马兰:这就是你如何发送 短信与C -
>> [各种短信 通知的声音]