它们不厌其烦地执行人的指令;它们收集世间万物的知识,供人顷刻之间随心调取;它们是现代社会的中流砥柱,但其存在却往往备受忽视。
它们就是计算机,是人类迄今为止最伟大的发明成就,是登峰造极、至高无上的终极工具。
计算机科学的问世,推动了人类历史上最非比寻常的社会变革之一。
而编程语言作为计算机的灵魂,存在感却远远高于计算机,它就像一个纽带把我们和计算机深深的联系在了一起。
编程语言的发展更是和计算机的演变有着密不可分的关系。
不知道大家有没有好奇过,世界上第一门编程语言是什么?
今天就由我带领大家穿越到这一切的起点,去看一看计算机和编程语言的爱恨情仇。
不同的的人面对计算机有着不同的给关注点,有人觉得计算机的设计很巧妙,有人觉得计算机的结构布置很酷,有人觉得计算机的界面很漂亮……
但计算机的美妙之处并不在于其闪烁的灯光、旋转的磁盘、成排的芯片和电线,而在于,这些部件的背后隐藏着一个优雅而简单的想法。这个想法同晶体管、操作系统、网络和文字处理器毫无关联,也不可能有任何关联,因为它的诞生时间比这些设备都早。
图灵的相关生平,这里不多做赘述,这里我们只关注他的“可计算性理论”。
还记得当时初学冯诺依曼结构时,我们班里的同学还就冯诺依曼机与图灵机谁的贡献最大,而吵的不可开交,最后也是谁也没说服谁。
冯诺依曼机大家都不陌生,可以简单地理解成冯诺依曼机更侧重于硬件的实现。
图灵机偏重的抽象模型是“可计算”和“不可计算”这个计算机的边界
这个时候可能有人就要说了,这和今天要讲的世界上第一个编程语言有什么关系?你这不是上来就先给计算机定下了一个边界了吗?
是的,先展示这段的目的就是为了告诉大家:不要迷信计算机,不要迷信我们的编程语言。
不管是在人工智能和深度学习大行其道的今天,有些问题也是无法用计算机去解决的,我们要始终怀着一种敬畏之心来面对这个世界。
这一切都要从打孔卡片开始说起。
美国宪法中要求,每10年就得进行一次人口普查。到了19世纪末期,人口增长的实在是太频繁了,以至于1880的人口普查历时8年才最终完成,当时还都是通过纸和笔来完成的。
1890年,Herman Hollerith被授命去解决这一问题,他最终使用了穿孔卡来存储数据,并用一台制表机(tabulating machine)来进行统计和排序。
在 20 世纪的大部分时间里,穿孔卡在数据处理行业得到了广泛的应用,其中专业且日益复杂的单元记录机器被组织成半自动数据处理系统,使用穿孔卡进行数据输入、输出和存储。
1896年,Hollerith成立了制表机器公司,开始了自己的事业。他把自己的设备和卡片出售给大的保险公司,以及包括英国,意大利,德国,俄罗斯,澳大利亚,加拿大,法国,挪威,波多黎各,菲律宾等国在内的多国政府。
他的公司后来跟别的公司进行了合并,并在1924年最终成为了国际商业机器公司。没错,它就是IBM。
这就是我们的第一站:打孔机和打孔卡片。
有人可能会有疑问,这打孔卡片也算是一门编程语言吗?这就要看大家怎么去定义编程语言了。
在我看来,只要其涉及数据处理与一定的计算规则都可以称为一种语言。就像我们常说的:
程序=数据+算法
哪怕这些数据只是最常见的自然数,哪怕这些算法只是加减乘除。
打孔卡片靠其出色的能力盛行了一段时间,但你能想想那硕大的机器和成吨种的卡片吗?
幸运的是这些都只是暂时的,而拯救我们的就是电子学与计算机科学的结合,让我们脱离了笨重的机械式计算机。
晶体管的出现更是让“开/关”动作变得简洁又优雅。
而我们这次的主角——机器代码,就是这一开一关动作的化身:0和1。
机器代码之所以被称为机器代码,就是因为这种代码是可以直接被机器(计算机)所读取。
用二进制代码表示的计算机能直接识别和执行的一种机器指指令系统令的集合。
大家可以随便打开一个自己用任何一种高级语言编译好的二进制文件(.bin)来查看这些机器码到底长什么样子。
最右边就是我们的机器码,但为什么不是01组合,怎么还有其他数字和字母呢?
这是因为二进制表示的数字实在是太小了,所以大多采用的是十六进制来表示。
用机器语言编写程序,编程人员要首先熟记所用计算机的全部指令代码和代码的涵义。
手编程序时,程序员得自己处理每条指令和每一数据的存储分配和输入输出,还得记住编程过程中每步所使用的工作单元处在何种状态。这是一件十分繁琐的工作。
编写程序花费的时间往往是实际运行时间的几十倍或几百倍,而且,编出的程序全是些0和1的指令代码,直观性差,还容易出错。
那么有没有一种方式,让我们能够更容易的记住这些机器指令?
汇编语言闪亮登场。
汇编语言的主体是汇编指令。汇编指令和机器指令的差别在于指令的表示方法上,汇编指令是机器指令便于记忆的书写格式。说白了,汇编语言就是助记符(Mnemonics)。
可能有人会问,我们用汇编语言编写程序,可是计算机只认识机器指令,那该怎么办?这时候就需要一个能将汇编语言转换成机器指令的工具,我们称其为编译器。程序员用汇编语言写出源代码,再用汇编编译器将其编译为机器码,最后由计算机执行。
再者,汇编语言指令是机器指令的一种符号表示,而不同类型的CPU 有不同的机器指令系统,也就有不同的汇编语言,所以,汇编语言程序与机器有着密切的关系。
所以,除了同系列、不同型号CPU 之间的汇编语言程序有一定程度的可移植性之外,其它不同类型(如:小型机和微机等)CPU 之间的汇编语言程序是无法移植的,也就是说,汇编语言程序的通用性和可移植性要比高级语言程序低。(因为高级语言可以再不同类型的计算机上用不同的编译器翻译成机器语言)
Fortran语言最初是由 IBM 公司在 50 年代开发的。
当时,创建语言的目的是专门解决一组特定的问题:Fortran 语言的目的是科学处理。
它仍然是在高性能计算领域最流行的语言之一,而且作为基准,用于世界最快的超级计算机程序的语言的排名。
Fortran 语言建立使用星号乘法,这是今天仍在使用的所有语言中的约定。
这是它的外观:
Program Hello
Print *, "Hello World!"
End Program Hello
COBOL (Common Business-Oriented Language)
被设计用于商业用途。这是企图使编程语言更类似于英语,让程序员和管理人员可以读取它。
它的设计者有 Grace Hopper(发现 “Bug” 的人),以及发明了类似英语的数据处理语言 FLOW-MATIC的人,也是最合适,帮助创建一个看起来类似英文通用商业语言的人选。
这是一个 COBOL 的 Hello World 程序:
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO-WORLD.
ENVIRONMENT DIVISION.
DATA DIVISION.
PROCEDURE DIVISION.
MAIN.
DISPLAY 'Hello, world.'.
STOP RUN.
ALGOL 60 (ALGOrithmic Language 1960)
是一个委员会推动的,非常好,有影响力的语言, 发布于 1960 年。
它从来没有得到普及,但它推出了许多重要概念,包括摆脱 GOTO。在行与行之间跳来跳去行的语言,如 BASIC,难以遵循程序的流程,导致编写程序容易出错。
ALGOL 60 引入结构化程序设计和模块:它使用 BEGIN 和 END(因为大括号是不可用),感谢 ALGOL 60 现在我们有了代码块,而不是 GOTO。
ALGOL 也不希望太过专业,从而适合良好的科学和业务处理
下面是它的样子:
procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);
value n, m; array a; integer n, m, i, k; real y;
comment The absolute greatest element of the matrix a, of size n by m
is transferred to y, and the subscripts of this element to i and k;
begin integer p, q;
y := 0; i := k := 1;
for p:=1 step 1 until n do
for q:=1 step 1 until m do
if abs(a[p, q]) > y then
begin y := abs(a[p, q]);
i := p; k := q
end
end Absmax
Pascal 是在 1968 - 1969 年设计, 由 Niklaus Wirth出版于1970年,其灵感来自 ALGOL
它最初是非常流行的,虽然最初设计为教学工具,很长一段时间很多人用它做通用编程。
但是,它不是模块化不够,有一些使得编程难的设计挑战。
比如有一个片段:
while a <> b do WriteLn('Waiting');
if a > b then WriteLn('Condition met') {no semicolon allowed!}
else WriteLn('Condition not met');
for i := 1 to 10 do {no semicolon for single statements allowed!}
WriteLn('Iteration: ', i);
repeat
a := a + 1
until a = 10;
case i of
0 : Write('zero');
1 : Write('one');
2 : Write('two');
3,4,5,6,7,8,9,10: Write('?')
end;
B 在贝尔实验室开发于 1969 年, 它的灵感来自于 Fortran 和 BCPL。
还记得有个同学开玩笑说,既然有C语言,那肯定会有B语言和A语言,没想到还真有B语言(其实还有个E语言就不说了)。
B 引入了 += 操作符 (尽管写成 =+), 以及自增/自减操作符 (++ 和 –)
printn(n,b) {
extrn putchar;
auto a;
if (a=n/b) /* assignment, not test for equality */
printn(a, b); /* recursive */
putchar(n%b + '0');
}
C 诞生于 B 加上从 Pascal 加入一些好的想法。它是在贝尔实验室(再次)的 Dennis Ritchie 在 1969 年和 1973 年之间开发。
相比较于机器语言与汇编语言来说,C已经拥有更强的表达能力,可方便地表示数据的运算和程序的控制结构,能更好的描述各种算法,而且容易学习掌握。
但高级语言编译生成的程序代码一般比用汇编程序语言设计的程序代码要长,执行的速度也慢。
关于编程语言就说到这里,如果把每一门语言都说一遍的话,可能几天几夜都说不完。
感兴趣的同学可以去维基百科上看一看
除了第一个编程语言外,相信大家肯定还有一个疑问:世界上第一个编译器使用什么语言来编译的?
这就类似于那个世界上是先有鸡还是先有蛋的问题。
其实在编译原理中,有一个概念:自举。
编程语言是自举的,指的是说,我们能用自己写出来的程序编译自己。但是自举,并不要求这门语言的第一个编译器就是用自己写的。
比如,这里说到的 Go,先是有了 Go 语言,我们通过 C++ 写了编译器 A。然后呢,我们就可以用这个编译器 A,来编译 Go 语言的程序。接着,我们再用 Go 语言写一个编译器程序 B,然后用 A 去编译 B,就得到了 Go 语言写好的编译器的可执行文件了。这个之后,我们就可以一直用 B 来编译未来的 Go 语言程序,这也就实现了所谓的自举了。
更详细的关于鸡蛋问题,可以直接看 Wikipedia 上这个链接,里面讲了多种这个问题的解决方案。
在上文中,我们大致了解了计算机和编程语言的发展史。
如果从严谨一点的角度去考虑的话,Fortran语言应该是世界上第一门高级编程语言。
编程语言千千万,这些语言之间没有高低贵贱,更不存在什么歧视链, 有的只有不同的应用环境适合哪一种编程语言。
最后祝愿大家不管使用哪一种语言都能bug少少!!!
(室友和同门都申请离校回家了,我还悲惨的在学校呆着,可快点解封吧~我要出去吃烧烤,吃火锅!)
参考文献:
《计算机:一部历史》彼得·本特利
http://foorious.com/articles/brief-history-of-programming-languages/
https://segmentfault.com/a/1190000004303544
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
我创建了一个由于“在运行时执行的单例元类定义”而无法编码的对象(这段代码的描述是否正确?)。这是通过以下代码执行的:#defineclassXthatmyusesingletonclassmetaprogrammingfeatures#throughcallofmethod:break_marshalling!classXdefbreak_marshalling!meta_class=class我该怎么做才能使对象编码正确?是否可以从对象instance_of_x的classX中“移除”单例组件?我真的需要一个建议,因为我们的一些对象需要通过Marshal.dump序列化机制进行缓存。
我正在查看Ruby日志记录库Logging.logger方法并从sourceatgithub提出问题与这段代码有关:logger=::Logging::Logger.new(name)logger.add_appendersappenderlogger.additive=falseclass我知道类 最佳答案 这实际上删除了方法(当它实际被执行时)。这是确保close不会被调用两次的保障措施。看起来好像有嵌套的“class 关于Ruby元编程问题,我们在StackOverflow上找到一
使用Paperclip,我想从这样的URL抓取图像:require'open-uri'user.photo=open(url)问题是我最后得到一个像“open-uri20110915-4852-1o7k5uw”这样的文件名。有什么方法可以更改user.photo上的文件名?作为一个额外的变化,Paperclip将我的文件存储在S3上,所以如果我可以在初始分配中设置我想要的文件名就更好了,这样图像就会上传到正确的S3key。像这样:user.photo=open(url),:filename=>URI.parse(url).path 最佳答案