返回介绍

从 1 加到 100:一道简单的数学题挑战下你的大脑

发布于 2025-01-22 00:38:47 字数 3867 浏览 0 评论 0 收藏 0

2017 年的第一篇, 写给刚刚踏入计算机编程领域的小白吧。

所谓编程,就是把自然语言的需求翻译成计算机语言, 让计算机去执行。 对于刚入行的人, 理解 CPU 和内存是怎么在一起工作的, 绝对是基础中的基础。

1

CPU 和内存

如果我们简化一下, CPU 和内存其实特别简单,内存就是一个个的小格子, 每个格子都有一个编号, 格子中的数据可以被 CPU 所读写。

CPU 内部的构造超级复杂, 但我们这次只关注两个东西:

一是运算器,可以做各种运算, 但是有个限制,这个 运算器不能直接操作内存进行运算 , 他在运算时使用的是内部的数据格子(学名叫寄存器), 为了区分开, 我把他们叫做 R1,R2,R3,R4,假设只有这么 4 个, 统称 Rx。

CPU 必须把数据装载到寄存器中才能运算。

CPU 运行速度快的令人发指, 但是它能做的事情却简单的令人发指, 主要是以下四种:

(1) 从内存的某个格子中读取数据放入自己内部的寄存器 Rx

(2) 把 Rx 的数据写入内存的某个格子中(会把原有数据覆盖)

(3) 进行数学运算和逻辑运算

(4) 根据条件进行跳转

数学运算就是加减乘除, 逻辑运算就是 AND , OR 这样的基本运算,没接触过的暂时可以不用深究。

根据条件进行跳转就是从一个指令跳转到另外一个指令, 下文会详述。

2

从 1 加到 100

现在我们试图用一个例子来揭开 CPU 和内存的神秘面纱, 这个例子就是把 1, 2, 3, 4,..... 97, 98, 99, 100 这 100 个数字加起来 。

如果你看过数学王子高斯小时候的故事, 自然很简单,不就是 101 * 50 = 5050 吗 ?

作为码农, 我们需要用上面的简化计算机来解决这个问题: 我们需要 精确的 告诉 CPU 来指令, 让它去完成这个加法运算。

切记切记: 内存只是一个个可以读写的格子, CPU 简单到只能做上面描述的 4 件事。

3

热身

在正式开始之前,我们先来热一下身,把你的思维切换一下, 用这个“简陋的”计算机计算一下 50 + 60 , 我门需要告诉 CPU 这些指令:

指令 1 : 把数字 50 放到编号为 #1 的格子里

指令 2 : 把数字 60 放到编号为 #2 的格子里

指令 3 : 把格子#1 的数字取出来,暂时放到 CPU 内部的寄存器 R1 中

指令 4 :把格子#2 的数字取出来, 暂时放到 CPU 内部的寄存器 R2 中

指令 5 :把 R1 和 R2 的值相加, 结果放到 R1 中

指令 6 :把 R1 的结果放到编号为 #1 的内存格子里。

真是不容易啊, 因为 CPU 不能直接操作内存进行加法操作, 需要把数据从内存和 CPU 之间搬来搬去, 最后才完成了这么一个简单的运算。

4

正式出发

热身完毕,正式出发 !

回到那个从 1 加到 100 的题目, 我们的指令如下所示,CPU 需要依次执行(除非遇到跳转指令), 直到结束:

指令 1 : 把数字 0 放到 编号为 #1 的格子里

指令 2 : 把数字 1 放到 编号为 #2 的格子里

指令 3 : 把#1 号格子的数取出放入 CPU 寄存器 R1 (即 R1 的初始值为 0)

指令 4 : 把#2 号格子的数取出放入 CPU 寄存器 R2 (即 R2 的初始值为 1)

指令 5 : 把 R2 的值和 100 比较, 如果小于等于 100,执行第 6 个指令, 否则执行第 9 个指令

指令 6 : 把 R1 和 R2 的数据加起来, 结果放入 R1

指令 7 : 把 R2 的数值加 1

指令 8: 跳转到第 5 个指令

指令 9: 把 R1 的值写回到 编号为 #1 的格子里

(注:#1 号格子的值就是结果)

这里提示一下: R2 表示的就是从 1 到 100 这些数字, R1 存放的就是中间和。

现在,请你在脑子里边模拟一下这个过程, 看看程序能不能成功结束, 把最终结果放到#1 号格子里。

如果觉得脑子不够用, 建议拿一个纸和笔, 把自己当成 CPU, 把上面的这些指令手工的执行一遍, 体会一下这个过程。

如果你是非科班出身,并且能迅速的理解上面这些指令是如何完成从 1 到 100 的加法的, 恭喜你, 你很适合学习编程, 光明的前途在前面向你招手。

我们上面所说的指令和汇编非常相似, 这是一种非常贴近机器, 非常“低级”的计算机语言。

用这种语言来编写大型程序,会把人活活累死。

当然话也不能那么绝对, 对于那些大神级别的程序员来说, 汇编也是小菜一碟。 Ken Thompson 和 Dennis Ritchie 不就用汇编写了第一版的 Unix 操作系统吗? 求伯君不就用汇编写了 WPS 吗?

对于普通人来说,大神们给我们创造了高级语言让我们使用, 如果我们用高级语言把上面的例子再写一遍, 你应该很容易能看明白了:

不要被之前的“低级”指令吓住, 这才是码农每天打交道的代码,不过这种高级语言写的代码最终也要被编译成“低级”语言代码, 最终交由 CPU 来执行, 编译后的机器语言,其实和上面的指令差不多。

5

思考

为什么要拿这个例子来挑战小白的大脑呢? 从本质上来说, 码农整天做的就是这样的事情, 告诉计算机使用这些指令去运算, 我们需要养成面向计算机的思维方式。

CPU 能干的事情非常有限,笼统来说就是上面那四种, 但是我们现在上网、听歌、看视频、玩游戏,最终都会归结到这些操作中来, 这就是计算的本质。

此外, CPU 是如此的冷酷, 以至于你的指令出一点点错误就不给你正确结果, 例如你把第 3 个指令中的“如果小于等于 100”, 不小心写成了“如果小于 100”,

CPU 当然不会告诉你程序中有问题,他只会冷冷的执行, 最后你会发现:这结果怎么不对呢?

还有一个问题,CPU 在运行的时候,从哪里取获得那些指令?

估计你已经想到了, 对,就是内存 ,指令也需要在内存中才能够被 CPU 访问到, CPU 从内存读到指令以后,会进行分析(译码) , 看看这个指令是干什么的, 然后再进行运算。

所以我们的内存小格子中不仅仅存放的是数据,还存放着至关重要的程序指令! 我们需要告诉 CPU 第一条指令在什么地方, 然后 CPU 就可以疯狂的开始运行了:

这些指令在内存中肯定不是我们看到的自然语言, 而是二进制的表示。

那内存的数据又是从哪里来的? 肯定是硬盘了, 我们写好的程序会放在硬盘上, 在运行的时候才调入内存。

最后,再次强烈推荐这本帮你透彻理解计算机软硬件到底是怎么结合工作的书籍:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文