如何把大象装进电脑?

计算机程序的基本概念:分解、表示与执行

第 16 期 · 2026-09-26 · 2026-10-11 修订

把大象放进冰箱要三步,放进电脑呢

你一定听过那个段子:把大象放进冰箱要几步?打开冰箱门,把大象放进去,关上门。那把大象放进电脑呢?

第一步就卡住了。电脑没有门。

不信就照着段子做一遍:机箱的盖子倒是能掀开。

漫画:掀开电脑机箱的盖子,把一头大象硬塞进去,盖上盖子,机箱鼓起来,砰地炸开,大象灰头土脸地出来

掀盖、塞进去、盖上——砰!电脑炸了,大象灰头土脸地出来了。这下要收拾的,可不止电脑。

冰箱里有放食物的空间,书包里有放书的空间。电脑机箱里装的是主板、电源、连接线这些零件,没有放动物的地方。你说把照片「存进电脑」,也不是把一张纸塞进机箱。

可你天天在屏幕上见到大象:动画片里的、照片里的、游戏里会走路的。

真大象没进去,屏幕上那头是从哪里来的?

6 个盲人摸象,这一次他们没摸错

先说另一个老故事。6 个盲人第一次遇到大象,每人伸手摸了一把。摸到腿的说大象像根柱子;摸到耳朵的说不对,像把扇子;摸到鼻子的说明明像条粗绳子。还有人摸到牙说像长矛,摸到尾巴说像小蛇,摸到身子说像一堵墙。6 个人吵得不可开交。

这个故事,大人讲完一般会说:他们都错了,要看整体。可这一次,我要替他们说句公道话:他们一个也没摸错。 腿真的像柱子,耳朵真的像扇子,鼻子真的像条粗绳子。他们只是各摸了一部分,再把摸到的那部分当成了全部。

如果把电脑比作故事里的盲人,它还少了一样东西:手。 电脑没法伸手去摸,大象到底长什么样,得由你来观察,再描述给它。

所以,把大象放进电脑的第一步是:你怎么把大象的样子描述给电脑?

摸法有一万种,所以先得说好摸哪几样

盲人摸到了不同的部位。能看见整头大象的人,关心的也各不相同:兽医要检查牙齿、关节,还要量体温;做动画的人盯着大象走路先迈哪条腿、耳朵扇一下要多久;研究象群的人记哪几头总在一起、一天走了多远;研究叫声的人记叫声引起的空气振动。

同一头大象,要弄清的问题不同,需要记下的就不同。你心里的大象,和你同桌心里的,也不是同一头。

光记下来还不够。你量了大象的身高,写下一个「3」。别人拿到这个数,怎么知道你记的是身高,不是年龄?就算猜到是身高,单位是米,还是厘米?

你们得先说清楚:这里记的是身高,用米作单位。这样,同一个「3」,两个人读出来的才都是「身高 3 米」。

把大象的样子交给电脑也一样:说清记哪几样、每个数表示什么,程序才能照着这些数画出来。这些共同遵守的记录规则,就是约定。有了约定,你写下的数,别人和电脑才能按同样的意思读回来。

船长摸到的是肚子

如果也让我来摸一把,我摸到肚子,就猜:这是一头大象妈妈。

这就是船长要放进电脑的那头大象:大象妈妈。她还能产生大象宝宝,每个宝宝可以有不同的样子。

前面几期,我们已经把照片、声音和视频放进过电脑:照片是一格格拼的,你为什么看不出来?,声音看不见摸不着,电脑怎么把它记下来?,手机拍的一秒视频,装着多少个瞬间?。今天换一种办法:把大象妈妈编写成一款游戏,放进电脑。 照片记录一个样子,视频记录一段过程;在这款游戏里,你可以亲手改变大象的样子,让大象妈妈产生不同的大象宝宝。

大象的哪些特征需要记下来?

大象有说不完的特征。这次我们想让屏幕上的大象能改变形状、换颜色、发出叫声,就先记下 形状、颜色、声音 这 3 样。

挑剩下的那些去哪了

先看看被扔下的:它有多重,体温多少度,皮肤上有多少道褶子,鼻子里有多少块肌肉,今天心情好不好,昨天跟谁待在一起——一样都没记。

