2019-06-11 11:11:14 +08:00
穿越到 1983 年学习 BASIC
2019-06-06 06:21:11 +08:00
======
2019-07-12 12:59:12 +08:00
![](https://img.linux.net.cn/data/attachment/album/201907/12/125743p495dqnqdtctqzgp.jpg)
2019-07-12 12:56:47 +08:00
1983 年时我还没出生,这让我略有一些遗憾。但我特别遗憾的是,是我没有经历过 8 位计算机时代的到来,因为我认为那些初次接触到还相对简单和受限的计算机的人们,拥有超过如今的我们的巨大优势。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
今天,(几乎)每个人知道如何使用计算机,但是即使是在计算机行业当中,也很少有人能明白任何一台计算机内部的所有内容。现在软件分为[如此多的层次][1],做的是如此不同的事情,没有哪个人能知道哪些是必不可少的。而在 1983 年,家用电脑足够傻大粗,努力一些的人就能了解到一台特定的计算机是如何工作的。那样的一个人可能不会像今天的我觉得操作系统那么神秘,因为如今的操作系统已经在硬件上叠加了太多的抽象层。我希望这些抽象层逐一引入以易于理解;而今天,新的程序员们不得不自上而下、按时间回溯地尝试理解它们。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
很多著名的程序员,尤其在计算机游戏行业,孩童时期就在苹果 II 和 Commodore 64 这样的 8 位计算机上开始编写游戏, John Romero、Richard Garriott 和 Chris Roberts 都是这样的例子。这好理解。在 8 位计算机时代,很多游戏只能在计算机杂志和[书籍][2]中以印刷的 BASIC 程序清单方式得到。如果你想玩其中一款游戏,就必须手工键入整个程序。不可避免的,你可能遇到一些问题,所以你就得调试你的程序。等到你让它可以工作起来了,你就已经对程序是如何运行的有了足够的了解,你就可以开始自己修改它了。如果你是一个狂热的游戏玩家,你几乎必然会成为一名优秀的程序员。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
在我的童年时期我也玩电脑游戏。但是我玩的游戏是在 CD-ROM 上的。我有时发现我自己必须得搜索一下如何修复崩溃的安装程序,这可能涉及编辑 Windows 注册表之类的东西。可能是这种小故障的排除让我感觉很棒,所以我才考虑在大学里学习计算机科学。但是在大学中从不教我一些计算机如何工作的或如何控制它们的关键性的东西。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
当然,现在我可以告诉计算机去干什么。尽管如此,我还是不禁感到,我缺少一些根本的见解 —— 只有那些伴随着更简单的计算机编程而成长的人才有的深刻见解。我不禁在想,如果在上世纪 80 年代初就接触到计算机会是什么样子?它们与今天使用计算机的体验相比有何不同?
2019-06-11 11:11:14 +08:00
这篇文章将与通常的 Two-Bit History 的文章有一点不同,因为我将为这些问题尝试设想一个答案。
2019-06-06 06:21:11 +08:00
### 1983
2019-07-12 12:56:47 +08:00
就在上周,你在电视上看到了 [Commodore 64 的广告][3] ,现在 M\*A\*S\*H 播完了( LCTT 译注: 这是一部上世纪 70 年代初的电视剧),星期一晚上你可以找点新的事情做了。这个 Commodore 64 甚至看起来比鲁迪( LCTT 译注:应该是下文中拥有 Apple II 的人)的家人放在他们家地下室的 Apple II 更好。而且,广告中吹嘘说新的计算机会让你的朋友们“挤破”你家的大门。你知道学校里的几个家伙宁愿在你家闲逛,也不愿去鲁迪家里,只要他们能玩 Zork 就行。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
所以,你得说服你的父母去买一台。你的母亲说,这事可以考虑,只要你不去游戏厅玩街机就给你买一台家庭电脑。虽然不太情愿,但是你还是同意了。而你的父亲则想,他可以用 MultiPlan ( LCTT 译注: 电子表格程序) 跟踪家庭的资金状况, MultiPlan 是他曾听说过的一个电子表格程序,这就是为什么这台计算机被放在客厅的原因。然而,一年后,你仍然是唯一使用它的人。最终,他们同意你把它搬到了你的卧室的桌子上,正好位于你的警察海报下方。
2019-06-06 06:21:11 +08:00
2019-07-09 01:18:19 +08:00
(你的姐姐对这个决定表示抗议,但是,在 1983 年电脑这种东西[并不适合女孩][4]。)
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
你的父亲在下班路上从 [ComputerLand][5] 那里把它捎了回来。你俩把盒子放置在电视机的旁边,并打开了它。外包装上说“欢迎来到友好的计算机世界”。而二十分钟以后你就不再信这句话了 —— 你俩仍然在尝试把 Commodore 连接到电视机上,并在想电视机的天线电缆到底是 75 欧姆还是 300 欧姆的同轴电缆。但是,最终你把电视机调到了频道 3, 看到了一个颗粒状的、紫色的图像。
2019-06-06 06:21:11 +08:00
![Commodore 64 启动屏幕][6]
2019-07-09 01:18:19 +08:00
计算机显示了一个 `READY` 。你的爸爸把计算机推向了你,这意思是你是第一个尝试它的人。你小心翼翼地敲击每个字母,键入了 `HELLO` 。然而计算机的回应是令人困惑的。
2019-06-06 06:21:11 +08:00
![Commodore 64 语法错误][7]
2019-07-12 12:56:47 +08:00
你尝试输入了一些稍有不同的单词,然而回应总是一样的。你父亲说,你最好仔细读一下手册的其它部分。这绝非易事,[随 Commodore 64 一起提供的手册][8] 是一本小一些的书。但是这不会困住你,因为手册的介绍预示着奇迹。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
它声称, Commodore 64 有“微型计算机行业中最先进的图画制作器”, 能允许“你设计拥有四种不同颜色的图画, 就像你在街机视频游戏里看到的一样”。Commodore 64 也有“内置的音乐和声音效果,可以与很多著名的音乐合成器相媲美”。所有的这些工具都置身于你的手边,手册会引导你完成所有这些:
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
> 与所有提供的硬件一样重要的是, 这本用户指南将提高你对计算机的理解。它无法在这里告诉你有关计算机的所有信息, 但是它会向你推荐各种出版物, 以获取有关所提出主题的更多详细信息。Commodore 希望你真正喜欢你的新 COMMODORE 64。要想真正得到乐趣, 请记住: 编程不是一种一天就能学会的东西。通读这个用户指南你要有耐心。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
那一夜, 你在床上通读了整整前三个章节: “安装”、“入门”和“BASIC 编程入门”,在你最终睡着时,手册还打开着放在了胸前。
2019-06-06 06:21:11 +08:00
### Commodore BASIC
2019-07-12 12:56:47 +08:00
现在是星期六早上,你渴望尝试你所学到的新东西。手册里教给你的第一件事是如何更改在显示器上的颜色。你按照操作说明,按下 `CTRL-9` 来进入反色输入模式,然后按住空格键来创建了一个长长的空行。你可以使用 `CTRL-1` 到 `CTRL-8` 在不同的颜色之间交换,这让你的电视机屏幕焕发出了新的力量。
2019-06-06 06:21:11 +08:00
![Commodore 64 颜色带][9]
2019-07-12 12:56:47 +08:00
尽管这很酷,但你觉得这不能算是编程。要对计算机编程,你昨晚已经学会了如何做,你必须以一种称为 BASIC 的语言与计算机交谈。对你来说, BASIC 看起来就像星球大战中的东西一样科幻,但是,到 1983 年时,其实 BASIC 已经快有二十岁了。它是由两位达特茅斯教授 John Kemeny 和 Tom Kurtz 发明的,他们想让社会科学和人文科学中的本科生也可以使用计算机。它被广泛使用在微型计算机上,在大学的数学课上很受欢迎。在比尔盖茨和保罗艾伦为 Altair 编写了微软 BASIC 解释器后,它就成为了微型计算机上的标准。但是这本手册对此没有任何解释,那么多年你都没学过它。
2019-06-06 06:21:11 +08:00
2019-07-09 01:18:19 +08:00
手册中建议你尝试的第一个 BASIC 命令是 `PRINT` 命令。你输入了 `PRINT "COMMODORE 64"` ,很慢,因为你需要花费一点时间才能在按键 `2` 上面找到引号符号。你单击 `RETURN` ,这一次,计算机没有抱怨,完全是按照你告诉它做的,在下一行中显示了 “COMMODORE 64” 。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
现在你尝试对各种不同的东西使用 `PRINT` 命令:两个数字加在一起,两个数字乘在一起,甚至几个十进制数字。你不再输入 `PRINT` ,而是使用 `?` 代替,因为手册中告诉你 `?` 是 `PRINT` 的一个缩写, 通常专业程序员都这么使用。你感觉自己已经像是一个专家了, 不过你想起你还没有进行到第三章“BASIC 编程入门”。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
你很快就开始了。该章节提示你编写你的第一个真正的 BASIC 程序。你输入 `NEW` 并单击 `RETURN` ,它给了你一个干净的< ruby > 黑板< rt > slate</ rt ></ ruby > 。然后你在其中输入你的程序:
2019-06-06 06:21:11 +08:00
```
10 ?"COMMODORE 64"
20 GOTO 10
```
2019-07-12 12:56:47 +08:00
手册里解释说 10 和 20 是行号。它们为计算机排序了语句。它们也允许程序员在某些命令中引用程序的其它行,正像你在这里使用的 `GOTO` 命令一样,它将程序指回到行 10。“这是一个很好的编程习惯”, 手册认为, “以 10 的增量来编号行,可以防止你以后需要插入一些语句”。
2019-06-06 06:21:11 +08:00
2019-07-10 21:55:31 +08:00
你输入 `RUN` ,并凝视充满了 “COMMODORE 64” 的屏幕,它一遍又一遍的重复。
2019-06-06 06:21:11 +08:00
![Commodore 64 显示反复打印 "Commodore 64" 的结果][10]
2019-07-10 21:55:31 +08:00
你不确定这不会引爆你的计算机,过了一秒钟你才想起来应该单击 `RUN/STOP` 按键来打断循环。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
手册接下来的一些部分向你介绍了变量,它告诉你变量像“在计算机中许多的盒子,它们每个可以容纳一个数字或一个文本字符串”。以一个 `%` 符号结尾的变量是一个整数,与此同时,以一个 `$` 符号结尾的变量是一个字符串。其余的所有变量是一些称为“浮点”变量的东西。手册警告你要小心变量名称,因为计算机仅会识别变量名称的前两个字母,尽管它不限制你想创建的名称有多长。(这并没有特别让你困扰,但是要是在 30 年后来看,这可能会让人们感到太疯狂了)
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
你接着学习 `IF... THEN...` 和 `FOR... NEXT...` 结构体。有了这些新的工具,你感觉有能力来解决接下来手册丢给你的重大挑战。“如果你是个有野心的人”,没错,“输入下面的程序,并查看会发生什么。”该程序比你目前为止看到的程序更长、更复杂,但是,你很想知道它做了什么:
2019-06-06 06:21:11 +08:00
```
2019-07-10 21:55:31 +08:00
10 REM BOUNCING BALL
20 PRINT "{CLR/HOME}"
25 FOR X = 1 TO 10 : PRINT "{CRSR/DOWN}" : NEXT
30 FOR BL = 1 TO 40
40 PRINT " ●{CRSR LEFT}";:REM (● is a Shift-Q)
50 FOR TM = 1 TO 5
60 NEXT TM
70 NEXT BL
75 REM MOVE BALL RIGHT TO LEFT
80 FOR BL = 40 TO 1 STEP -1
90 PRINT " {CRSR LEFT}{CRSR LEFT}●{CRSR LEFT}";
2019-06-06 06:21:11 +08:00
100 FOR TM = 1 TO 5
110 NEXT TM
120 NEXT BL
130 GOTO 20
```
2019-07-12 12:56:47 +08:00
上面的程序充分利用了 Commodore 64 最酷的功能之一。当把不可打印的命令字符作为字符串的一部分传递到 `PRINT` 命令时, 它们会执行其操作, 而不是被打印到屏幕上。这允许你重新摆放你程序中打印的字符串。( LCTT 译注:上述程序中如 `{CRSR LEFT}` 之类的控制字符执行类似 “在行中向左移动一个位置” 的操作,因此上述程序中利用这些字符操作了一个圆点字符四处移动,如下图。)
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
输入上面的程序你花费了很长时间。你犯一些错误,并不得不重新输入一些行。但是,你最终能够按下 `RUN` ,并看到了一幅杰作:
2019-06-06 06:21:11 +08:00
![Commodore 64 反弹球][11]
2019-07-12 12:56:47 +08:00
你觉得这恐怕是你见过的最酷的事了。不过你几乎转头就忘记了它,因为马上你就学到了 BASIC 的内置函数,像 `RND` (它返回一个随机数字)和 `CHR$` (它返回与一个给定数字代码匹配的字符),这个手册向你展示一个程序,这个程序有名到什么程度呢?直到许多年后,它仍然被当成了一个[短文选集][12]的标题:
2019-06-06 06:21:11 +08:00
```
10 PRINT "{CLR/HOME}"
20 PRINT CHR$(205.5 + RND(1));
40 GOTO 20
```
2019-07-12 12:56:47 +08:00
当运行时,上面的程序会生成一个随机的迷宫:
2019-06-06 06:21:11 +08:00
![Commodore 64 迷宫程序][13]
2019-07-10 21:55:31 +08:00
这绝对是你曾经见过最酷的事。
2019-06-06 06:21:11 +08:00
### PEEK 和 POKE
2019-07-10 21:55:31 +08:00
现在你已经看过了 Commodore 64 手册的前四章节,包含那篇 “高级的 BASIC” 的章节,所以你感到十分自豪。在这个星期六早上,你学习到了很多东西。但是这个下午(在赶快吃了点午饭后),你将继续学习一些使这个放在你的客厅中的奇妙机器变得不再神秘的东西。
2019-06-06 06:21:11 +08:00
2019-07-10 21:55:31 +08:00
手册中的下一个章节标题是“高级颜色和图像命令”。它从回顾你今天早上首先键入的彩色条开始,并向你展示了如何在一个程序中做同样的事。然后它教给了你如何更改屏幕的背景颜色。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
为此,你需要使用 BASIC 的 `PEEK` 和 `POKE` 命令。这些命令分别允许你检查和写入一个存储器地址。Commodore 64 有一个主背景颜色和一个边框背景颜色。每个都通过一个特定的内存地址控制。你可以把你喜欢的任何颜色值写入到这些地址,以使用这些背景颜色和边框颜色。
2019-06-06 06:21:11 +08:00
2019-07-10 21:55:31 +08:00
手册中解释:
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
> 正像变量可以被认为机器中你放置信息的“盒子”一样,你也可以认为在计算机中代表特定内存位置的是一些特殊定义的“盒子”。
2019-06-06 06:21:11 +08:00
>
2019-07-10 21:55:31 +08:00
> Commodore 64 会查看这些内存位置来了解屏幕的背景和边框应该是什么样的颜色,什么样的字符应该被显示在屏幕上,以及显示在哪里,等等其它任务。
2019-06-06 06:21:11 +08:00
2019-07-10 21:55:31 +08:00
你编写了一个程序来遍历所有可用的背景和边界的颜色的组合:
2019-06-06 06:21:11 +08:00
```
10 FOR BA = 0 TO 15
20 FOR BO = 0 TO 15
30 POKE 53280, BA
40 POKE 53281, BO
50 FOR X = 1 TO 500 : NEXT X
60 NEXT BO : NEXT BA
```
2019-07-12 12:56:47 +08:00
虽然 `POKE` 命令以及它的大操作数一开始时看起来很吓人, 现在你看到那个数字的实际值其实不是很要紧。显然, 你必须得到正确的数字, 但是所有的数字代表的是一个“盒子”, Commodore 只是正好存储在地址 53280 处而已。这个盒子有一个特殊的用途: Commodore 使用它来确定屏幕背景应该是什么颜色。
2019-06-06 06:21:11 +08:00
![Commodore 64 更改背景颜色][14]
2019-07-12 12:56:47 +08:00
你认为这简直棒极了。只需要写入到内存中一个专用的盒子,你可以控制一台计算机的基础属性。你不确定 Commodore 64 的电路系统如何读取你写入在内存中的值并更改屏幕的颜色的,但是,你不知道这些也没事。至少你知道结果是怎么样的。
2019-06-06 06:21:11 +08:00
### 特殊容器
2019-07-12 12:56:47 +08:00
在那个周六,你没有读完整本手册,因为你现在有点精疲力尽了。但是你最终会全部读完它。在这个过程中,你学到更多的 Commodore 64 专用的盒子。有一些盒子你可以写入来控制在屏幕上显示什么——这也是一个盒子,事实上,是控制每一个位置出现的字符。在第六章节 “精灵图形” 中,你学到可以让你定义可以移动和甚至缩放图像的特殊盒子。在第七章节 “创造声音” 中,你学到能写入以便使你的 Commodore 64 歌唱 “Michael Row the Boat Ashore” 的盒子。Commodore 64, 事实证明, 它和你可能以后学习到的一个称为 API 的关系甚少。控制 Commodore 64 大多涉及写入到电路系统赋予特殊意义的内存地址。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
多年来,你花费在这些特殊盒子的时光一直伴随着你。甚至几十年后,当你在一个拥有大量的图形或声音 API 的机器上编程时,你知道,隐藏于其背后的,这些 API 最终是写入到这些盒子之类的东西里面的。你有时会好奇那些只使用过 API 的年轻程序员,他们肯定是觉得 API 为他们做到的这一切。可能他们认为这些 API 调用了一些其它隐藏的 API。但是, 那些隐藏的 API 调用了什么?你不由得同情这些年轻的程序员们,因为他们一定会非常迷惑。
2019-06-06 06:21:11 +08:00
2019-07-12 12:56:47 +08:00
如果你喜欢这篇文章,也喜欢它每两周发布的一篇新文章的话,那么请在 Twitter 上关注 [@TwoBitHistory][15] 或订阅 [RSS 源][16]来确保你知道新的文章发布出来。
2019-06-06 06:21:11 +08:00
--------------------------------------------------------------------------------
2019-06-11 11:11:14 +08:00
via: https://twobithistory.org/2018/09/02/learning-basic.html
2019-06-06 06:21:11 +08:00
作者:[Two-Bit History][a]
选题:[lujun9972][b]
译者:[robsean](https://github.com/robsean)
2019-07-10 21:55:31 +08:00
校对:[wxy](https://github.com/wxy)
2019-06-06 06:21:11 +08:00
本文由 [LCTT ](https://github.com/LCTT/TranslateProject ) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://twobithistory.org
[b]: https://github.com/lujun9972
[1]: https://www.youtube.com/watch?v=kZRE7HIO3vk
[2]: https://en.wikipedia.org/wiki/BASIC_Computer_Games
[3]: https://www.youtube.com/watch?v=ZekAbt2o6Ms
[4]: https://www.npr.org/sections/money/2014/10/21/357629765/when-women-stopped-coding
[5]: https://www.youtube.com/watch?v=MA_XtT3VAVM
[6]: https://twobithistory.org/images/c64_startup.png
[7]: https://twobithistory.org/images/c64_error.png
[8]: ftp://www.zimmers.net/pub/cbm/c64/manuals/C64_Users_Guide.pdf
[9]: https://twobithistory.org/images/c64_colors.png
[10]: https://twobithistory.org/images/c64_print_loop.png
[11]: https://twobithistory.org/images/c64_ball.gif
[12]: http://10print.org/
[13]: https://twobithistory.org/images/c64_maze.gif
[14]: https://twobithistory.org/images/c64_background.gif
[15]: https://twitter.com/TwoBitHistory
[16]: https://twobithistory.org/feed.xml
[17]: https://twitter.com/TwoBitHistory/status/1030974776821665793?ref_src=twsrc%5Etfw