是什么让一门编程语言的所有单词都能真正发挥作用?我的意思是,实际上发生了什么让计算机知道所有这些词的意思?如果我口头告诉我的计算机做某事,它不会做,因为它不理解。那么这些人类语言写成一种语言究竟是如何真正使计算机做一些合乎需要的活动的呢?
13 回答
这一切都始于 CPU 或处理器。每种处理器类型都有一组定义的能够执行的指令。这些指令对 1 和 0 进行操作,它们反过来代表您希望它们执行的任何操作:数字、字母,甚至是指令本身。
在最低级别,零是由晶体管上存在特定电压(通常接近 0V)确定的,而 1 是存在不同电压(取决于 CPU,例如 5V)
机器指令本身是一组零和一组放置在处理器中称为寄存器的特殊位置,处理器从特定位置获取指令及其操作数并执行操作,将结果放置在另一个位置,然后获取下一条指令,依此类推,直到它用完要执行的指令或被关闭。
一个简单的例子。假设机器指令 001 表示两个数字相加。
然后你编写一个程序,将两个数字相加,通常是这样的:
4 + 5
然后将此文本传递给编译器,该编译器将为您将在其上运行程序的处理器生成足够的机器代码(旁注,您可以编译代码以在与当前运行的处理器不同的处理器中运行,这是一个名为交叉编译,它很有用,例如,在嵌入式平台中)。好吧,编译器最终会大致生成,
001 00000100 00000101
使用额外的样板机器代码将 001 指令放在下一个指令寄存器(指令指针)中,并将二进制编码的数字放在数据寄存器(或 RAM)中。
从结构化语言生成机器代码的过程相当复杂,并且限制了这些语言最终看起来的正常程度。这就是为什么你不能用英语编写程序的原因,它有太多的歧义,编译器无法生成正确的 0 和 1 序列。
CPU可以执行的指令相当基本和简单,加法、除法、取反、从RAM读取、放入RAM、从寄存器读取等等。
下一个问题是,这些简单的数字指令如何产生我们在计算中看到的所有奇迹(互联网、游戏、电影播放器等)?
它基本上归结为创建足够的模型,例如 3D 游戏引擎有一个代表游戏世界的数学模型,并且可以根据它计算游戏对象的位置/碰撞。
这些模型建立在许多这样的小指令之上,这就是高级语言(不是机器代码)真正大放异彩的地方,因为它们提高了抽象级别,然后你可以更接近你想要实现的模型,让你轻松推理诸如如何根据从控制器接收到的输入有效地计算士兵将要进入的下一个位置,而不是因为您忙于不忘记 0 而阻止您轻松推理。
从汇编语言(一种与机器代码非常相似的语言,它是第一种编程语言,它是特定于 CPU 的。每条汇编指令都直接转换为机器代码)到 C(可在不同 CPU 之间移植,并且是在比汇编更高的抽象级别:每行 C 代码代表许多机器代码指令)。这对程序员来说是一个巨大的生产力提升,他们不再需要在不同的 CPU 之间移植程序,他们可以更轻松地思考底层模型,从而导致我们看到的软件复杂性持续增加(甚至需求)从 1970 年代到今天。
未决的缺失环节是如何控制如何处理该信息以及如何接收来自外部来源的输入,例如在屏幕上显示图像或将信息写入硬盘驱动器,或在打印机上打印图像,或从键盘。这一切都是通过计算机中存在的其他硬件实现的,这些硬件以类似于 CPU 的方式进行控制,您将数据和指令放置在图形卡或网卡或硬盘驱动器或内存。CPU 具有指令,可以将一些数据或指令放入(或从中读取信息)不同硬件的正确位置。
与我们今天所拥有的存在相关的另一件事是,所有现代计算机都带有称为操作系统的大型程序,这些程序管理所有基本内容,例如与硬件通信和错误处理,例如程序崩溃时会发生什么等。此外,许多现代编程环境都带有许多已经编写好的代码(标准库)来处理许多基本任务,例如在屏幕上绘图或读取文件。该库将反过来要求操作系统代表它与硬件对话。
如果这些不可用,编程将是一项非常艰巨且乏味的任务,因为您编写的每个程序都必须再次创建代码以在屏幕上绘制单个字母或从每种特定类型的硬盘读取单个位,例如。
看来我得意忘形了,我希望你能从中理解一些事情:-)
计算机编程语言实际上是一种高度抽象的语言,它被转换成计算机实际理解的非常基本的语言。
基本上,计算机真的只理解机器语言,这是一种以二进制(1 和 0)实现的基本语言。在此之上的一个级别是汇编语言,它是一种非常原始的语言,至少是人类可读的。
在高级语言中,我们可能有类似的东西:
Person.WalkForward(10 steps)
在机器代码中,它将是:
Lift Persons Left Foot Up
Lean Forward
Place Left Foot Down
Lift Right Foot up
Lean Forward
Place Right Foot Down
etc
现在很明显,没有人愿意编写程序来告诉计算机每一个重复的小事情要做,所以我们有称为编译器的工具。
编译器采用更易于人类理解的高级语言,并将其转换为机器代码,以便计算机可以运行它。
一本为非工程师讨论计算机的好书是Charles Petzold 的“代码”。我不记得它是否完全涵盖了您的问题,但我认为是的。如果你有足够的兴趣走得更远,这是一个不错的选择。
在最简单的情况下,称为编译器的程序将您编写的编程语言单词转换为计算机可以理解的机器语言。编译器了解一种特定的编程语言(C#、Java 等),它对如何向编译器解释你想要它做什么有非常具体的规则。
对这些规则的解释和理解是 Stack Overflow 的主要内容。:)
编程是你采取一系列步骤来解决某个问题,然后用某种需要某种语法的语言写出来。当您用该语言描述了这些步骤后,您可以使用编译器(根据 Greg 的评论),该编译器将该语言翻译成计算机可以解释的语言。
艺术在于确保你足够好地描述这些步骤:)
一些人已经提供了从典型编程语言到处理器可以执行的实际机器代码的翻译过程的摘要。
要理解这个过程,对在机器代码级别进行编程的实际感觉有一个具体的感觉会很有帮助。一旦您了解了处理器本身可以做什么,就更容易将高级编程结构理解为它们的缩写。
但不幸的是,为台式计算机编写机器代码并不是很有趣。
作为替代方案,有一个很棒的老游戏,叫做Corewar,你可以在其中使用简化的机器语言编写小程序。然后这些程序为了生存而相互竞争。你可以用原始机器语言编写基本程序,然后有一个宏系统,所以你不必重复太多,这是迈向全功能语言的第一步。
另一件简单、有益但低级的事情是编写一个简单的嵌入式控制器,如Arduino。有很多像这样的简单介绍可用。您仍将使用编译器,但生成的机器代码更容易理解(如果您愿意的话),因为处理器的功能要简单得多。
这两种方法都是了解数字计算机实际工作方式的好方法。
很简单,计算机编程就是以计算机可以理解的语言向计算机提供一组指令的行为。程序员通常用高级编程语言编写指令,然后这些指令被翻译成计算机可以理解的二进制语言。进行这种翻译的程序称为编译器。
您可以将编程的工作原理与语言之间的翻译进行比较。假设你和另外两个人在一个荒岛上。你只会说法语。1 号人(我们称他为 Fred)只会说法语和日语。第 2 个人(鲍勃)只会说日语。假设你需要让 Bob 去帮你收集一些柴火。想象在这种情况下,您是程序,而 Bob 是计算机。你用法语对弗雷德说:“你能告诉鲍勃来帮帮我吗?” Fred 翻译成日语并请 Bob 帮助您。在这种情况下,Fred 将是编译器。他将请求翻译成 Bob 可以理解的内容。这就是计算机程序的工作方式。
有一篇很好的How Stuff Works文章解释了一些事情。
在我参加数字电子课程之前,我个人并不真正了解计算机如何以它们的方式工作。在此之前,我完全了解计算机如何工作的整个想法。在我建立了一个二进制计数器之后,一切都变得有意义了。
我有两个疯狂的建议。及时回去!
1. 获得一个可编程计算器。
可编程计算器是一个普通的计算器,你可以用它做通常的事情:输入数字,输入操作符号,按下equel键后,你可以在微型显示器上读取结果。此外,可编程计算器可以将短的击键序列存储为程序,以后可以通过单次按键“重播”。假设您将此序列设置为程序(每行一条指令):
(Start)
*
2
+
1
=
(Stop)
现在您有一个自定义操作:按下“程序”键(或您分配给哪个键)它将在没有您进一步帮助的情况下运行序列,并将显示内容乘以 2 并加 1 - 这是一个程序!
稍后您可以尝试更多增强的技术:将临时结果存储到内存中,在结果上进行分支。
优点:
- 计算器是一个熟悉的环境。您已经具备了基础知识。
- 这很简单。你不必学习很多指令和编程技术。
- 现代编程语言离地面很远,而可编程计算器“就在上面”。您将学习基础知识:内存、分支、基本操作。计算机的工作方式非常相似(在机器语言级别上)。
- 您将遇到低级问题:内存、除以零。
- 这非常酷。
缺点:
- 它已经过时了。你必须学习一门现代编程语言,这会有所不同。
- 这很不舒服(嗯,它是专业的:你不能使用舒适的点击播放玩具)。也许你甚至不能保存你的代码。
- 得到一个不是一件容易的事。你可以在 E-Bay 上试试。此外,文档不会有问题,大多数模型在互联网上都有大量的用户群。
恕我直言, TI-59的最佳选择。
2. 在模拟器的帮助下学习 BASIC 语言。
当您打开具有内置BASIC 语言解释器的机器时,它已准备好接受您的命令,并在您键入时执行。首先,您可以在命令模式下尝试一些指令,例如:
PRINT 5*4
它将在下一行打印“20”,哇。如果你在命令模式下玩够了,你可以将指令整理成程序,然后你可以运行、编辑、增强它。
优点:
- BASIC 是一种真正的编程语言,专为教育而设计。
- 当您后来遇到一种现代编程语言并发现其中的差异时,您将看到过去 30 年编程技术(例如过程、结构等)的进步。
- 这很酷,特别是如果你得到一个真正的,而不仅仅是一个模拟器。
缺点
- 它已经过时了。从那个年龄到现在已经过去了将近 30 年。
- 旧机器是紧凑的封闭系统。没有文件(以我们今天使用的形式)、文件夹、文件类型,可能会让初学者感到困惑。
我最喜欢的 BASIC 系统是Commodore 16 (Plus/4),它与著名的 C64 非常相似。但更舒服。我更喜欢YAPE模拟器,它可以保存/加载内存快照或 BASIC 程序到文件。
电脑有预设数量的指令;它已经知道该怎么做。计算机程序只是计算机将按顺序执行的指令列表。
早期的程序是直接用机器语言编写的。程序员为了让他们的生活更轻松,开始创建抽象来简化他们需要编写的程序。随着时间的推移,添加了越来越多的抽象,就像洋葱层一样,但归根结底都是同一件事——执行一系列指令。
如果您想在不关注编译器、技术等的情况下学习编程,那么当您开始在Alice中创建 3D 场景时,您会很好地了解程序是什么。爱丽丝从卡内基梅隆大学免费。您最终会学习如何编程,而无需尝试学习编程。
但是,如果您想了解更多有关技术细节的信息,最好的办法是查看一些介绍性的 compi-sci 大学教科书。以下How C Programming Works也可能会给您一些答案。
正如人们已经注意到的那样,有一些预程序(通常是“编译器”)可以将程序中的文字翻译成一种更冗长的“低级”语言,称为“机器代码”。
机器代码由非常简单的指令组成,这些指令已经被底层处理器“理解”(或至少就其意义而言)。例如,一条指令将数据从内存位置复制到处理器的一个特殊部分(称为“累加器”,可以对其进行简单的算术运算)。或者一条将两个插槽的内容相加的指令在蓄能器中。
你看到的复杂的程序(包括高级语言的编译器和解释器)最终都是由这些运行了数百万次的简单指令构建的。
基本上,您从简单的事情开始,例如:
print("Hello World");
然后你只需在它上面撒上语法糖和魔法标记,直到它做你想要的!