挑得这么少,好像太亏了。可你想想那 6 个盲人:谁也没摸全,照样各自摸到了真东西。挑,不是说别的不重要,是这一次不要。 兽医扔下了叫声,动画师扔下了牙齿,谁都得扔。

根据这次要做的事,保留有关的特征,暂时忽略其他细节,这就是抽象。屏幕上的大象没有体温,不是忘了记,是这次没打算表现它。

这些特征怎样用数字表示?

选好了要记的特征,还得往下分:「形状」这么大一件事,具体记在哪里?我们先取外轮廓,再沿轮廓选出点,最后记录每个点的位置。把复杂的对象分成可以分别处理的部分,就是分解。

形状:一条线,写成一串数

先说形状。我们不记整头大象的身体,只记外面那一条轮廓线,就是圈出它身子的那一圈。一条线怎么变成数?用你家就有的方格纸试一次。

准备:2 张格子大小相同的方格纸,一支铅笔。

第一步,在方格纸上画一头大象的外轮廓。只画外面那一圈,不画眼睛,也不画耳朵里的纹路。画得像不像不要紧。

第二步,从大象背上最高的地方起手,沿着这条线朝一个方向走,比如往鼻子那边走,每隔 2 格在线上点一个小圆点,一直点回到起点。

第三步,以方格纸左上角为起点,向右数横着的位置,向下数竖着的位置,2 个数写成一对,比如「8,3」。从大象背上那个点开始,按点的顺序记录,每个点都从同一个起点数。

做对了是什么样:你手里会多出一串成对的数,一对一个点,顺序和你点的顺序一样。数一数写了多少对,多半是几十对。

方格纸上的大象轮廓,每个点读出横竖 2 个格数;整条线 116 个点、232 个数

图中这条线是本期程序里的真实数据:116 个点,232 个数。坐标是它在 1000×1000 这块画布上的位置。

现在把原来的画放到一边,只看这串数,在另一张方格纸上重新点出这些点。仍然从纸的左上角向右、向下数,点完后按记录的顺序连起来,最后一个点连回第一个点。

再把 2 张纸放在一起看看:新画出的轮廓,已经有了原来那头大象的样子。点之间的细小弯曲可能不一样,因为你只记下了选中的那些点。

一条轮廓,现在有了一串数字的表示。按约定的规则,用数字表示要记录的信息,这一步就是编码。

这里的规则是:第一个数记横着的位置,第二个数记竖着的位置。先竖后横也可以,但记录和重画时必须一致。如果写的时候先横后竖,重画时却把 2 个数用反,点的位置就会变,轮廓也会跟着变。

记录和读取遵守同样的约定,数字才能表示同一个位置。

还可以挑出记录中的 2 到 3 对数,把它们的第二个数各加上 3,再重新画一次。这几个点就向下挪了 3 格,连到它们的线也变了,其他点仍在原来的位置。后面程序拉长鼻子时,改变的也是这些点的位置。

本期的程序里存的也是这么一串数。它的起点不是大象,是一只猪——手指按住线上哪儿,哪儿就跟着走,鼻子就是这样拉出来的。

一只小猪的轮廓,手指按住鼻子往外拉,慢慢拉出一条长鼻子和 4 条柱子似的腿

按住的时候线上冒出来的小圆点,就是刚才你在方格纸上点的那些点。手指一动,变的只是它们的数。

这串数一共 116 个点,232 个数,写下来 1,155 个字节。 字节不是新朋友:照片、声音、文字和视频,也能放在一起比大小吗?那一期就数过它。

颜色:一个数就够

颜色更省事。我们让整头大象只有一种颜色,只要记一个编号:0 号不上色,1 号陶粉,2 号灰蓝,3 号浅紫,4 号沙黄,5 号草绿,6 号金黄,一共 7 个号。

一个数,就说清了它是什么颜色。

为什么用编号,不直接写「灰蓝」这两个字?因为「灰蓝」是给人看的,每个人心里的灰蓝还不一样深。编号是说好的:6 号就是 6 号,两边查同一张表,不会差。这又是一次约定。

要是想让每个部位颜色都不一样,记一个数就不够了,得给每一段线都配一个号。那样大象更好看,要记的数也更多。记得越细,要写下的数就越多——这件事你在下一节会看见真数字。

声音:一秒钟一万多个数

