WEBVTT 00:00:00.780 --> 00:00:05.280 这节课的主题是 for 循环 00:00:05.280 --> 00:00:09.722 使用 for 循环,我们就可以用代码来做许多事情 00:00:09.910 --> 00:00:14.672 这幅花朵的原图是457像素宽乘360像素高 00:00:14.672 --> 00:00:19.684 将两者相乘,就得到164000像素 00:00:19.684 --> 00:00:24.697 这张图挺小的,已经有这么多像素 00:00:24.697 --> 00:00:29.835 我们之前写代码的方式是用 pixel.setRed(255) 这个代码行 00:00:29.835 --> 00:00:34.346 来将一个像素点改成红色,用这样的方法来改变整张图片 00:00:34.346 --> 00:00:39.171 是很不现实的。我的意思是,这么小的一张图就有超过10万个像素 00:00:39.171 --> 00:00:43.965 我们需要有一个结构 00:00:43.965 --> 00:00:49.191 写几行代码来反映我们要做的改变 00:00:49.191 --> 00:00:54.541 然后让计算机自己不断重复地运行这些代码,改变图像的每一个像素点 00:00:54.541 --> 00:00:59.581 因此,我们这堂课要讲的 for 循环就是要做到这一点 00:00:59.581 --> 00:01:04.610 这样会大大增强我们使用代码的范围 00:01:04.610 --> 00:01:09.003 我要先讲一下 for 循环的结构,先来看看这个结构有哪些组成部分 00:01:09.003 --> 00:01:13.693 我来举个例子。这个蓝框里有一张 for 循环的图片 00:01:13.693 --> 00:01:20.751 我待会会讲一下组成部分 00:01:20.751 --> 00:01:27.484 开始 - 我用红笔画出来 - 这里开始 for 循环,所以有 for 这个单词 00:01:27.484 --> 00:01:33.423 括号里是 pixel: image,后面是尖括号,开始另一行 00:01:33.423 --> 00:01:38.565 这里的意思是这个句法要有括号、尖括号和其他内容 00:01:38.565 --> 00:01:43.046 在我的例子和练习里,都是一样的 00:01:43.046 --> 00:01:47.583 我们会提供这一行,让你写出下面的代码 00:01:47.583 --> 00:01:52.120 这一行的意思是 00:01:52.120 --> 00:01:56.490 图像里的每一个像素都要完成下面的代码 00:01:56.490 --> 00:02:03.720 下面的代码就是用来规定完成的任务 00:02:03.720 --> 00:02:09.243 这些行是 for 循环的主体 00:02:09.243 --> 00:02:14.627 这几行就可以完成我们要做的事情 00:02:14.627 --> 00:02:20.010 for 循环的运行方式是我们要改变这个花朵图像 00:02:20.220 --> 00:02:25.240 这里有三行代码。要取整个图像的第一个像素 00:02:25.240 --> 00:02:29.617 左上角的像素,因此它就取出第一个像素 00:02:29.617 --> 00:02:33.365 for 循环就运行这三行代码,这里是 pixel.setRed(0) 00:02:33.365 --> 00:02:37.165 pixel.setGreen(0)、pixel.setBlue(0) 00:02:37.165 --> 00:02:41.066 这些代码都是针对第一个像素执行的 00:02:41.066 --> 00:02:45.348 就是要将这个像素变成黑色,对吧?它将红、绿、蓝的值全部改成0 00:02:45.348 --> 00:02:49.917 for 循环到这里底部的时候,发生一个有趣的事情,我用黑色的箭头显示出来 00:02:49.917 --> 00:02:54.720 代码返回到这三行代码的顶端,取出第二个像素 00:02:54.720 --> 00:02:59.230 对第二个像素运行这三行代码 00:02:59.230 --> 00:03:04.268 对第二个像素运行完以后,再次返回到顶部 00:03:04.268 --> 00:03:08.837 对第三个像素运行这三行代码。我们就是不断重复地运行代码 00:03:08.837 --> 00:03:15.044 改变图像里的每一个像素 00:03:15.044 --> 00:03:19.220 要注意的一点是代码主体的这三行是缩进的 00:03:19.220 --> 00:03:23.044 尽管不是必须的,这是个常见的作法 00:03:23.044 --> 00:03:27.271 就是要将主体代码和其他代码区别开来 00:03:27.271 --> 00:03:31.346 image = new SimpleImage 这行代码只运行一次,print(image)代码也只运行一次 00:03:31.346 --> 00:03:35.623 循环里的代码就有点特别 00:03:35.623 --> 00:03:40.084 他们的性质是不断循环的运行。我们来试试看 00:03:40.084 --> 00:03:44.658 我们来试这个实例,这里是可运行的代码,这里加载图像 00:03:44.658 --> 00:03:49.290 有 for 循环,主体代码开始,这里是三行主体代码 00:03:49.290 --> 00:03:54.095 这个括号有点小,不过这里有个右尖括号 00:03:54.095 --> 00:03:58.958 和左尖括号对应,结束主体代码 00:03:58.958 --> 00:04:03.315 运行来看看结果。你看到的是这个纯黑色的长方形 00:04:03.315 --> 00:04:07.660 这不是很有用,但确实显示了 for 循环的功能 00:04:07.660 --> 00:04:12.059 其中的原理是这幅花朵的原图 00:04:12.059 --> 00:04:16.938 有各种红、绿、黄和其他颜色,代码的作用 00:04:16.938 --> 00:04:21.912 是访问图像的每个像素点,执行这三行代码 00:04:21.912 --> 00:04:26.396 这个程序就是取像素点,将红、绿和蓝全部设成0 00:04:26.396 --> 00:04:31.002 结果就是将像素变成纯黑像素 00:04:31.002 --> 00:04:35.916 你可以想象,这个过程就是将图像6的数据删掉 00:04:35.916 --> 00:04:41.358 剩下来的就是这个纯黑的长方形 00:04:41.358 --> 00:04:48.129 再多试一个例子,将每个像素的红色值和绿色值设为255,将蓝色值设为0 00:04:48.129 --> 00:04:53.608 我要想想什么代码可以完成这一点 00:04:53.608 --> 00:04:58.030 这里的思维方式是我们用英语说 00:04:58.030 --> 00:05:02.279 我要这个效果,将红色值设成255或其他数值 00:05:02.279 --> 00:05:07.044 在练习里,你的任务就是要将这句英语翻译成代码 00:05:07.044 --> 00:05:11.638 这个例子说明这种模式 00:05:11.638 --> 00:05:16.633 代码的主体要将红色值和绿色值改成255,将蓝色值改成0 00:05:16.633 --> 00:05:21.399 头两行是 pixel.setRed(255) 和 pixel.setGreen(255) 00:05:21.399 --> 00:05:25.956 第三行是 pixel.setBlue(0)。运行一下看看 00:05:25.956 --> 00:05:30.171 结果是鲜黄色的长方形,和前面的例子差不多 00:05:30.171 --> 00:05:34.545 我们的作法是改变这幅图里每个像素的绿色值和蓝色值 00:05:34.545 --> 00:05:39.863 就得到鲜黄色 00:05:39.863 --> 00:05:44.055 这两个例子有点不现实,是吧?我们只是删除所有数据 00:05:44.055 --> 00:05:48.140 产生这个有色的长方形。我现在来试一个现实一点的例子 00:05:48.140 --> 00:05:51.908 我们不删除花朵图像中的全部数据 00:05:51.908 --> 00:05:56.650 我们来改变这些数据。这是花朵的原图 00:05:56.857 --> 00:06:02.852 你知道,黄色等于红色加绿色 00:06:02.852 --> 00:06:08.572 所以这里黄花的红色值和绿色值是很高的 00:06:08.572 --> 00:06:14.085 在这个例子里,我要将整个图像的红色值改成0 00:06:14.085 --> 00:06:19.235 想想要怎么做。第一个问题是,要用什么样的代码 00:06:19.235 --> 00:06:23.753 在这个例子里,你看到的是主体代码只有 pixel.setRed(0) 一行代码 00:06:23.753 --> 00:06:28.440 我以前的实例里,主体代码有三行 00:06:28.440 --> 00:06:33.014 行数是任意的,可以是三行或六行 00:06:33.014 --> 00:06:37.589 这个例子只有一行代码。这行代码用英语来表达 00:06:37.589 --> 00:06:41.994 就是这个 for 循环用于图像里的每一个像素点,将其红色值改成0 00:06:41.994 --> 00:06:46.621 我们来看看结果。运行一下,你看到的是 00:06:46.621 --> 00:06:51.600 花朵变成这种奇怪的、放射的绿色花朵 00:06:51.600 --> 00:06:55.790 如果将黄色花朵的组成部分分解来看 00:06:55.790 --> 00:07:00.190 就是红色光和绿色光的结合 00:07:00.190 --> 00:07:03.874 这行代码做的是将红色光的值调为0 00:07:03.874 --> 00:07:07.700 就像我们将灯光调到0一样 00:07:07.700 --> 00:07:11.526 所以图像只是有绿光组成 00:07:11.526 --> 00:07:15.305 还有一点要注意,看看右下角的绿叶 00:07:15.305 --> 00:07:19.415 它们没有什么不一样,所以这里可能大部分是绿光 00:07:19.415 --> 00:07:23.288 红光的值大概是8或者10左右 00:07:23.288 --> 00:07:29.698 如果将红色值改成0,从视觉上而言没有什么区别 00:07:29.698 --> 00:07:34.881 我们再多试一个例子。在这个例子里 00:07:34.881 --> 00:07:40.596 我要将花朵图像的绿色值和蓝色值设成0,蓝色值保持不变 00:07:40.596 --> 00:07:45.978 代码是什么呢?要写两行主体代码 00:07:45.978 --> 00:07:51.560 pixel.setGreen(0) 和 pixel.setBlue(0),红色保持不变 00:07:51.560 --> 00:07:57.843 运行一下,你看到的是红色的花朵 00:07:57.843 --> 00:08:04.590 这称作图像的红色通道 00:08:04.590 --> 00:08:09.309 这个图像是红光、绿光和蓝光的组合 00:08:09.309 --> 00:08:13.691 我们刚才将绿光和蓝光设成0 00:08:13.691 --> 00:08:17.848 就是将两个颜色的值调到最低 00:08:17.848 --> 00:08:22.342 剩下来的就是一副红色光图 00:08:22.342 --> 00:08:26.723 有些地方是鲜红色,有些地方是暗红色 00:08:26.723 --> 00:08:31.274 左边这里是暗红色,没有太多红光 00:08:31.274 --> 00:08:35.132 这里的绿叶没有很多红色 00:08:35.132 --> 00:08:39.986 只是黄色花朵有显著的红色光 00:08:39.986 --> 00:08:44.337 这只是看图像的一种方式 00:08:44.337 --> 00:08:48.410 这里的蓝色通道和绿色通道其实是类似的 00:08:48.410 --> 00:08:55.053 for 循环的功能非常强大 00:08:55.053 --> 00:08:59.476 我们可以用它来写几行代码 00:08:59.476 --> 00:09:03.488 让计算机运行一些大数据集 00:09:03.488 --> 00:09:07.912 在这个例子中我们是处理图像。我要提一下的是 00:09:07.912 --> 00:09:11.975 Java Script 语言的 for 循环不是这么简洁的 00:09:11.975 --> 00:09:15.935 这在 JavaScript 语言里是没有的,我在这门课里加上,所以可以运行 00:09:15.935 --> 00:09:19.844 如果你做其他的 JavaScript 题目时,就不会有这个功能 00:09:19.844 --> 00:09:24.114 但大多数语言都有像这样的 for 循环 00:09:24.114 --> 00:09:29.844 只是很奇怪 JavaScript 没有。所以这里的模式是我们要写代码 00:09:29.844 --> 00:09:34.331 写一点点代码来表达我们想要做的事情 00:09:34.331 --> 00:09:39.045 这体现了计算机是很强大的,但也很愚蠢 00:09:39.045 --> 00:09:43.532 你写有意思的代码 00:09:43.532 --> 00:09:48.190 我要这样那样该绿色 00:09:48.190 --> 00:09:53.018 通过使用 for 循环,我们可以和计算机合作 00:09:53.018 --> 00:09:57.009 计算机就会做很厉害的事情,运行代码10万次甚至是100万次 00:09:57.009 --> 00:10:01.621 计算机这样运行 00:10:01.621 --> 00:10:05.419 但其实也只是做非常机械的事情 00:10:05.419 --> 00:10:09.867 这体现了计算机原理的总体主题 00:10:09.867 --> 00:10:14.371 那就是计算机可以快速地处理机械的部分 00:10:14.371 --> 00:10:18.820 人类要用创造性来控制如何让计算机运行 00:10:18.990 --> 00:10:23.764 下一节 - 做完这样的练习以后 - 00:10:23.764 --> 00:10:28.481 我会加一个功能 00:10:28.481 --> 00:10:31.380 我们就可以开始做一些更有趣的事情