早期计算机如何编程?
打孔纸卡 -> 插线板 -> 面板拔开关。python
计算机的原理:程序员
程序如何“进入”计算机:
程序须要加载进内存,是计算机科学。(打孔纸卡,插线板,面板拔开关)编程
打孔纸卡 Punched card
需求:
给机器编程,早在计算机出现以前就有了,著名的就是纺织业。
若是只想一块红色大桌布,能够直接放红线进织布机,可是若是想要图案怎么办?好比条纹或方格。
须要没隔一会,调整一次织布机,由于很是消耗劳动力,因此图案纺织品很贵。网络
可编程纺织机:
每一行的图案由可穿孔纸卡决定,特定位置有没有穿孔,决定了线是高是低。
横线是从上/从下穿过,为了让每行图案不一样,纸片连成长条,造成连续指令。架构
不少人认为雅卡尔织布机是最先的编程。app
事实证实,穿孔纸卡便宜,可靠,也易懂。
后面世代中,穿孔纸卡用于1890年美国人口普查。
例如:一张卡存一我的的信息,好比种族,婚姻情况,子女数量,出生国家等等。针对每一个问题,人口普查工做者会在对应位置打孔,当卡片插入汇总机,孔会让对应总和值+1,能够插入整个国家入口的卡片,在结束后获得各个总值。
可是,早期的汇总机不算计算机。由于它们只作一件事:汇总数据。操做是固定的,不能编程。穿孔 纸卡存的是数据,不是程序。以后,这些机器被增强,能够作减,乘,除。甚至能够作一些小决定,决定什么时候执行某指令。编程语言
插线板 Plugboard
为了正确执行不一样计算,程序员须要某种控制面板,面板有不少小插孔,程序员能够插电线,让机器的不一样部分,互相传数据和信号。所以也叫“插线板”。
可是,这意味着,运行不一样程序要从新接线。因此到了1920年代,控制面板变成了可拔插。让编程更方便,能够给机器插入不一样程序。好比,一个插线板算销售税,另外一个算工资单。但给插线板编程很复杂。
用插线板编程,不仅在机电计算机流行,世上第一台通用电子计算机,ENIAC,完成于1946年。用了一大堆插线板。模块化
程序在纸上设计好以后,给ENIAC连线,最多可能花三个星期。由于早期计算机很是昂贵,停机几个星期只为了换程序,彻底没法接受,急须要更快,更灵活的新方式来编程。函数
幸运的是,到1940年代晚期1950年代初。内存变得可行,价格降低,容量上升。与其把程序存在插线板,存在内存变得可行,这样易于修改,方便CPU快速读取。这类机器叫“存储程序计算机”。工具
冯诺依曼架构
若是内存足够,不只能够存要运行的数据,还能够存程序须要的数据。包括程序运行时产生的新数据。
程序和数据都存在一个地方,叫“冯诺依曼结构”。将指令和数据混合存放到内存,穿孔纸片和插线板,都是分开。
冯诺依曼曾过:我在思考比炸弹重要得多的东西计算机。
冯诺依曼计算机的标志是,一个处理器(有算术逻辑单元)+ 数据寄存器 + 指令寄存器 + 指令地址寄存器 + 内存(负责存数据和指令)。
第一台冯诺依曼架构的“存储程序计算机”,由曼彻斯特大学于1948年建造完成,绰号“宝宝”。
虽然有内存很棒,但程序和数据,依然须要某种方式输入计算机,因此用穿孔纸卡。
到1980年代,几乎全部的计算机都有穿孔纸卡读取器,能够吸入一张卡片,把卡片内容写进内存,若是放了一叠卡片,读取器会一个个写进内存。一旦程序和数据写入完毕,电脑会开始执行。即使简单程序也有几百条指令,要用一叠纸卡来存。
用纸卡的最大型程序是美国空军的SAGE防空系统,于1955年完成,据称顶峰时期,雇佣了世上20%程序员。
主控制程序用了62500张穿孔纸片,等同于大约5MB的数据。穿孔纸卡不只能够往计算机放数据,还能够取出数据,程序运行到最后,结果能够输到纸卡上,方式是打孔。而后人能够分析结果,或者再次放进计算机,作进一步计算。
穿孔纸卡的亲戚是纸带,基本是一回事,只不过更连续,不是一张张卡。
如今存储的方式,硬盘,只读光盘,DVD,U盘等等。
面板编程 Panel programming
与其插一堆线到插线板,能够用一大堆开关和按钮,作到同样的效果。面板上有指示灯,表明各类函数的状态和内存中的值。
50和60年代的计算机,通常都有这样巨大的控制台。不多有人只用开关来输入一整个程序,但技术上是可行的,早期针对计算机爱好者的家用计算机,大量使用了开关。由于大多数家庭用户负担不起昂贵的外围设备,好比穿孔纸卡读取器。
第一款取得商业成功的家用计算机是Altair 8800
有两种版本能够买:
为了给8800编程,要拨动面板上的开关。输入二进制操做码,而后按“存储键”把值存入内存。
而后会到下一次内存位置,能够再次拨开关,写下一个指令,重复这样操做。(初代plc 原型)
把整个程序都写入内存以后,能够推进开关,回到内存地址0,而后按运行按钮,灯会闪烁。
不论是插线板,开关或穿孔纸卡。早期编程都是专家活,不论是全职仍是技术控,都要很是了解底层硬件。好比 操做码,寄存器等,才能写程序。因此编程很难,很烦。
哪怕工程师和科学家都没法彻底发挥计算机的能力,须要一种更简单方式,告诉计算机要作什么。一种更简单的编程方式。
编程:二进制 -> 助记符(汇编器) -> A-0(编译器) -> FORTRAIN
组成计算机的物理组件:
好比电
,电路
,寄存器
,RAM
, ALU
, CPU
。
在硬件层面编程很是麻烦,因此程序员想要一种更通用的方法编程。
一种“更软的”媒介: 软件。
第一条指令在内存地址0: 0010 1110
。前4位操做码,简称OPCODE
对于这个假设CPU,0010
表明LOAD A
指令:把值从内存复制到寄存器A。
后4位是内存地址,1110
是十进制的14。
因此这8位表达的意思是:读内存地址14,放到寄存器A。
只是用了两种不一样语言,能够想成是英语和摩尔斯码的区别。
“hello
” -> “.... . .-.. .-.. ---
”是一个意思:“hello
”
只是编码方式不一样,英语和摩尔斯码的复杂度也不一样,英语有26个字母以及各类发音。摩尔斯码只有“点”和“线”但它们能够传达相同的信息,计算机语言也相似。
二进制写程序
计算机能处理二进制,二进制是处理器的“母语”。事实上,它们只能理解二进制。这叫“机器语言”或“机器码”。
在计算机早期阶段,必须用机器码写程序。
具体来说,会先在纸上写一个“高层次版”的伪代码(PSEUDO-CODE)。
例如:从内存取下一个销售额,而后加到天,周,年的总和,而后算税。
写好伪代码后,用“操做码表”把伪代码转成二进制机器码,翻译完成后,程序能够喂入计算机并运行。
助记符
在1940~1950年代,程序员开发出一种新语言,更可读,更高层次。
每一个操做码分配一个简单名字,叫“助记符”(MNEMONICS)。
“助记符”后面紧跟数据,造成完整指令。与其用1和0写代码,程序员能够写“LOAD A 14”。它不能理解文字,只能理解二进制,因此程序员想了一个技巧,写二进制程序来帮忙。它能够读懂文字指令,自动转成二进制指令。这种程序叫“汇编器”。
汇编器读取用“汇编语言”写程序,而后转成“机器码”。“LOAD_A 14”是一个汇编指令的例子。
随着时间的推移,汇编器有愈来愈多功能,让编程更容易,其中一个功能是自动分析JUMP
地址。
例如:JUMP NEGATIVE
指令跳到地址5, JUMP 2
指令跳到地址2。
问题是,若是在程序开头多加一些代码,全部地址都会改变。更新程序会很痛苦。
因此汇编器不用固定跳转地址,而是让插入可跳转的标签。
当程序被传入汇编器,汇编器会本身搞定跳转地址。程序员能够专心编程,不用管底层细节。隐藏没必要要的细节来作更复杂的工做。
然而,即便汇编器有这些厉害的功能,好比自动跳转。汇编只是修饰了一下机器码。
通常来讲,一条汇编指令对应一条机器指令。因此汇编码和底层硬件的链接很紧密,汇编器仍然强迫程序员思考,用什么寄存器和内存地址。
若是忽然要一个额外的数,可能要修改不少代码。
A-0
哈佛1号在1944年战时完成,帮助盟军做战,程序写在打孔纸袋上,放进计算机执行,若是程序由漏洞,直接使用胶带来补“漏洞”。
Mark 1的指令集很是原始,甚至没有JUMP
指令,若是代码要跑不止一次,得把带子的两端连起来,作成循环。(循环,物理,物理,循环)
给Mark 1编程简直是噩梦,战后,霍普继续研究计算机,为了释放电脑的潜力,设计了一个高级编程语言,叫“算术语言版本 0”,简称“A-0”。
汇编与机器指令是一一对应的,但一行高级编程语言,可能会转成几十条二进制指令。为了作到这种复杂的转换,霍普在1952年创造了第一个编译器,编译器专门把高级语言,转成低级语言,好比汇编或机器码(CPU 能够直接执行机器码)
尽管“使编程更简单”很诱人,可是不少人持怀疑态度。
霍普曾说:“我有能用的编译器,但没人愿意用,他们告诉我计算机只能作算术,不能运行程序”。
不久,不少人尝试创造新编程语言,到现代现在有上百种语言。
惋惜的是,没有任何A-0
的代码遗留下来。
使用Python举例:
假设想相加两个数字,保存结果,记住,若是用汇编代码,得从内存取值,和寄存器打交道,以及其它底层细节。
不用管寄存器的内存位置,编译器会搞定这些细节,不用管底层细节。
程序员只须要建立,表明内存地址的抽象,叫“变量”(给变量取名字)。
底层操做时,编译器可能把变量A存在寄存器A,但程序员不须要知道这些,眼不见心不烦。
FORTRAN
但A-0
和以后的版本没有普遍使用。FORTRAN
,名字来自“公式翻译”。这门语言数年后由IBM在1957年发布。主宰了早期计算机编程。
FORTRAN
项目总监John Backus
曾说:我作的大部分工做都是由于懒,我不喜欢写程序,因此我写这门语言,让编程更容易。
FORTRAN
写的程序,比等同的手写汇编代码短20倍,而后FORTRAN
编译器会把代码转成机器码。
对于FORTRAN
程序的性能是否比得上手写代码?但由于能让程序员写程序更快,因此成了一个更经济的选择。
运行速度慢一点点,编程速度大大加快。
当时IBM在卖计算机,所以最初的FORTRAN
代码只能跑在IBM计算机上,1950年代大多数编程语言和编译器,只能运行在一种计算机上。若是升级电脑,可能要重写全部代码。所以工业界,学术界,政府的计算机专家,在1959年组建了一个联盟: 数据系统语言委员会,霍普担任顾问。开发一种通用的编程语言,能够在不一样机器上通用。最后诞生了一门高级,易于使用:普通面向商业语言,简称COBOL
。
为了兼容不一样底层硬件,每一个计算机架构须要一个COBOL
编译器,最重要的是,这些编译器均可以接受相同的COBOL
代码。不论是什么电脑,这叫“一次编写,处处运行”。现在的大多数编程语言都是这样。没必要接触CPU特有的汇编码和机器码。
减下了使用门槛,在高级编程语言出现以前,编程只是计算机专家和爱好者才会作的事,并且一般是主职。但如今,科学家,工程师,医生,经济学家,教师等等,均可以把计算机用于工做。
“解释型语言”对应“解释器”,编译器是把语言编程二进制代码再运行。
计算机科学从深奥学科,变成了大众化工具,同时,编程的抽象也让计算机专家,制做更复杂的程序。
1959年代,编程语言黄金时代开始,和硬件一块儿飞速发展。
1960年代:ALGOL, LISP, BASIC
1970年代:Pascal C, Smalltalk
1980年代:C++, Object-C, Perl
1990年代:Python, Ruby, Java
2000年代:Swift, C#, Go
新语言想用更聪明的抽象,让某些方面更容易或更强大,或利用新技术和新平台带来的优点。
用机器码写程序,还要处理那么多底层细节,对写大型程序是个巨大障碍。为了脱离底层细节,开发了编程语言,让程序员专心解决问题,不用管硬件细节。
变量,赋值语句
规定句子结构的一系列规则叫语法。
a=5
是一个编程语言语句,意思是建立一个叫a的变量,把数字5放里面。这叫“赋值语句”,把一个值赋给一个变量。为了表达更复杂的含义,须要更多语句。
变量名能够随便取。
程序由一个个指令组成,有点像菜谱:烧水,加面,等10分钟,捞出来就能够吃了。
程序也是这样,从第一条语句开始,一句一句运行到结尾。
拍虫子游戏
阻止虫子飞进计算机形成故障,关卡越高,虫子越多。在虫子损坏继电器以前,抓住虫子。
开始编写时,须要一些值,来保存游戏数据,好比当前关卡数,分数,剩余虫子数,还剩下几个备用继电器。
因此要“初始化”变量,“初始化”的意思是设置最开始的值。
level = 1 # 关卡=1 score = 0 # 分数=0 bugs = 0 # 虫子=5 relays = 4 # 备用继电器=4 name = 'andre' # 玩家
为了作成交互式游戏,程序的执行顺序要更灵活,不仅是从上到下执行,所以用“控制流语句”。if
构成的语句叫: “条件语句”
若是但愿根据条件执行屡次,须要“条件循环”。
计算指数,代码很经常使用。若是每次想用就复制粘贴,会很麻烦,每次都要修改变量名,若是代码发现问题,要补漏洞时,要把每个复制粘贴过的地方都找出来修改,并且会让代码更难懂,少便是多。想要某种方法,把代码“打包”,能够直接使用,得出结果。不用管内部复杂度。
函数
为了隐藏复杂度,能够把代码打包成“函数”也叫“方法”或“子程序”,其它地方想用到这个函数,直接写函数名就能够了。须要把结果,交给使用这个函数的代码,因此用return
语句,指明返回什么。
函数是,抽象的力量。
现在超过100行代码的函数不多见,若是多于100行,应该有些东西能够拆出来作成一个函数。
若是有第二次地方使用,就抽象出函数。
模块化编程,不只可让单个程序员独立制做app,也让团队协做能够写更大型的程序。
现代编程语言,有不少预先写好的函数集合,叫“库”。由专业人员编写,不只效率高,并且通过了仔细的检查。几乎作全部的事情,都有库,网络,图像,声音。