声音用上一期的老办法:对着话筒学一声象叫,电脑每隔很短一会儿把空气振动量成一个数,一秒钟量一万多次。办法本身上期讲过:声音看不见摸不着,电脑怎么把它记下来?。

这一声有多大?我们实测了一段 3 秒的录音,4,737 个字节。3 样摆在一起,差别一眼看出来:

记哪一样 记了什么 有多大
形状 116 个点的位置,232 个数 1,155 字节
颜色 1 个编号 1 个数
声音 3 秒里的一万多次测量 4,737 字节

形状 1,155 字节、一声 3 秒的象叫 4,737 字节、颜色只有 1 个编号,条形按真实字节成比例

条形长度按真实字节数画;颜色那一条只有 1 个数,短得几乎看不见。

一声象叫,差不多是整条轮廓的 4 倍。声音之所以大,是因为它要一遍遍地量:形状画好就不动了,声音每一刻都在变,不停地量才留得住。

形状、颜色、声音都有了数字的表示,它们是描述大象的数据。但只有数据,还不是能产生大象宝宝的「大象妈妈」;还得写出怎样使用和改变这些数据的程序。

程序怎样把这些数字变成屏幕上的大象?

这份描述躺在那里,屏幕上什么也不会发生。它就是一串数,不会动,也不让你去拉。

要让它变成一页你能伸手去碰的东西,得再做一件大事:写一个程序。

「写一个能玩的大象」还不够具体:页面上要有什么?手指拖动时怎样改那些数?改完怎样画出来?这里又用到了分解:刚才分解的是形状,现在分解的是程序要做的事。

这些事由不同的工具和软件分工,各自管一件小事:

谁 管哪一件小事
HTML 这一页上有哪些东西
CSS 它们多大、什么颜色、摆在哪里
JS 碰了之后算什么
浏览器或微信 把上面 3 样读进来,一条一条执行
数据库 会变的东西记在哪儿

HTML:这一页上有哪些东西

第一件小事,说清这一页上摆了几样东西。这一页很简单:一块画大象的方块,一个换颜色的圆点,一个按住学象叫的按钮,再加上撤回、从头再来、做好了,一共 6 样。写下来是这样:

<view class="board">
  <image class="shape-image" src="..." />
</view>
<view class="actions">
  <button class="swatch" />
  <button>配音</button>
  <button>撤回</button>
  <button>从头再来</button>
  <button>做好了</button>
</view>

每一对尖括号圈起来的,就是一样东西。board 是那块画大象的方块,actions 是下面那一排。写这些用的语言叫 HTML。

注意它只说有什么,不说长什么样。按钮多大、什么颜色、挨得多近,这里一个字也没提。

CSS:它们长什么样

第二件小事才是长相。那块画大象的方块,我们是这么说的:

.board {
  border-radius: 10px;   /* 四个角磨圆 10 */
  overflow: hidden;      /* 画到外面去的部分不显示 */
  cursor: grab;          /* 鼠标移上去变成一只手 */
}

写长相的语言叫 CSS。它和 HTML 分开,是因为这两件事本来就该分开:有什么是一回事,长什么样是另一回事。 同一块方块,换一套长相的说法,就是另一副模样,里面画的大象一点不用改。

HTML、CSS 和下面的 JS,都有说好的写法和意思,人照着这些规矩写,机器才读得懂。人写下来的这些字,叫代码。上面那两段,就是代码。

JS:碰了之后算什么

第三件小事最有意思:人碰它的时候,那串数怎么变。你的手指按在线上往外拖的那一刻,程序要做 3 件事。

先是收到:手指按在哪里、朝哪个方向挪了多远。从外面进来的这些东西,叫输入。

然后是算。它先找出离手指最近的是哪一段线,再一个点一个点地问:这个点离手指有多远?近的多挪一点,远的少挪一点,够远的干脆不动。这一步叫处理。

最后是画:按改过的那串数,重新把点连成线,你看见鼻子鼓出来了。这一步叫输出。而「近的多挪、远的少挪」这句话,在程序里真的写成了几行字:

const far = Math.min(raw, total - raw)               // 这个点离手指多远(沿着线量)
if (far >= reach) return [p[0], p[1]]                // 太远的点,原样不动
const w = .5 * (1 + Math.cos(Math.PI * far / reach)) // 近的跟得多,远的跟得少
return [p[0] + dx * w, p[1] + dy * w]                // 按这个比例挪一挪

