笔记
Lecture 0 - CS50x 2023
欢迎!
- 这门课不仅仅是关于计算机编程!
- 事实上,你将在此学到极具价值的问题解决技巧。这些技巧不仅能立即应用于本课程之外的学习,更能助你一臂之力,在未来的职业生涯中大放异彩!
- 然而,这并不容易! 在这门课程中,你将会面临海量的信息。 你会惊讶于你在未来几周内能够完成的事情。
- 本课程的重点在于帮助你从现有水平不断进步,而非达到某种既定的标准。
- 本课程最重要的建议是:请务必安排充足的时间来学习。 每个人学习的方式都不同。 如果起步阶段遇到困难,请不要灰心。随着时间的推移,你的技能定会不断提升。
后续内容
本周你将学习 Scratch,一种可视化编程语言。
然后,在未来的几周里,你将学习 C 语言。它看起来像这样:
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
}后续课程中,你还将学习算法。
你将学习内存。
你将学习如何识别并修复代码中的缺陷,以及导致计算机崩溃的常见原因。
你将学习诸如哈希表之类的数据结构。
然后,我们将过渡到一种新的、更高级的语言,称为 Python。 你的代码看起来像这样:
print("hello, world")
通过本课程,你将深入了解现代编程语言从早期语言演变而来的过程。
我们还将研究如何使用数据库和第三方框架来构建 Web 应用程序。
社区!
- 你将与来自哈佛学院、哈佛推广学院以及通过 edX.org 参与本课程的同学们共同组成一个学习社区。
- 本课程还会组织解谜日和 CS50 展览会等活动。
计算思维
本质上,计算机编程就是接收输入,产生输出,从而解决问题。而输入和输出之间的过程,也就是我们常说的“黑盒”,正是本课程要重点探讨的内容。
举例来说,我们需要统计班级的出勤情况。可以用“一元计数法”,也就是扳手指头来数。现在的计算机则使用二进制计数。我们常说的“位 (bit)”,就是从“二进制数字 (binary digit)”这个概念衍生出来的。一个“位”要么是 0,要么是 1。
计算机的世界只有 0 和 1。0 代表“关”,1 代表“开”。计算机内部有数百万甚至数十亿个晶体管,它们通过不断地开关来工作。
想象一下,如果用一个灯泡来计数,它只能表示 0 或 1 两种状态。
但是,如果有三个灯泡,就能表示更多的信息了!
使用三个灯泡,以下可以代表零:
0 0 0
类似地,以下将代表一:
0 0 1
按照这个逻辑,我们可以提出以下等于二:
0 1 0
进一步扩展这个逻辑,以下代表三:
0 1 1
四将显示为:
1 0 0
事实上,我们只用三个灯泡就可以数到七!
1 1 1
我们可以这样理解:在二进制数中,每一位上的值代表着不同的权重:
4 2 1
计算机使用“以 2 为基数”的计数方式,也就是二进制。如下图所示:
2^2 2^1 2^0
4 2 1所以,需要三个比特位(分别代表 4、2 和 1)才能表示最大为 7 的数字。
计算机通常用 8 个比特位(也就是一个字节)来表示一个数字。例如,
00000101
这个二进制数就代表十进制的 5。
文本
正如数字是 1 和 0 的二进制模式一样,字母也用 1 和 0 表示!
由于数字和字母都用 0 和 1 来表示,为了区分它们,就有了 ASCII 编码,将特定的字母对应到特定的数字。
例如,字母
A
被决定映射到数字 65。例如,你收到一条短信,其底层二进制数据可能对应着 72、73 和 33 这几个数字。将它们转换为 ASCII 码,就会得到如下信息:
H I !
72 73 33多亏有了像 ASCII 这样的标准,我们才能对这些数值达成共识!
这是一个扩展的 ASCII 值图:
如果你愿意,你可以了解更多关于 ASCII 的信息。
表情符号
随着时间的推移,通过文本进行交流的方式越来越多。
由于二进制编码的位数有限,无法表示人类使用的所有字符,因此 Unicode 标准扩展了编码的位数,从而能够表示更多的字符。
你可能每天都在使用表情符号。以下内容你可能很熟悉:
为了让表情符号更具个性化,计算机科学家们希望为每个表情符号添加不同的肤色选项。他们面临的挑战是,如何在现有编码的基础上实现这一点。最终,表情符号的创建者们决定,用一部分编码表示表情符号的基本结构,另一部分编码表示肤色。
越来越多的功能被添加到 Unicode 标准中,以表示更多的字符和表情符号。
如果你愿意,你可以了解更多关于 Unicode 的信息。
如果你愿意,你可以了解更多关于 表情符号 的信息。
RGB
红色、绿色和蓝色(简称
RGB
)是三种颜色的数值组合。如果我们采用之前用过的数字 72、73 和 33,它们在文本中表示
HI!
,但在图像读取器中会被解读为一种浅黄色。其中,红色分量是 72,绿色分量是 73,蓝色分量是 33。
图像、视频和声音
- 图像本质上是 RGB 值的集合。
- 视频是由一系列连续的图像组成,这些图像按顺序排列,类似于翻页书。
- 音乐可以通过 MIDI 数据表示。
算法
解决问题是计算机科学和编程的核心所在。
想象一下,在电话簿中查找单个姓名的基本问题。
你会怎么做呢?
一种方法就是从第一页开始,一页一页地翻,直到最后一页。
另一种方法是每次翻两页。
最后一种可能更好的方法是直接翻到电话簿中间,然后判断:“我要找的名字是在这页之前还是之后?” 接着,重复这个步骤,每次将查找范围缩小一半。
这些方法都可以被称为算法。每种算法的效率可以用所谓的 大O表示法 来衡量,如下所示:
注意,第一个算法(红色高亮显示)的大O复杂度是
n
,这意味着如果电话簿里有 100 个名字,最坏情况下需要查找 100 次。第二个算法,每次查找两页,大O复杂度是“n/2”,效率提高了一倍。最后一个算法的大O复杂度是 log2n,也就是说,问题规模翻倍,查找步骤只增加一步。
伪代码和编程的基本构建块
编写伪代码的能力对于在本课程和计算机编程中取得成功至关重要。
伪代码是代码的一种人类可读的版本。例如,考虑到上述第三种算法,我们可以这样编写伪代码:
1 拿起电话本
2 翻到电话簿中间
3 看那一页
4 如果那个人在这一页上
5 给那个人打电话
6 否则,如果那个人在书的前半部分
7 翻到书的左半部分的中间
8 返回第3行
9 否则,如果那个人在书的后半部分
10 翻到书的右半部分的中间
11 返回第3行
12 否则
13 退出编写伪代码是一项非常重要的技能,主要有两个原因。首先,在创建正式代码之前编写伪代码,可以帮助你提前理清问题的逻辑。其次,编写伪代码后,你可以将它提供给其他人,帮助他们理解你的编码思路和代码的工作方式。
请注意,我们的伪代码语言有一些独特的特点。首先,其中一些行以动词开头,例如拿起、打开、看等。稍后,我们会将它们称为函数 (functions)。
其次,请注意,有些行包含诸如
if
或else if
之类的语句。这些被称为条件语句 (conditionals)。第三,请注意,有些表达式可以被陈述为真或假,例如“那个人在书的前面”。我们称这些为布尔表达式 (boolean expressions)。
最后,请注意像“返回第3行”这样的语句。我们称这些为循环 (loops)。
在接下来要讨论的Scratch中,我们将使用上述每个编程的基本构建块。
Scratch
Scratch 是一种由麻省理工学院 (MIT) 开发的可视化编程语言。
Scratch 使用的是我们在本次讲座前面介绍过的那些基本编程构建模块。
Scratch 是学习计算机编程的绝佳入门方式,因为它能让你以可视化的方式操作这些构建模块,而无需操心花括号、分号、圆括号之类的语法问题。
Scratch 的
IDE
(集成开发环境) 界面如下所示:请注意,在左侧,是你在编程时可以使用的各种构建块。在这些构建块的右侧,你可以将它们拖拽到编程区域来搭建程序。在编程区域的右侧,你会看到猫咪所在的舞台。舞台是你的程序运行和呈现效果的地方。
Scratch 使用如下所示的坐标系:
请注意,舞台中心位于坐标 (0,0),现在猫咪也位于这个位置。
首先,把“当绿旗被点击”积木拖到编程区。然后,再把
say
积木拖过去,和之前的积木连接起来。请注意,现在点击舞台上的绿旗,猫咪就会说“hello world”。
这很好地解释了我们之前讨论的编程原理:
请注意,输入
hello world
被传递给say
函数,而该函数运行的副作用就是猫咪说出hello world
。我们可以让程序更具互动性,让猫咪对特定的人说
hello
。按如下方式修改你的程序:请注意,点击绿旗后,
ask
函数开始运行。程序会提示用户输入姓名 (What's your name?
),并将用户输入的姓名储存在名为answer
的变量里。接着,程序会将answer
传递给名为join
的特殊函数,这个函数会将文本字符串hello
和用户输入的姓名拼接在一起。然后,拼接好的字符串会被传递给say
函数,猫咪就会说“Hello, [用户姓名]”。现在,你的程序就具有交互性了。类似地,我们可以这样修改程序:
请注意,点击绿旗后,这个程序会将同样的变量和
hello
拼接在一起,然后传递给speak
函数。
抽象
除了伪代码之外,抽象是计算机编程中一项至关重要的技能和概念。
抽象是将一个问题简化为越来越小的问题的行为。
例如,如果您要为朋友举办一个盛大的晚宴,那么准备一整桌菜的难题可能会让人感到无从下手!但是,如果您将烹饪饭菜的任务分解为越来越小的任务(或问题),那么完成这顿美味佳肴的重任就会显得轻松一些。
在编程区,输入以下代码:
请注意,您一遍又一遍地做着同样的事情。事实上,如果您发现自己反复编写相同的语句,那么您很可能可以更巧妙地进行编程——将这种重复的代码抽象出来。
您可以按如下方式修改您的代码:
请注意,循环实现的功能和之前的程序完全一样。但是,通过将重复部分抽象成一个重复执行代码的积木,问题就得到了简化。
我们甚至可以使用
define
积木来更进一步!按如下方式编写代码:请注意,我们正在定义我们自己的名为
meow
的积木。这个函数会播放meow
的声音,然后等待一秒。在下面,您可以看到,当单击绿旗时,我们的 meow 函数会重复三次。我们甚至可以提供一种方法,让函数可以接受输入
n
并重复多次:请注意,
n
是从“meow n times”中获取的。n
通过define
积木传递给 meow 函数。顺便说一句,我们可以将猫称为
sprite
——游戏编程中用于屏幕上对象或角色的通用术语,玩家将与之交互。
If
条件语句是编程的基本组成部分,程序会检查是否满足特定条件。如果满足条件,程序会执行某些操作。
为了说明条件语句,请按如下方式编写代码:
请注意,
forever
积木会不断重复执行,持续检查猫是否碰到了鼠标指针。我们可以这样修改程序,来加入视频感应功能:
请记住,编程通常是一个反复试验的过程。如果您感到沮丧,不妨冷静下来,仔细分析一下当前的问题。您现在正在处理的具体问题是什么?什么在起作用?什么不起作用?
Expanding Your Imagination
在本次讲座中,我们展示了一些Scratch程序,旨在激发大家的想象力。
Oscartime 是 David 自己的 Scratch 程序之一 —— 虽然创作过程中,为了这段音乐,他听了无数遍,现在可能都有点怕了。不妨花点时间亲自体验一下这个游戏。
要自己动手制作Oscartime,首先要添加一个路灯。
然后,按如下方式编写代码:
注意,当鼠标悬停在Oscar角色上时,他的造型会发生变化。点击此链接,可以查看更多代码细节:
接下来,按照下面的方法修改代码,创建一个下落的垃圾。
注意,垃圾在Y轴上的初始位置是180,X轴的位置是随机的。 当垃圾高于地面时,每次会向下移动3个像素。点击此链接,可以查看更多代码细节:[]
接下来,修改代码,让垃圾可以被拖动。
点击此链接,可以查看更多代码细节:
接下来,我们可以按如下方式实现评分变量:
点击此链接,可以查看更多代码细节:
角色移动
现在,让我们从Oscartime转移到Ivy’s Hardest Game,我们现在可以想象如何在我们的程序中实现移动。
这个程序主要由三个部分组成。
首先,按如下方式编写代码:
注意,点击绿旗后,角色会移动到舞台中央(0,0)的位置,然后持续监听键盘输入,并检测是否碰到墙壁。
其次,添加第二组代码块:
注意,我们创建了一个自定义的“listen for keyboard”脚本。 通过按下键盘上的方向键,可以控制角色在屏幕上的移动。
最后,添加这组代码块:
注意,还有一个自定义的“feel for walls”脚本。 当角色碰到墙壁时,这个脚本会把它移回安全区域,防止它穿墙而出。
点击此链接,可以查看更多代码细节
快去体验完整的游戏吧!Oscartime
更多角色
Scratch 允许在屏幕上同时显示多个角色(精灵)。
要添加另一个角色,请把下面的代码块添加到你的程序里:
注意看,耶鲁的角色好像在来回晃悠,挡了哈佛的角色。碰到墙后,它会转弯,直到再次撞墙。 想了解更多?可以看看这些代码块:浏览这些代码块。
您甚至可以使一个角色跟随另一个角色。 要添加另一个角色,请将以下代码块添加到您的程序中:
注意看,麻省理工的标志现在好像在追着哈佛的标志跑。 您可以通过浏览这些代码块了解更多信息。
快去试试完整的游戏吧!Ivy’s Hardest Game。
总结
在本课程中,您了解了本课程在广阔的计算机科学和编程领域中的地位。 您学到了…
- 很少有学生在参加本课程之前有编码经验!
- 你不是一个人在战斗! 你是社区的一员。
- 解决问题,才是计算机科学家的真谛。
- 这门课不仅仅是教你编程,更会教你一种新的学习方法,让你受益终身。
- 计算机如何理解数字、文本、图像、音乐和视频。
- 伪代码的基本编程技能。
- 抽象将如何在您未来的课程工作中发挥作用。
- 编程的基本构建块,包括函数、条件、循环和变量。
- 如何在 Scratch 中构建项目。
咱们下节课见!