[Powered by Google Translate] [第4周，续]
[戴维·J·马兰 - 哈佛大学]
[这是CS50。 - CS50.TV]
>> 这是CS50，这是结束4周。
因此，一些好消息和一些坏消息。
星期一不上课，没有问题设置下周，。 [学生欢呼]
你不会喜欢，这是怎么回事。
但是，我们确实有这个，而不是下周三，
也按照教学大纲周五演讲下周五，这样我们就可以留在赛道上。
但是，一切都将被拍摄下来，像往常一样，所以不用担心。
>> 而对于测验0朝周的结束，我们会做什么
发布课程的网页cs50.net解释
你应该有什么样的期望时，它的第一次测验。
在一般情况下，这将是多项选择题，是非，简答题，短的编码问题。
你不会被预计实现相当于
的问题上，你会看到一个pset中，你有一台电脑
和调试器之类的，但会有小的编码问题。
>> 事实上，得到了CS50测验感的最佳指南是像
就是到cs50.net去，去测验链接，
你可以看到价值在过去几年的测验。
只是实现课程并不总是相同多年来。
有时候，我们增加，有时相减，
所以如果你看到一些话题之一，那些老测验
你不知道它在说什么，这是，我们没有覆盖
或者，我们并没有覆盖它。
但是，评论的形式，这个星期天，星期一和星期二
以及在周日晚上的课程广泛的审查会议 -
课程的网页上公布的时间和地点 -
你有机会检讨课程的教学研究员
今年，无论是在材料部分，作为一个完整的类，
和那些将被拍摄下来，像往常一样。
>> 好的。因此，事不宜迟，评论通过/失败，并添加/删除。
您可能已经看到我的笔记昨晚，这真的只是一些额外的放心
如果你是在那些特别不舒服的，或介于两者之间
和你的感觉只是一点点在你的头上，
实现这确实是很正常的，并有充足的支撑结构，
其中之一办公时间为每提高我的电子邮件昨晚的意图，
实现过类似的选项通过/失败的一类这样的
真的是作为一种机制，采取边关闭的这样一个过程，
因此，再次，如果你花这10个，15个，20个小时
只是想获得一些pset的工作，你知道你的方式有90％-95％
但你不能找到一些该死错误，在一通/失败的排序模型，没关系。
>> 我们的想法是，该机制可以去专注于其他pset
或睡眠，不管它是什么，你要专注于。
所以知道你有，直到下星期二 - 技术上，5日（星期一），
但它是一个节日，所以这下星期二 - 切换合格/不合格分级或反之亦然。
而且，如果你真的在绝壁上，并考虑丢弃完全，
请抓住我讲课后，我。
我们很乐意向你告别之前，至少聊天。
好的。因此，我们开始考虑关闭最后一次训练车轮。
特别是，我们专注于字符串。
String是宣布的CS50库中的东西的，
特别是在该称为cs50.h的文件，我们将在本周和下周开始寻找。
但是，字符串是真的只是一个简化的东西
这是一个有点更arcanely为char *。
CHAR我们熟悉的。这只是一个单一的字符。
*截至周一表示什么？ >> [学生]的指针。
一个指针。什么是指针吗？ >> [学生]的地址。
>> 这就像一个地址，一个在内存中的位置。
什么是地址或位置，或记忆体？
同样，我们所有的人都有笔记本电脑的演出或2 GB的RAM，最有可能的，这些天，
这意味着你有一个亿或2亿字节值得的内存。
它并不真正的问题是什么身体看起来像，
但要信你可以列出所有的单个字节，自己的笔记本电脑 -
这是0字节，这是第1个字节，这是第2个字节亿 -
而这正是一台电脑做什么。
例如，当您分配的单个字符的空间，
在您的计算机的内存中显然有地方住，
也许是在字节数12345，
这就是这里的某个地方在您的计算机的内存中。
该字符的地址，然后是12345。
>> 现在，在0周，通过现在到目前为止，我们还没有真正关心
在那里存储在内存中的东西，因为我们通常使用的符号，
变量和数组其实在我们的数据。
但是，星期一，今天，你将有
更表达能力编写程序
要真正操纵一台计算机的内存，您认为合适的，
既有良好的目的和坏的，
错误在学习这东西在这一点上是一种很常见的结果。
但什么是它真正的意思，是一个char *？
让继续回到 - 和所承诺的今天，我们会回来Binky。
让我们到这里一个简单的例子。
让我保存这个文件为compare.c，让我在这里得到一些模板代码
所以包括stdio.h中，让我也给自己包括cs50.h.我会在有放大。
让我开始写主要的诠释，主要（无效），现在我想要做这样的事情：
printf（“请给我一个字符串：”），然后我会使用字符串s中得到的getString
从用户得到一个字符串，那么我要问另一个用户。
（“给我另一个字符串：”）和我通过GetString来，我要问他们。
我会打电话给它吨，因为T后，S和S为一个字符串，如果是一个好听的名字，这是非常普通的。
GetString的，现在我只想要做完整性检查，我要去说
（== T），然后我只是要告诉用户输出（“你输入同样的事情！\ n”）;
否则，我要打印出来的东西（如“您所键入的不同的东西！\ n”）
或其他的句子。因此，类似的东西。
然后，像往常一样，我会回来0这标志着没有什么糟糕的事情发生，
我要继续前进，编译并运行这个程序。
>> 但在周一，我们运行这个程序，
实际上是说，HELLO你好和再见不再见。
的行为，我们看到的是一个有点像。
让我进入我的源目录，在这里变焦，并让我们做作出比较。
编译没问题。让我跑了比较。给我一个字符串：HELLO。
给我另一个字符串：HELLO。
您输入不同的东西！
好了，让我试试简单的像50，50。您输入不同的东西！
嗨，嗨。所以很明显，这是怎么回事。
但究竟是什么理由来解释为什么？
显然，12号线是完全不正常的。
这里的根本问题是什么？是啊。 >> [学生]的地址进行比较。
是的，没错。它实际上是比较地址
HELLO和HELLO存储。
这不是比较的字母HELLO一遍又一遍，
因为什么是真正发生的事情，这段时间我们一直在使用GetString -
黑板又是我们电脑的内存，
让我们说我调用GetString后声明一个变量s。
我的记忆是什么样子呢？
让我们武断地说，，长相像这样。这是一个正方形。
和几乎所有的时间在屏幕上，我画的一块内存
如果是32位我已经画广场这样的，因为确实在家电，
一个指针，一个地址，为32位。这是一个int一样。
这可以根据计算机系统的不同而有所差异。
你们谁是与你的Mac或PC是64位的事实​​，依稀熟悉，
实际上代表您的电脑使用的是64位指针，
64位地址，并跻身有利的一面，那是你的电脑
可以有更多的RAM比昔日。
长话短说，早在一天当计算机只使用32位
表示地址的最大字节数，你可以代表
在这种情况下，如果你有32位吗？
所以4亿美元，正确的，因为2到32是4亿美元。
这个数字已再次发生的过程。
>> 所以，如果你只有32位，你可以数到的最高数量是大约4亿美元。
但是，这是一个基本的限制，直到几年前的电脑
因为如果你只能算作高为4亿美元，
不要紧，如果你买了8 GB的RAM，甚至5千兆字节的RAM;
你不能指望那么高，所以它是无用的。
您只能访问您的计算机的内存中的第3或4 GB的。
这不再是一个问题了，你可以买的MacBook Pros笔记本电脑和戴尔
8 GB的RAM，甚至更多，这些天。
但是，如果我分配在这个程序很简单指针，指针，
它可能看起来像在屏幕上，因为我们确实需要剥开这层。
我一直在说的字符串，但截至周一，字符串是真正的char *，
一些字符的地址。
因此，让我们的训练轮中断，即使现在我们将继续使用GetString。
所以，我宣布，这是一个内存块，32位。
在这里，默认情况下，在内存中吗？ >> [听不见的学生反应]
那是什么？ >> [学生]垃圾。 >>垃圾。没错。
如果你的程序员不把一个变量的值，谁知道它是什么呢？
有时你会得到幸运的，它是0，这是怎么样的一个不错的，干净的默认值，
但正如我们所看到周一，有时完全是一派胡言，
一些非常大的正数或负数，从哪儿来？
是啊。 >> [学生]的功能。 >>呀。
>> 通常情况下，被调用的函数，因为以前记得，
当你调用函数在内存中，他们采取了越来越多的空间从下往上，
尽快函数返回时，那段记忆得到重用
，被称为未来的家伙，谁在使用相同的内存片。
如果你已经离开垃圾在那里，以前的值，
我们可能会误以为S作为有一定的价值时，我们真的不把任何东西存在。
因此，我们在这一点上看起来是这样的RAM。
现在的右手边的第7行，我们调用GetString时，
我们现在做了几个星期，但真的这样做是GetString的吗？
GetString的是一个有点聪明的的CS50人员的书面
，只要用户开始输入密钥，点击输入，
GetString的数字用户按下了多少按键，
我需要多少个字符分配RAM。
，RAM，谁知道？
这是在您的计算机上的2千兆字节的内存或诸如此类的东西的地方。
但是，让我们假设计算机空间的单词HELLO。
我输入的字是H-E-L-L-O。
如果我们得出这样的字符序列，我们可以绘制它是这样的。
不过，我需要做额外的事情。结束时的任何字符串在C属于什么？
空字符，这是我们写的\ 0。
这是技术上的数字0，，但反斜线使更清晰
这是字面上的编号为0，整数0;
它不是，例如，报价引文结束，你可能会在键盘上键入0。
因此，这是HELLO。
>> 了什么，我们在周一，类似的函数的GetString
实际上返回所有这几个星期呢？
这不是返回一个字符串，因为这本身并没有真正的意思
因为字符串不存在。他们的一个制造的CS50库的排序。
什么是真正的字符串，技术上呢？ >> [学生]这是第一个字符。
没错。这是很简单的第一个字符的地址，用户输入的字词。
所以，如果我的话HELLO结束的时候，人们的字节数123，然后在字节数124，
125，126，等等，如果我只是我从0字节数就到了，
真正的GetString返回简直是数字123。
那么，什么被在s号为123，而不是字母H，而不是这个词HELLO，
很简单的地址，我能找到的第一个字母HELLO。
但是，这似乎并不像足了。我问你一个字符串，而不是一个字符。
那么，如何才能或计算机知道ELLO种以及H？
我们有什么样的协议？是啊。
[学生]不断告诉自己找到一些更多的字符。 “没错。
>> 这种人机惯例，即当你处理字符串，
否则现在已知为char明星，你只需要找出
在生活中的每一个字符串的结束是真的只是一个for循环迭代，
一个while循环，什么的，所以，当你找到的字符串的结尾
哦，现在你可以推断出，整个单词HELLO。
这些与以前的编程经验，你可能知道在Java中
你可以调用。长和在其他语言中，你可以调用长度或类似的。
这是因为，在很多​​语言中，特别是被称为面向对象的语言，
长的东西是种的一块封装在数据本身，
就像我们封装的ID和姓名，房屋内的学生周一。
但是，C是低得多的水平。有没有对象或类的，如果你听说过这些术语。
你真的是内存地址。
因此，这是一种老式的方法较有趣的数据结构。
你有一个开始的第一个字符的地址值，如
，然后就一些任意的约定，每个人都同意遵守。
因此，如何实现字符串的长度，我们提出了吗？
STRLEN，STRLEN，你们中的一些现在已经用了几次。这是很简单的，对不对？
这就像两行代码。
这几乎是一个某种形式的for循环，也许有一个额外的局部变量。
但strlen的只是一个指针，然后开始寻找\ 0。
>> 而一旦它发现它，它可以返回总数的步骤，它采取了在该字符串中。
因此，我们可以推断，这是下一个。
假设，然后在第10行，因为我已经做了，我宣布吨。
这是一些垃圾的价值。在第一谁知道？
但在我右手边的10调用的getString再次。
谁知道在哪里结束呢？
让我们武断地说，操作系统搜房的方式在这里。
我正好不约而同地再次键入H-E-L-L-O，
因此，我们可以得出相同类型的图像。
但事实上，我已经重新绘制这幅画是故意的
因为这是一个不同的HELLO超过这一点。
因此，这里，这可能会对位置456，这是457，等等。
那么，什么被放在其中的问号？
在这种情况下，456。
我们选择这些数字随意，因为今天真
我们不会那么在乎任何事物的地址是什么。
我们所关心的是，我们可以计算出地址的某些数据，如HELLO。
>> 所以，真的是大多数人都在谈论的内存地址时，计算机科学
和谈论的指针具体而言，
而不是费心找出123 - 谁在乎这个东西实际上是，
我们只知道它是在一些数字地址 -
我们简化了世界，只是说S是指向该字符
，t为指向这个角色。
而事实上，它是一个箭头是很有意
因为从字面上现在s是指向在H和t指向其他的H
因为在一天结束时，它并没有关系的地址是什么，
但它的问题，我们有一些代码的表达能力，地址。
我们还没有真正操纵这些地址，只是还没有
所以我们会看到，在这里我们可以没错，排序做的事情与指针，
但现在在第12行从字面上我们比较的是什么值
根据这个故事在第12行吗？
我们说的是123，等于等于456？这绝对不是这样的。
甚至在概念上，这个指针肯定是不一样的，因为这
因为你叫GetString的两倍，和GetString不会尝试是超级聪明，
它不会尝试来实现的，哦，你键入HELLO 5分钟前;
让我给你的，因为我以前给你相同的指针，
它只是分配一个新的内存块，每次调用它。
>> 那么，我们如何解决这个问题？
如果需要更高的水平，我想比较字符串HELLO HELLO -
我不关心的指针 - 我该如何去回答这个问题，
用户键入了同样的事情？有什么必要在这里？是啊。
[学生]使用的功能。 >>我可以使用一个函数的开箱即用。
我可以使用一个函数调用strcmp，S-T-R-C-M-P，
只是说字符串比较的缩写形式。
如果我们进入，例如，比较两对，这是在今天的讲义，
我这样做。
我一直下降到26左右，一切从1号线
现在请大家注意，这部分也发生了一点点。
让我们忽略了一会儿，第28行只集中在这一个。
我们说什么（星期一），海峡比较不？
它处理的过程中，在这种情况下，服用2指针，s和t，
排序几乎把手指放在这2个字母，
必须做的是像一个while循环或循环的东西，
，它说，这是相同的吗？如果是这样，将手指或指针向前移动。
这是相同的，这些相同的，这些是相同的，
这是相同的，这是一样的吗？而且哦，我在结尾的字符串s和t。
我还没有发现任何矛盾。是的，这些字符串是相同的。
什么STR比较的回报，如果两个字符串是相同的，显然是吗？零。
所以0是很好的，因为如果在这种情况下，则返回-1或+1，
这意味着，只是发生之前按字母顺序或在t。
为什么会是有用的，它告诉你有一个函数的字符串之前
后，在一本字典吗？
[学生]搜索。 >>搜索和排序。
>> 所以，你可以做的事情，如的二进制搜索或泡沫排序或归并排序
你要比较的东西。
到目前为止，我们已经削减某些角落，只谈到排序
的背景下的数字，因为它是好的和简单的说说，
但你一定可以比较字符串，苹果，香蕉，
因为如果苹果被称为到来之前，香蕉，同样，
你可以将字符串大约在内存中一样罗布与归并排序的视频
我们在这里所做过的舞台上，选择排序，插入排序，冒泡排序。
所以我们可以采取什么地方？让我们来试试这个。
让我们的忘记了一会儿，这个教训，尝试和复制1.C做到以下几点。
我说在第21行打印的东西，
然后我得到了来自用户的字符串，
然后我检查了。
我们还没有真正得到这个习惯，但现在，让我们做到这一点。
实际，让我们剥开这层。这是真正的char *。这家伙是真正的char *。
所以，这是什么意思进行检查，如果S == NULL？
事实证明，当你调用一个函数一样的GetString
或更一般只要求一台电脑给你一些内存，
东西可以去错了。
你可能是疯了，问TB的内存的电脑
问万亿字节的内存，只是不存在于电脑，
但GetString和其他功能的大喊大叫，你需要通过某种方式
如果你问太多。
的GetString这是，如果你要求更多的内存
比在电脑上，即使这是超级，超级的低概率
因为我们要输入一个万字符，然后按下回车键，
但概率很低，尽管它可能是，但我仍然要检查，以防万一，
GetString时，回答等功能，返回的特殊值，
如果出了问题是NULL全部大写。
>> 什么是空？ NULL恰好表示指针。它的内存地址为0。
世界决定意，如果这是我的电脑的内存 - 你知道吗？ -
我们要偷的每一台计算机的内存只有1个字节，这是位置0。
我们要去给它一个昵称为NULL，我们要保证
，我们永远不会真正把真实的数据
因为我们只是任意需要一个特殊的值，又名NULL，0，
因此，我们可以大声喝斥用户，如果出现错误。
否则，你可能不知道0意味着把这里的东西
或它意味着出事了吗？
我们都同意，返回NULL意味着什么，
没有实际地址返回。
现在，在这里我只是通过我的人的惯例，我返回1，从主
如果出现错误。
这是因为主要的回报的约定是返回0，如果好，
或一些其他的值，如果坏。
但是GetString和交易功能，在内存中返回NULL，如果出现坏。
>> 好吧。不幸的是，第27行，超级简单，但它是完全无法复制的字符串。
为什么呢？我们可以看到如下。
我要求在27行s的副本，并呼吁它吨。
所以我不会问用户时间2串;我只是说在s
应在T。
所以，现在只是证明这是多么破碎，第29行起，我在做什么？
首先我检查如果t的长度是大于0的。
有一些字符串。用户输入的东西英寸
第32行，显然是什么？
听不见的学生回应] >>权。您可以推断，从我说的做。
但在技术上，这是什么做的？ T [0]代表什么？
[学生]：第零个字符。 >> [马兰]第零个字符。
或者，更人性化的，在T的第一个字符，不管它是什么，H，也许在这种情况下。
和toupper做什么它说。它利用第零个字符的T和它改变它。
因此，这意味着第零个字符的T，大写，
在相同的位置把它放回去。
所以，如果我键入Hello小写字母，这应该改变小写h资本H.
但问题是，在35和36什么，我做的是打印出我们的s和t。
你的直觉是什么？
我究竟要什么，如果我输入了全部用小写吗？
这是怎么回事，列印吗？ >> [听不见的学生反应]“那是什么？
[学生]：大H，其余小。 >>大H，其余小的，S或T？
[学生]两个。 >>两种。没错。所以，让我们来看看这里发生了什么事情。
>> 让我去和编译。这是COPY1，所以COPY1。好的。
放大，让我继续运行COPY1，输入，想说什么：您好，小写字母。
资本化的副本，但它显然资本化原，
因为现在发生在这个故事吗？
在第27行，其实我不似乎被复制的字符串，
但即使你可能直观地希望的情况下，
如果你仔细想想这张照片，我真正做了什么？
一半的图片是相同的。
因此，让我们回滚的时间，使吨尚不存在的故事。
S可以存在的故事，但让我们小写您好，这时间。
因此，让我解决了我的实际输入数字。
在这种情况下，在这里，我们有H-E-L-L-O。
我们将以此作为一个字符序列，在这里把我的分割线，我的\ 0。
因此，这是我们在哪里，只要1号线24上下的，给予或采取，已执行。
这是我记忆中的画面。
当我到第27行，会发生什么呢？
就像以前一样，我得到一个指针，我会画这个广场。
这就是所谓的T。默认情况下，它的价值？谁知道？一些垃圾的价值。
>> 因此，我将抽象为一个问号。
尽快右手边的第27行执行，我把里面的T？
同样的事情，在s。
因此，如果我们的时刻删除这个抽象的箭头和我们说，
哦，这是内存加载地址123，当你说T得到s，分号，
你从字面上把123在这里。
现在，如果我们种简化我们的世界再次与图片，
你真的做的只是另一个箭头可以使你的世界
从t到指向完全相同的字符串。
所以，当我在31和32号线去改变T [0]，
什么是T [0]显然与现在的代名词吗？ [0]
所以这一切的发生。
即使这种感觉有点低的水平，神秘的
这种感觉就像也许是直观的，这应该只是工作 -
我复制的东西，它只是工作 -
如果你真的觉得什么真的是一个字符串，它是一个char *。
嗯，那是什么？这是一些字符的地址。
然后，也许更有意义，当你尝试做一些事情
超级看似简单的这样，你做的是复制一个内存地址。
你的字符串本身实际上没有做任何事情。
所以，即使你不知道你将如何解决这个问题的代码，
高的水平，从理论上讲，是什么，我们需要做的，以使TA s的真实副本，显然吗？
是啊。 >> [学生]给它一个新的位置吗？ “没错。
>> 我们需要，给T A品牌新的位置。
我们需要以某种方式创造的世界中，我们得到了一个新的内存块，
这只是为清楚起见，我会画右下面这一个，但它并不需要在那里。
但它需要是相同的大小，所以在同一个地方，我给你画这些垂直线。
这是罚款，如果最初全部是垃圾。谁知道是什么吗？
第1步将有尽可能多的内存给我，因为我需要
适合的副本招呼，然后找出如何复制的H这里，这里的电子，
升这里，等等。
但是，这已经觉得有点明显，即使一些细节仍是抽象的。
这个字符串复制到这一点，它只是一个for循环或while循环
你变得更熟悉的东西。
所以，让我们来试试这个。让我进入copy2.c。
在copy2.c我们具有几乎相同的程序，除了第27行。
它看起来有点复杂，但如果我们把它分解一块一块的，
的左手侧是相同的。
字符* T在内存中创建了这件事情，但一个问号
因为我们不知道什么是有默认。
在右手边，我们现在引入一个新的函数malloc的，
内存分配的，给我的记忆，
它显然需要多少个参数，括号里面的东西有多少？
我听到怨言，1和2，但它仅仅是1。
有没有逗号，这意味着仅有1括号内的事情。
即使有其他括号，我要强调
最外层的括号里面是什么，它​​是这个表达式：
（strlen的（）+ 1）* sizeof（char）的的。
因此，如果我们真的该好好想一想，这是说给我s的长度。
我为什么，虽然，加1到的长度？ >> [听不见的学生反应]
没错。我们需要空间，这家伙的尾巴，有没有英文的意思第六个字符
但确实有特殊的纲领性意义。
>> 所以我们需要一个+ 1，因为人意料的strlen返回的长度，
打招呼或5，它不给你额外的空字符。
所以，我手动添加+ 1。
然后这个，*大小（字符），我们还没有看到这样的情况。
这不是技术上的功能。
这是一个特殊的关键字，它只是告诉你的计算机上的某些数据类型的大小是
因为在现实中，我们中的一些人有32位计算机。
我有一个很老的电脑在家里，它仅使用32位来表示指针。
所以，如果我做的数据类型的大小，它可能是32位。
但是，如果我用我的新奇特的电脑，我可能会得到64位值
类似地址。
因此，在这种情况下，仅仅是超级安全，我们不打算到硬编码类似的东西 -
那么，究竟是根据什么说了这么远的一个字符的大小吗？
我们已经差不多口头上说是1个字节，这几乎是全线。
但同样，假设往往是坏的。
他们导致bug的软件，如果人们使用软件的方式，你不打算。
因此，让我们的抽象之遥，只是更一般的说
我需要很多的内存块
并且每个块的存储器应该是相当于一个字符的大小，
这是在实际上等于在此情况下为1，但它是一个更通用的方法将其写入。
因此，如果这个词是个招呼，多少字节的malloc显然是分配给你好呢？
[学生]六。 “六。正如很多，因为我们有问号在屏幕上。
然后采取的猜测现在根据你的理解的GetString
可能是什么的malloc返回？ >> [学生]的地址。
地址是什么？第一块内存。
>> 我们不知道那里有什么，因为其他一些功能
已使用内存之前。
但malloc的，喜欢的GetString，返回地址的第一个字节的内存
它已经为你留。
然而，它不会做一个反斜杠空字符填补这个空白
因为事实证明，你可以使用malloc分配的任何整数，字符串，数组，
花车，学生结构。
您可以使用malloc完全通用。
它不关心或者知道你分配内存。
因此，这将是放肆的malloc把\ 0
在每一个内存块，它给你
因为\ 0的字符串的事情仅仅是一个惯例。
它不使用int类型，它不使用的花车，它不是供学生使用。
这样一来，用malloc是疑难杂症的负担是完全在你的程序员
记得多少字节分配，而不是以往任何时候都使用一个for循环
或while循环的边界的内存块，你已经走过去。
换句话说，只要你分配内存，
你不能要求操作系统，哦，顺便说一下，有多大的内存块是这样的吗？
这完全取决于你要记住，如果你需要的值。
>> 因此，让我们来看看如何我继续使用该内存。
在28和29号线，我为什么这样做呢？
只是总的仔细检查。
以防万一出事了，我问一些疯狂的内存量
或我有这么多的事情在计算机上运行，​​根本就没有足够的内存，
那样的话，我至少要检查是否为NULL。
在现实中，大多数计算机给你的幻觉，每一个程序
可以使用全部的RAM，
但即便如此，如果用户在一些疯狂的长字符串，也许是因为他们是一个坏家伙
他们实际上是想你的程序崩溃或攻入，
你至少要检查返回值的malloc和是否等于null。
如果是这样，就让我们现在退出，因为我不知道该怎么做，在这种情况下，。
如何复制的字符串？有一些方法来做到这一点。
有STR功能在C复制，但它是超级简单的，我们能够做到这一点，老式的方法。
>> 首先，让我弄清楚什么s的长度。
我可以把这个循环中的，但我只是把它在这里为清晰。
所以N存储原始字符串的长度，这显然是5。
然后在我的for循环，我迭代从0到n，
在每次迭代我把[]内为t [I]。
所以，这就是我暗示，我的手指在琴弦前。
由于for循环遍历这个样子，我要被复制h进这里，
E到这儿的时候，到这里，因为这是，这是T。
那么最后，在第35行，为什么我这样做吗？
我需要确保我结束的字符串t。
我这样做，是这样是超级明确的。
但提出，一个人，如果你能这样做，以不同的方式。
我并不真的需要35行。有另一种方式来做到这一点。
是啊。 >> [听不见的学生反应] >>说它响亮。
[学生]小于或等于。 “没错。
我们只能说小于或等于n，它一直不好一般
因为我们几乎总是等于我们要计算的东西
我们去太远。
但请记住，我们多少字节分配？
我们分配的strlen的S，5 + 1共6个。
因此，在这种情况下，我们可以做这样的事情
这样我们就复制不只是打招呼，但在“\ 0”在最后。
另外，我们可以使用一个功能称为STR副本，STRCPY，
但不会是几乎一样多的乐趣。
但是，这是它的引擎盖下方。
最后，我们像以前一样做同样的事情。
我利用T然后我要求原来看起来像这样的副本看起来像。
因此，让我们试试这个。让我在这里。请COPY2。我们会放大在，并运行COPY2。
我要输入小写字母，而事实上我得到小写的原始
但资本你好的副本。
但我没有这样做，只是还没有。我要在这里做最后一件事。
46和47显然是释放内存，但是，实际上是什么意思呢？
我在做什么，你认为，通过调用第46行和第47行吗？
什么样的影响？是啊。
[听不见的学生回应] >>没错。
>> ，你只是告诉操作系统，嘿嘿，这个内存。
现在，您可以用它给别人。
这里是一个很好的例子，垃圾值。
我刚才用这个记忆写下来的单词hello在2个地方，
这里，这里，这里，和这里。
因此，这是H-E-L-L-O-\ 0。
但后来我打电话第​​46行和第47行，你知道会发生什么的图片吗？
其实，等待，这张照片是旧的。
一旦我们的副本，这家伙居然指指点点，
让我们删除的数字，只是抽象掉，因为我们的箭再次。
这幅画中会发生什么，当我打电话免费？
[听不见的学生响应>>甚至没有。
如果我打电话s和t - 样的一个棘手的问题 - 这幅画不改变
因为调用s，并呼吁只是告诉操作系统，
哎，你可以使用此内存，但它并没有改变为null
或一些特殊的字符，它不改变这一点，
它不改变H或E或L或升或o在别的任何地方。
的图片，只要你通话完全免费，没有任何变化。
，这其中就有原产地的垃圾值，因为如果我再在这个程序
要求更多的内存GetString或malloc或类似的操作系统，
和操作系统的说，当然，我有12个字节的内存刚刚释放，
使用这些方法，你有什么要交吗？
你要交给一个内存块，我们通常会画
带问号的，但这些问号是什么？
他们正好是H-E-L-L-O，H-E-L-L-O。
这是我们的新的垃圾值，只要你释放该内存。
>> 这里也有一个现实世界的含义。
这恰好与RAM，但您的计算机
其实做同样的事情磁盘。
我们再谈谈，特别是与未来的问题集中在取证集。
但到底发生了什么，如果你有一些敏感的财务文件在您的桌面上
或一些粗略的JPEG和将其拖动到您的垃圾，
当你把它拖到垃圾桶或回收站时，会发生什么情况？
你知道我在说什么。 [笑声]
当你的证据拖动到回收站或垃圾桶，会发生什么情况？
[听不见的学生反应]
好了，所以小心。当你这样做，会发生什么情况？
简短的答案是什么，对不对？
粗略的或敏感的文件仍然只是坐在那里，在您的硬盘驱动器上的某个地方。
我们大多数人至少已经了解到硬盘的方式，你需要清空你的回收站
或回收站删除的文件。
事实上，当你右键点击或控制单击您的垃圾
或选择“文件”，“清空废纸篓”或任何
你实际上是空的垃圾桶或回收站，到底发生了什么，然后把这张照片吗？
更多的什么都没有。所以没有什么实际发生的磁盘上。
>> 如果我们仅仅是暂时偏离和写 - 我会使用后面的。
所以，现在的故事正在发生变化，从RAM，这是程序存在
而你在运行当中，磁盘，这是他们长期存储
即使在电源熄灭，现在 - 而且在未来，我们会回来的这 -
让我们假装这代表您的计算机硬盘驱动器内
因为在这一天，他们曾经是圆盘，就像软盘。
所以，如果你有一些敏感的Excel文件，它可能需要此内存块的
您的计算机的磁盘上，我只是画相同的任意1s和0s。
当您拖动文件，这样您的垃圾回收站，
从字面上没有任何反应，因为苹果和微软刚决定
垃圾桶，回收站实际上只是一个临时占位符。
也许最终的OS将它清空你的，但通常情况下，它不会做任何事情，
至少要等到你的空间是非常低的。
>> 然而，当你去清空垃圾箱或清空回收站，
同样，什么也没发生这个画面。
所有这一切发生在您的计算机上的其他地方，有一些类型的表。
这有点像一个小小抄说，让我们的说，resume.doc的，
所以你的简历在Microsoft Word文件，用于住在你的硬盘上的位置123，
在内存中，而不是在RAM，但在您的硬盘，
粗略JPEG住在456，和住在789或是其他地方，您的Excel文件。
当你清空垃圾桶或回收站，删除的文件
这幅画并没有改变。在您的硬盘驱动器上的“0”和“1不要去任何地方。
但这个表，这个小数据库的各种变化。
当你删除你的简历，这是因为虽然在一定程度上被删除的文件，
但所有的电脑没有忘记那件事住在您的硬盘驱动器。
您的简历或任何其他文件的0和1组成仍然完好无损。
>> 所以，如果你这样做是偶然，还是有一个非零的概率
使用Norton Utilities或一些商业软件，你可以恢复你的数据
在生活中，其目的是找到“0”和“1”，有几分被孤立，
被遗忘在这里，但离开这里，这样您就可以得到您的数据备份。
或与警方或联邦调查局的法医调查将采取实际的硬盘驱动器
真正的“0”和“1，看像JPEG文件，看起来像Excel文件的模式，
和恢复，即使电脑已经忘记了他们有他们的方式。
因此，唯一的办法真的要删除数据，我们将讨论在未来，
是进行擦洗或擦拭的文件或硬盘 -
你真的不能摆脱的0和1
否则你会从一个GB的硬盘驱动器
和你最终会与一兆字节的硬盘驱动器，如果你不断地被删除，
从字面上看，“0”和“1。
所以，你会怎么做，如果你真的想掩盖你的行迹
的根本问题仍然是，有0和1的磁盘上的？
我看到有人指手划脚，你会实际打开的设备。这将工作。
[笑]但如果这是一种昂贵的解决方案，你会是更合理？
是啊。 >> [学生]覆盖它们。 >>覆盖他们什么呢？ >> [学生]其他数据。
其他数据。您可以只是简单地覆盖你的磁盘0或1或全0，全1。
>> 这的确是一些软件的作用。
你可以购买软件，甚至获得免费的软件，
甚至建到Mac OS这些天来，因此在Windows，
是能够安全擦除。
其实，如果你想今天所有的跑回家，如果你有一个苹果，这样做，
如果你有一些东西在你的垃圾，你可以做“安全清倒废纸篓”，
这正是这么做的。
而不仅仅是擦除文件，它不会删除“0”和“1，
相反，它只是改变了他们所有的，例如，0，点，点，点。
因此，你的未来的pset实际上是有意恢复数据 -
我们已经采取了在校园内的人，地，事，物的照片，
为此我们做了法医图像的数码相机的存储卡，
这是同样的想法 - 你将面临的挑战是找到
的模式，代表您的硬盘驱动器上的JPEG，
很像以前的学生，他的电子邮件，我读了几个星期前做
恢复他的妹妹的照片。
为什么我们不采取有5分钟的休息时间，和我们会重组与更多的内存。
因此，这里的事情变得有点令人费解，但是这是一个非常强大的步骤
对理解这项工作的。
这里是了一项名为pointers.c。
这是在今天的示例代码。
请注意，在第几行，19至22日，所有我们正在做的是类似的GetString
并返回一个地址，将其存储在s。
今后的pset甚至3，如果你想要的，但pset的4和
在那里你可以开始把这些培训驱动轮离开自己，
没有任何理由假装字符串不存在了。
这当然是好刚开始说的char *。
>> 顺便说一句，在网上参考和书籍，你可能会经常看到旁边的星号的变量。
你甚至可能看到它的左右两侧的空间。
所有这些都是功能上是正确的。
不过，就目前而言，我们将这种方法的标准化，使超清晰
，char *是这样说的字符指针。
这是数据类型。
的名称，然后在这种情况下，该变量为s。
因此，我们已经得到了一个字符串，我们调用它s。
然后在这里发现，其实我做的一点点的挂羊头卖狗肉。
这就是所谓的指针的算术运算，这是超级简单的排序。
这只是意味着增加和减少数字的指针。
但是，这实际上是工作的。
这个方案显然打印字符串的第1个字符，每行这样最终的结果 -
正是这样，我们可以尽情这是怎么回事，使指针，运行指针，让我放大。
现在，让我像HELLO类型输入类型
并打印出每行1个字符。
直至一秒钟前，我们就已经做到了这一点用方括号表示。
我们希望有一个for循环，我们会做的printf的s [i]和我们做一遍又一遍
用反斜杠n在每行末尾。
但这种方案是不同的。这个程序使用，从字面上看，算术。
所以这是怎么回事呢？
首先，这个循环执行之前，是什么，仅仅是明确的，是什么呢？
S是吗？ >> [学生]的地址。 >>地址。
>> 它的地址，在的情况下，你好，这个词的第一个字符，这是H。
因此，s是，在这个特定的例子中，h的地址。
那么，是什么意思做s +我吗？
嗯，我从0开始，在for循环。我们已经做了很多次。
我是要去的字符串的长度，显然。
因此，在此循环的第一次迭代中，i是明显0。
所以这个表达式是说S + I - 而，S +0，显然只需s。
那么，什么是*吗？
现在，我们在一个稍微不同的方式使用明星。
让我继续前进，摆脱对的，因为我们正在谈论t和s的副本。
现在，我们只是想讲一个故事，涉及小号。
因此，在这一刻，后字符串类型的，我们的世界看起来很喜欢它以前
只需s h和存储地址通常指向的字符串你好。
如果我现在做的像一条线*（S + I），让我们尝试了这一点。
所以*（S + I）。让我简化了这一点，因为这是0，所以这是*（+0）。
好了，等待一分钟。进一步简化。这是*（）。
那么，现在的括号是种愚蠢的，所以现在就让我们做*。
因此，在这个循环中，该行突出显示，26的第一次迭代中，
几乎相当于印刷本。
*的数据类型是什么？
在这方面，因为明星恰好是旁边的s本身，
但更特别的是，因为我们不再声明，
我们不创建一个变量了，这里没有提到的char *在第26行，
这里没有提到的关键字串，我们只使用一个变量称为s，
事实证明，现在的明星都有稍微不同的，无可否认，扑朔迷离的意义。
*在这里的意思去做，就这样在s和打印的地址。
所以S是在这里，s是 - 有点像槽和梯子，按照箭头 - 在这里。
因此，这是* S。
>> 那么，什么被印在第一次迭代中，第26行的循环？
我打印出来％，这是一个字符的占位符，
然后一个\ n新行。 *（S + i）其中i为0就是这种。
所以char类型，我将在％C？ H.
在接下来的迭代循环 - 你或许可以看到这是怎么回事 -
明显的下一次迭代i是1，所以这意味着s +1个
，那么现在我需要括号，因为现在的明星需要说
到内存地址+1。
是什么？我们走的时间和说，现在这个箭头是不实际做我们任何好处。
让我们更具体的说，这是存储数量123
此字符串的开始，因为你好，这是地址123，这是124，等等。
因此，在第二次迭代时，我说S +1，这是喜欢说123 +1，
否则为124，所以char类型被印在第二次迭代？
E在内存地址124。
+再次，125，126，127，和这个循环谢天谢地停止之前，我们在这里
因为我使用strlen，以确保我不指望太高。
所以这也是它。
再次，这是就好像我们做了一个星期前。
让我把它写在下面的行，即使我们不希望做两件事。
这是相同的，现在这个。
>> 因此，即使s是一个字符串，因为我们已经调用了几个星期，S是真的一个char *。
因此，如果我们想成为超级肛门，这是很正确的写特定的字符
在第i个位置使用这些数字的地址，这星算，
但坦率地说，这就是这么多的清洁剂。因此，这是不坏的。
没有理由停止在这里做线27，26在功能上是相同的，
它的功能相同的确切原因，我们一直在讨论迄今。
最后，29是良好的做法。
调用free s的，现在你给GetString的给你的内存
这还是因为同样的原因，我提到周一，GetString的几个星期
已经被引入到您的代码中的错误。
你的代码为周有内存泄漏
让你一直问GetString的内存，但你从来没有给它。
而且，我们特意选择了教学法
因为它只是太多认为大约在早期。
但现在我们需要更多的对称性​​。
如果你问电脑的内存，是为getString的情况下，
的malloc的情况一样，显然，
现在，您必须pset的4起，也无任何这样的记忆。
请注意，这是不同的，说廉政n。
你不需要释放，因为你没有调用GetString
你没有调用malloc。
>> 而且，即使你叫调用getInt，因为我们最终会看到，
调用getInt不分配内存给你，因为你可以传递的整数
花车和字符的方式，我们已经做了好几个星期。
字符串，虽然是特殊的，因为实际上他们的串联多个字符。
因此，他们只是不同的字符和浮点和整数等。
但我们会回来的，不久。
任何问题，然后在此开始的指针吗？是啊。
[听不见的学生问题]
啊，非常好的问题。
C实际上为你做的几件事情之一，这是方便，
它计算出你的数据类型的大小是什么
，然后做那种对你的乘积。
中字符的情况下，这是不相关的，因为几乎总是一个char是1个字节，
所以这只是工作。
但为了讨论的方便，如果你在实际打印整数
你试图打印出一些值，指向一个整数，
你同样不会需要做的+ 4 *我只是因为int是4个字节。
指针的算术平均值的C编译器为你做所有的数学。
所有你关心的是点样的人的感觉。是啊。
[学生]如果你声明一个字符串在一个for循环，你必须释放它吗？
这个问题问得好。
>> 如果你声明一个字符串内的循环，你需要释放它吗？
您只需要你GetString或使用malloc分配的可用内存。
所以，如果你只是说类似 - 让我把花括号，所以现在所有的代码都涉及。
如果你做了，尽管是buggily的，像这样的char * T = S，
你不需要免费的T，因为T不涉及任何提及malloc或GetString的。
GetString时，如果通过对比，你这样做，那么，你将需要免费的T。
而事实上，你唯一的机会做到这一点是在这个循环中，对同一问题的范围
我们已经讨论了过去。
否则，你会被分配内存，分配内存，分配内存，
和在程序结束时，因为你以外的该循环，
t不存在的，但你从来没有告诉操作系统
你并不需要的内存了。
不久，pset的4或5，我们将装备你的程序称为Valgrind的，
这是类似的，它是一个神秘的界面得到了一定程度的精神，GDB，
但它的目的是帮助你在生活中。
和Valgrind是一个程序，将在未来搜索你的程序
查找内存泄漏，无论是从GetString或malloc的，
我们将开始使用更因为我们停止使用尽可能多的CS50库。
现在我们终于有几分的词汇和理论模型中的那种精神
解决这个破碎的程序。
>> 因此，在这个破碎的计划内的交换，交换，
但它从来没有真正的工作，主要是因为主要通过在X和Y，召回，
和那些被传入的值，可以这么说。
副本交换。
年底的交换，确实被交换a和b，
x和y，我们讨论（星期一），但当然不在场。
所以我在这里提出的绿色，这其实是这里的解决方案。
而实际上，让我感动我的星星，只是是一致的
，即使再次，功能这并不重要。
在未来几周，我们将解释时，为什么它很重要。
因此，在绿色现在是一个解决方案。
坦率地说，它看起来一大堆混乱的，因为我有所有的这些明星。
让我指出一件事。
最上面一行在这里说* A * B
从根本上做同样的事情，因为它总是。
声明的参数或参数交换，
第一，这是一个int指针，
其中第二个是一个int指针调用b。
在这一点上是新的唯一的事实是，有一个明星。
>> 这是什么意思呢？是不是int，b是一个int。
A是一个int和b的地址的地址是不同的诠释。
在这里，这是我承认C得到混乱。
现在我们使用的是一个明星，但在这种情况下有不同的含义。
因为我们并没有声明函数指针，因为我们是在这里，
在这里，我们提领的东西。
所以，在技术上，在此上下文中的第一，第二，和第三线的内部的交换星级
被解引用运算符，它只是意味着去那里。
因此，正如我的手指跟着箭头为h，
*的手段去该地址，找到我的int类型的存在。
* B表示的地址和那里的东西递给我。
因此，让我们重新绘制的图片（星期一）现在使用的栈帧，
其中一个的底部将是主要，
上其中之一将是交换，
所以，我们的世界看起来，就像周一，是这样的。
这里是一大块的内存，主要是要使用。
>> 回想一下，该计划有2个变量，
一个叫x和一个称为y，我已经把数字1和2，。
现在，当我打电话交换一样，我（星期一）
以前我用的是红色版本的这个程序时，它看起来像这样，
我有2个参数，a和b，并没有写在这里和这里？
仅有1和2中，x和y的字面复制。
今天，我们改变这种状况。
今天，而不是传递int类型A和B，我们要通过2个地址。
这些地址正好为整数，但这些地址不是整数。
他们的地址。它像是一个邮寄地址。
所以，现在我们需要的只是给自己多一点细节在屏幕上。
这是我的电脑的内存，因为它整天。
现在，我们需要一些任意的编号方案。
因此，让我们说，只是偶然，这是内存地址123，124。
让我们只说这是125，这是126，等等，但那是完全任意的。
我们只是需要一些在我的记忆中编号方案。
所以，现在当我通过在X和Y，我不打算通过在X和Y;
我要通过邮政地址，可以这么说，x和y的
从而使被存储在这里和这里是1和2，
但如果你能看到我的小文本，通过在这里和这里得到什么？
[听不见的学生回应] >>没错。 123被放在这里，和124被放在这里。
>> 现在，因为我用本的第一行，在这里的明星在上面，
我只知道，123和124，尽管它们显然整数
任何人类可以注意到，他们应该被解释为地址，数字地址。
他们不是在和自己的int类型，他们的地址，
那是因为我已明确地把星星。
所以现在我的第一，第二和第三线的实际代码，这里发生了什么？
让我们绘制的图象的其余部分。
TMP就像是在星期一。没有什么特别的TMP。
这是本地32位变量，和里面的，我的一个显然的值存储。
现在，如果我刚才说的TMP = A，那么我放在这里？ >> [学生123。
123。但是，这不是我在做什么。
我说的TMP = * A。星号表示去那里。
因此，这里是123。我怎么去那里？假装有一个箭头。
好了，就在这儿，1。那么，什么被存储在tmp，显然是吗？仅有1。
所以，换句话说，tmp是去的地址，目前正处于一个*，*的手段，
这显然​​是123。
>> 好了，在这里，我们是在位置123，我看到数字1，
所以我打算把1号。
现在，我该怎么办第2行中，* = * B吗？
这是稍微复杂些，因为现在是一个什么呢？这是123。
所以，一个是在哪里呢？在我之前。所以去那里。好吧。
现在，最后，然后终于，这将开始有意义，希望，
* B在B意味着什么？ 124。因此，我需要去那里，这是2。
那么，我该怎么放哪里？
2进入这里，因为进入* A * B。所以，我会做到这一点。
你已经可以看到，或许，我们更接近
第一次正确地解决这个愚蠢的，简单的问题
因为现在我们仍然是x的回忆，
我们有2个副本，无可否认，y的，
但现在3号线* B说。
因此，这里的B。 * B的手段去那里。那么，是位置124？
它显然是在这里。所以我把什么呢？显然，tmp目录。
所以，现在我做到这一点。所以，我这里这里。
而现在所有这一切，123，124，和1？
只要交换的回报，这种记忆丢失
因为一旦作为交换的回报，操作系统
在未来再次使用该内存。
只有主内存在这个所谓的堆栈的底部，坚持围绕。
>> 因此，我们现在终于有一个工作版本。
让我去为swap.c，并注意以下几点。
在顶部的程序，我已经改变了我的原型是* A和int * B。
因此，唯一的事情，我改去，这是坏的，从红色到绿色，这是很好的，
是我今天的这些明星。
但再往下在这里交换本身我不得不复制，粘贴只是在幻灯片上。
我在这里有一个明星，明星在这里 - 相匹配的原型 -
然后所有这些事情现在有星星除了TMP
因为使用一个临时变量，有没有什么新东西。
我只是需要临时存储类型为int的。
因此，我们并不需要一个明星。
我们需要的只是明星，这样我们就可以过这种任意边界
这些在我的电脑的内存中的2帧之间。
但最后一件事必须改变，你可能已经瞥见了它。
什么其他的显然是不同的呢？ >> [学生]＆X。
>> 是啊，所以25是最后一行的代码，我需要改变这个工作。
一个星期前，即使是在星期一的第25行是这样的，交换x和y，
这是刚刚打破，因为如果你说掉期（X，Y）
你给的x和y的副本掉，然后做自己的事情，
但你从来没有真正改变x和y本身。
所以，即使你从来没有见过这个字符与符号的代码，
只是猜测。符号做什么，显然是吗？
[学生]的地址。地址>>注意到。
因此，符号是说给我x的地址。
谁知道它在哪里？它正好是123。我不在乎。只要给我x的地址。
＆y表示y的地址给我。
在这一点上的故事是完全一致的图片，我们刚才画。
>> 所以，我得承认指针，当然对我来说，当我第一次开始学习，
绝对包住我的脑海里约最困难的事情之一。
但实现，尤其是我们玩这些事情，
智力无趣的，如果你把它分解到这些超级简单的排序问题
移动数字周围，回答了很多混乱的指针
真的可以来自这些非常基本的力学。
这里有一个地址。去那里的明星。
或者反过来说，这里是一个符号。图的地址实际上是什么。
好的。
那么，此内存来自哪里？
我们已经开了几次这张照片，我一直许诺我们会回来的，
但这里是您的计算机的内存中的代表性
这是多一点比我们的黑板标记。
在顶部的文本段代表你的程序是什么？
[听不见的学生回应] >>你说什么？再说一遍。
[学生]：实际的程序。 >>实际的程序。
>> 因此，“0”和“1您已经编写C代码编译后，然后运行铛
和产生0和1的目的还是藏在内存中
因为当你双击一个图标在您的Mac或PC
像马里奥或运行命令提示符，从磁盘0和1的
获得加载到内存中，计算机可以操纵他们
更迅速地执行。
所以初始化的数据和未初始化的数据，我们不会多谈这些问题，
但这些仅仅是全局变量。
初始化是指全局变量，你给的值;
未初始化意味着，你没有给的值的全局变量。
然后这些环境变量，我会完全挥挥手，
但他们在那里和存储事情，比如你的用户名
和其他类型的低级别的细节。
但最精采的作品是这件事情的栈和堆内存的布局。
堆栈中再次是明确的，是的函数被调用时使用的内存，
每当有局部变量
，每当有参数被传递。
所有这些都发生在堆栈中。
堆，我们还没有谈到，但猜测谁使用堆。
只是不同的内存块。
它发生在被绘制在顶部，但是这是一个任意的图案公约。
谁的显然已经使用的内存从堆中周吗？
这是技术上你，但间接的。 >> [学生] GetString的。
GetString和malloc的。因此，这里的根本区别。
>> 你知道，在过去的几个星期，如果你需要的内存，只需要声明一个变量。
如果你需要大量的内存，直接在你的函数声明一个数组。
但我们已经把面临的问题是，如果你声明的变量在本地内的功能，
只要在函数返回，会发生什么变化记忆体及变量？
只是它不再是你的，对不对？它只是消失在概念上的排序。
它仍然是物理存在，很明显，但它不再是你的使用权。
这显然​​是有问题的，如果你想在生活中写功能
实际分配内存，不给它立即返回。
举个例子：在生活中的GetString的目的是不知道提前
我要在键盘上输入一个字符串有多大，
但它有能够分配内存来存放大卫你好
或213-248，用户可能会键入。
所以GetString的已使用malloc。
malloc的，因此必须使用的堆栈;
而不是它的使用这个东西称为堆。
有没有什么不同的内存。这不是更快或更慢或类似的东西。
这只是身体在不同的位置。
>> 但是，该规则是在堆上分配的内存的
你将永远不会被带走，直到你调用 - 猜测 - 免费。
与此相反，任何在栈上的内存，你问的只是声明一个数组
或者声明一个变量，如我们已经做了好几个星期，
默认情况下，结束了在堆栈中。
的伟大工程的90％的时间，但对那些罕见的场合
在那里你要分配内存，并保持周围，
然后，你需要使用的malloc之类的函数。
我们使用GetString时，在使用malloc之类的函数。
让我们来看看，这可能分解，然后采取偷看在宾基。
我们会回来的，在未来。
这是一个超级简单的程序，在第2行做什么？
在英语中，这些第2行代码里面做的主吗？
[听不见的学生反应]
小心点。它并没有给我的地址，x或y。
[学生]给出整数的指针。 >>好。给我指向整数的指针。
换句话说，给我2块内存我保持绘图今日，，
即使我现在将其擦除，为方形。
给我2块内存，一个叫X，Y -
刚才我叫s和t - 该内存块的类型是什么？
这将存储地址。
这是int *类型。
>> 因此，一个int的地址最终会住在x，
一个int的地址，最终将居住在y
但最初，x和y的里面是什么？谁知道？垃圾值。
它有什么做用指针。
如果我们没有把东西，谁知道居然有吗？
现在，X。这里发生了什么？这是合法的，因为x是一个指针。这是一个int *。
因此，这意味着我可以把在x一些的内存块的地址。
什么的malloc返回？完美的，它返回地址，
在一个整体的内存块的第一个字节的地址。
多少个字节，这显然是分配，例如，在家电吗？
什么是一个int的大小吗？ 4。
如果你觉得回到了1周，这是超级重要的，永远记住，
但在这种情况下，它是有用的知道，4个字节。
因此，这是在堆上分配4个字节
和它的返回地址的第一个我任意。
现在，X是什么做的？
A * X = 42是做什么的？
如果我们的故事在这一点上有X，它看起来像这样一些垃圾的价值，
这是目前一些垃圾值y的，现在在第3行中，我已经分配了4个字节。
基本上，这张照片看起来是这样的。
或者更具体地说，如果这是任意地址123，这是我们的故事现在看起来像。
* X = 42意味着什么呢？这意味着到的地址123，并把42号有。
我不需要画出这些线条，因为我们没有做字符串。
>> 我应该写这样的，和示范的缘故，
42作为一个int种需要一个很大的空间，4个字节。
所以这是发生了什么事，但现在有一个问题。
* Y = 13。这是怎么回事就发生在这里？
问题是，* Y在我们的简化的世界只是意味着到y的地址。
在y是什么？这是一些垃圾的价值。
因此，让我们假设，垃圾的价值是5551212，发疯似的。
* y表示去解决5551212。
这就像在这里。它不存在，例如。
因此，* Y取得13的意思，我想画13。它不存在。
我已经超过了段的黑板。我能得到什么？
这神秘的，因为我试图把在内存中的信息segmentation fault
13日在一个地方，不存在这样的值。
其余的程序可能还行，但直至这一点上它不工作。
所以，我们的尝试讲这个故事。
我们会回来的，一旦我们谈到十六进制。
让我们回去，最后，这个东西叫做Binky，
这使人想起坐在家里玩黏土动画是斯坦福大学的一名教授，
来讲述的正是同样的程序。
这只是约3分钟之久。在这里，我们有Binky。
[男扬声器视频]嘿宾基，醒了。它的时间的指针乐趣。
[宾基]那是什么？了解指针吗？哦，好极了！
[男扬声器]好了，要开始了，我想我们需要一对夫妇指针。
>> [Binky]好吧。此代码分配可以指向整数的指针。
[男性扬声器]好吧。嗯，我看到了两个指针，但他们似乎并没有指向任何东西。
[宾基这是正确的。最初，指针不指向任何东西。
的事情，他们指出，被称为指针对象，并设置他们是一个单独的步骤。
[男扬声器]哦，对的，正确的。我知道这一点。的指针对象是分开的。
呃，怎么你分配一个指针对象？
[Binky]好吧。此代码分配一个新的整数的指针对象，而这部分设置x为指向它。
[男性扬声器]嘿，看起来更好。
所以，把它做的东西。 >> [宾基]好吧。
我会取消引用指针x及其指针存储42。
这一招，我需要我的魔杖解引用。
[男性扬声器]你的魔杖提领吗？这是伟大的。
[宾基]这是代码看起来像什么。我会刚刚成立的数量和... [爆裂声]
[男性扬声器]嘿，你看，那里去。
这样做在x取消引用如下的箭头来访问它的指针对象，
在这种情况下，在那里存储42。
嘿，尝试用它来存储指针，Y 13号通过。
[Binky]好吧。我就在这里为Y，13号成立
然后采取的魔杖提领，只是... [嗡嗡的声音喔！
[男性扬声器哦，哎，没有工作。
>> 再说了，Binky，我不认为提领y是一个好主意
因为指针对象是一个单独的步骤
我不认为我们曾经做了。
[Binky]嗯，好一点。
[男性扬声器]是啊。我们分配的的指针y，但我们从来没有设定它指向一个指针对象。
[Binky]嗯，很细心的。
[男扬声器]嘿，你看起来好有，宾基。
所以你能解决它的指针对象为x，y点呢？ >> [宾基]当然。
我会用我的魔杖指针赋值。
[男性扬声器]的是，要像以前一样是一个问题吗？
[Binky]不，这不是触摸指针对象。
它只是改变一个指针，指向的另一个同样的事情。 [爆裂声]
[男性扬声器哦，我明白了。 y点为x的同一个地方。
所以等待。现在，y是固定的。它有一个指针对象。
所以，你可以尝试的的提领魔杖再次发送13个以上。
[Binky]嗯，还行。这里“。 [爆裂声]
[男性扬声器]嘿，你看那个。现在提领对y的作品。
因为指针共享一个指针对象，他们都看到了13。
[Binky]是啊，分享。不管。
>> 所以我们要切换地方，现在呢？
[男性扬声器哦，看，我们没时间了。 >> [宾基]但是 -
[男性扬声器，只要记住3个指针的规则。
1，基本结构是，你有一个指针，它指向指针对象。
但指针和指针对象是分开的，常见的错误是设置一个指针
但忘了给它一个指针对象。
2，指针解引用的指针开始，并遵循其箭头
访问及其指针。
我们都知道，这只是工作，如果有一个指针对象，
种回来规则编号1。
3，指针赋值一个指针，并将其更改
作为另一个指针指向相同的指针对象。
因此，在转让之后，指针将指向的相同指针对象。
有时，这就是所谓的共享。
>> 而这一切是它真的。再见。
这是Binky。这是CS50。我们会下周见。 [掌声]
>> [CS50.TV]