写这些规定的语言叫 JS。像它这样能规定「先做什么、后做什么」的语言,有个专门的名字,叫编程语言。你不用看懂每个符号,看出一件事就够了:你觉得「线柔和地跟着手走」的那个感觉,是有人一条一条写下来的规定。 电脑没有感觉,它只是照着算。有意思的是,这一拉,改动比你想的小得多。

同一条轮廓拉之前和拉之后,118 个点里位置变了的只有 10 个

图里 2 条线都是程序算出来的真实数据。每次拉动前,程序会把这条线重新取一遍点,这一回是 118 个;拉完之后,位置变了的只有 10 个,其余 108 个一个数也没动。

整整一头大象看起来变了样,其实电脑只改了 20 个数——10 个点,每个点 2 个数。

还记得你在纸上改的那两三对数吗?电脑干的是同一件事,只是它一次改 10 个点,每个点该挪多少,是按那几行字算出来的。

这里就看出数据和指令的分工了:数据是它记住的东西,指令是它要做的事。你拉了半天,指令一条也没变,变的只是那 20 个数。数据和指令合起来,就是一个程序。

浏览器和微信:谁在执行

前面 3 样写完,还只是 3 份写在纸上的说明,谁来照着做?你用手机打开这一页的时候,真正干活的是浏览器,微信里也有这样一套东西。它做的事按顺序是这样:

  1. 读 HTML,知道这一页上有哪几样东西;
  2. 读 CSS,知道每样该多大、什么颜色、摆哪儿,把它们摆好;
  3. 读 JS,把那些规定记住,然后等着;
  4. 你的手指一碰,它就按规定算,再把新的画面画到屏幕上。

这套负责读代码、照着执行的东西,有个名字,叫运行环境。你可以这么理解它的位置:HTML、CSS、JS 是 3 张写满了规定的纸,运行环境是那个识字、并且真去照做的人。纸自己不会动,人不照着做,纸上写得再清楚也没用。

数据库:会变的东西记在哪儿

除了画出来,程序还可能要保存新增加的记录——比如你学的那一声象叫。这种会不断增加、需要一条条记住的东西,放进数据库。

数据库你可以想成一张表格,一行是一条记录。我们存那一声象叫的表,真的长这样:

编号 谁录的 哪一类 什么格式 多少字节 多长 什么时候录的
一串不会重样的字 录它的人 声音 audio/mp4 4,737 3,022 毫秒 录下来的那一刻

7 个格子,把这一声象叫说清楚了。注意里面没有声音本身——声音另外存成一个文件,这张表只记它是谁的、多大、放在哪。表管「有哪些、各是什么样」,文件管「那一大堆数」,分开放,找起来才快。

大象妈妈这一页真实的样子:上面一块浅色画布里是那条轮廓,下面两行按钮,配色、配音、撤回、从头再来、做好了

这一页就是这样做出来的:画布和按钮来自 HTML,它们的大小和颜色来自 CSS,碰上去会变的部分来自 JS,把它们读出来照着做的,是你手机里的运行环境。

画出页面、接收操作、计算位置、重新画线,一件一件写好,再由运行环境执行,那串数才成了屏幕上可以拉动的轮廓。

别人怎样在自己的电脑上打开它?

程序在我自己的电脑上能运行了,可文件还在我这里。你用自己的电脑或手机,怎样才能打开它?

服务器:这些东西从哪儿来

我们把页面需要的文件放到一台提供网络服务的电脑上,它叫服务器。你在浏览器里打开这一页时,你的电脑或手机向它请求文件,它把文件发回来。

这一次要发多少?我们量过:画大象这部分的 JS 是 16,220 个字节,它的长相说明是 2,660 个字节,加上整页的外壳,一共几十万个字节。这些数不小,但也就是几张照片的量,所以你按一下,一两秒就打开了。

一个值得留意的地方:你拉出来的那头大象,没有发回服务器。 那串数一直待在你手机里。你同桌拉的,也在他自己手机里。服务器只负责把「怎么做」的说明发给每个人。

怎样让服务器把页面送给你?

要让你也能玩,得做 3 件事:把写好的这些文件送到服务器上,让它在那台机器上跑起来,再给它一个地址,别人照着地址就能找到。这 3 件事合起来,有个名字,叫部署。

地址你天天在用,就是那串以 https 开头的字。它的作用和你家门牌号一样:全世界那么多台机器,凭这串字就能找到该问哪一台。

你打开时,这一秒里发生了什么

你在手机上点开这一页,一秒钟之内,下面这些事按顺序发生了:

  1. 手机照着地址,找到那台一直开着的机器;
  2. 手机说:把大象那一页给我;
  3. 服务器把 HTML、CSS、JS 发回来,几十万个字节;
  4. 手机里的浏览器读这 3 样,摆好画面,把规定记住;
  5. 那串 232 个数被读进来,连成线,画在屏幕上;
  6. 你的手指按上去,前面那段 JS 就根据操作计算新的位置。

到第 5 步,你手机上就有了一头大象。而我的电脑上那头,还在。

复制不是搬运

到这里,最奇怪的事情发生了。真大象只有一头。你把它从这个动物园搬到另一个动物园,这边就空了。搬运要用卡车、要花力气,大象还会累、会老、会生病。

程序文件不一样。它们送到你手机上,我这边一点也没少。这不是搬运,是复制。

你和同桌运行的是同一个程序,却各有一份正在修改的轮廓数据。你把鼻子拉长,他把耳朵拉宽,各改各的数据,就得到不同的大象。

一份描述放在那里不变,照着它做出来的大象可以有许多头,各不相同

图中 5 头都由本期程序生成:同一份起点描述,分别拉过之后得到 5 个不同的结果。

现在回头看「大象妈妈」这个名字:放进电脑的是能产生大象的程序,你用它做出来的每一头大象,就是一个大象宝宝。 同一个「妈妈」,能让你做出长鼻子的、宽耳朵的、胖胖瘦瘦的不同宝宝。

这里的「妈妈」是对程序的比喻,「宝宝」是你用程序做出的作品。它们不是真的动物,也不是程序自己在生育;你改变数据,程序按照指令把新的样子画出来。

一份描述,87 万头

复制不花力气,可不代表不占地方。每多一头,就多一份那 1,155 字节。你手机里要是还剩 1 GB,也就是 10 亿个字节,能装多少头?

拿 10 亿除以 1,155,大约 87 万头。这个除法你自己就能算,1 本书和 1 首歌,谁更占手机空间?那一期练的就是它。

它大得有点吓人:今天全世界野生的真大象,加起来大约 46 万头。你手机里一点空地方,装得下比全世界真大象还多的大象。

而这还只是形状。要是每头都配上一声 3 秒的象叫,每头就变成大约 5,900 字节,同样的 1 GB 只装得下大约 17 万头——一下少了八成。记得越多,装得越少,这笔账从第 14 期到今天一直是同一笔。

这就是硅基世界和我们这个世界最不一样的地方: 这边的东西搬走了就没了,那边的东西送出去还在,而且要多少有多少。可它也不是凭空来的,它照样要占地方,只不过占的是字节。

电脑里留下的,到底是什么?

真大象没有变小,也没有钻进机箱。我们根据要做的事,选择记录它的形状、颜色和声音,这是抽象;把轮廓继续分成点的位置,把程序要做的事拆成接收操作、计算和显示,这是分解。

每个数表示什么,要有共同的约定。按照这些规则把特征表示成数,是编码;记录的人和读取它的程序遵守同样的规则,数字才不会被读成别的意思。

有了数据,还需要程序规定怎样使用它们。运行环境执行这些指令,屏幕上才出现大象;把文件部署到服务器上,别人也能取得一份,在自己的设备上运行。

把复杂的东西逐层分解,用约定的数字表示各个部分,电脑才能把这些描述记下来,再按程序处理它们。 从轮廓到点,从拉长鼻子到计算位置,我们一直在做这件事。

回到那 6 个盲人,他们各自描述了大象的一部分。我选择做的是「大象妈妈」:把产生大象的办法写成程序,让你能在电脑里做出自己的大象宝宝。

我们没有把真大象塞进电脑,却把描述大象、改变大象样子的办法放了进去。

那现在换你来分一次:要是想让这头大象会走路,一按它就迈开腿走两步,这件事该先分成哪几件小的?每一件里,又要记住些什么数?

署名:王叔叔